Introducción a Elixir
@solojavier
@solojavier
Qué
es
Elixir
Funcional
EVM
Extensible
Sintaxis similar a Ruby
Qué
dicen de
Elixir
I [looked at Elixir again], and I felt the same way I felt when I first saw Ruby.
Dave Thomas
Elixir is what would happen if Erlang, Clojure, and Ruby somehow had a baby and it wasn’t an accident.
Devin Torres
Elixir offers developers the functional power and concurrent resilience of Erlang, with friendlier syntax, libraries and metaprogramming
Simon St. Laurent
It didn’t take long, but pretty soon my gut feeling kicked in. This is good shit.
Joe Armstrong
Having a pretty syntax wrapped around the powerful Erlang VM seems to be an irresistible combination.
Benjamin Tan
I liked everything I saw in Erlang, but I hated the things that I didn’t see.
Jose Valim
Porqué
usar
Elixir
Pensar dyferente
Curva de aprendizaje
Inmutabilidad
Concurrencia
Erlang
Adaptable
Performance
Tolerante a fallos
Herramientas
Comunidad
Pipes!
Pipes!
def fetch(user, project) do
handle_response(HTTPoison.get(issues_url(user, project), @user_agent))
end
Pipes!
def fetch(user, project) do
url = issues_url(user, project)
response = HTTPoison.get(url, @user_agent)
handle_response(response)
end
Pipes!
def fetch(user, project) do
issues_url(user, project)
|> HTTPoison.get(@user_agent)
|> handle_response
end
Como
se ve
Elixir
defmodule Times do
def double(n), do: n * 2
def triple(n), do: n * 3
def quadruple(n), do: n * 4
end
defmodule Factorial do
def of(0), do: 1
def of(n) when n > 0, do: n * of(n-1)
end
message = fn
0, 0, _ -> "FizzBuzz"
0, _, _ -> "Fizz"
_, 0, _ -> "Buzz"
_, _, n -> "#{n}"
end
fizz_buzz = fn
n -> message.(rem(n, 3), rem(n, 5), n)
end
defmodule MathTest do
use ExUnit.Case, async: true
test "can add two numbers" do
assert 1 + 1 == 2
end
end
parent = self()
# Spawns an Elixir process
spawn_link(fn ->
send parent, {:msg, "hello world"}
end)
# Block until the message is received
receive do
{:msg, contents} -> IO.puts contents
end
Cómo
utilizar
Elixir
mix
mix new
* creating README.md
* creating .gitignore
* creating mix.exs
* creating config
* creating config/config.exs
* creating lib
* creating lib/kv.ex
* creating test
* creating test/test_helper.exs
* creating test/kv_test.exs
mix.exs
defmodule KV.Mixfile do
use Mix.Project
def project do
[app: :kv,
version: "0.0.1",
deps: deps]
end
def application do
[applications: [:logger]]
end
defp deps do
[]
end
end
mix compile
Compiled lib/kv.ex
Generated kv.app
mix test
1) test the truth (KVTest)
test/kv_test.exs:4
Assertion with == failed
code: 1 + 1 == 3
lhs: 2
rhs: 3
stacktrace:
test/kv_test.exs:5
Finished in 0.05 seconds
1 tests, 1 failures
mix help
mix # Run the default task (current: mix run)
mix archive # List all archives
mix archive.build # Archive this project into a .ez file
mix archive.install # Install an archive locally
mix archive.uninstall # Uninstall archives
mix clean # Delete generated application files
mix cmd # Executes the given command
mix compile # Compile source files
mix compile.protocols # Consolidates all protocols in all paths
mix deps # List dependencies and their status
mix deps.clean # Remove the given dependencies' files
mix deps.compile # Compile dependencies
mix deps.get # Get all out of date dependencies
mix deps.unlock # Unlock the given dependencies
mix deps.update # Update the given dependencies
mix do # Executes the tasks separated by comma
mix docs # Generate documentation for the project
mix escript.build # Builds an escript for the project
mix eunit # Run a project's eunit tests
mix help # Print help information for tasks
mix hex.config # Read or update hex config
mix hex.docs # Publish docs for package
mix hex.info # Print hex information
mix hex.key # Hex API key tasks
mix hex.owner # Hex package ownership tasks
mix hex.publish # Publish a new package version
mix hex.search # Search for package names
mix hex.user # Hex user tasks
mix loadconfig # Loads and persists the given configuration
mix local # List local tasks
mix local.hex # Install hex locally
mix local.rebar # Install rebar locally
mix new # Create a new Elixir project
mix run # Run the given file or expression
mix test # Run a project's tests
iex -S mix # Start IEx and run the default task
hex
mix.exs
defp deps do
[{:ecto, "~> 0.1.0"},
{:postgrex, "~> 0.3.0"},
{:cowboy, github: "extend/cowboy"}]
end
mix deps.get
* Updating ex_doc (git://github.com/elixir-lang/ex_doc.git)
remote: Counting objects: 46, done.
remote: Compressing objects: 100% (17/17), done.
remote: Total 46 (delta 7), reused 4 (delta 4), pack-reused 25
From git://github.com/elixir-lang/ex_doc
fa2feac..214afbb master -> origin/master
* [new tag] v0.7.2 -> v0.7.2
A new Hex version is available (v0.7.5), please update with `mix local.hex`
Running dependency resolution
Unlocked: httpoison, jsx, earmark
Dependency resolution completed successfully
httpoison: v0.6.2
ssl_verify_hostname: v1.0.4
idna: v1.0.2
jsx: v2.6.1
hackney: v1.1.0
earmark: v0.1.16
* Updating jsx (Hex package)
Checking package (https://s3.amazonaws.com/s3.hex.pm/tarballs/jsx-2.6.1.tar)
Fetched package
Unpacked package tarball (/Users/javier/.hex/packages/jsx-2.6.1.tar)
* Updating earmark (Hex package)
Checking package (https://s3.amazonaws.com/s3.hex.pm/tarballs/earmark-0.1.16.tar)
Fetched package
Unpacked package tarball (/Users/javier/.hex/packages/earmark-0.1.16.tar)
* Updating hackney (Hex package)
Checking package (https://s3.amazonaws.com/s3.hex.pm/tarballs/hackney-1.1.0.tar)
Fetched package
Unpacked package tarball (/Users/javier/.hex/packages/hackney-1.1.0.tar)
* Updating ssl_verify_hostname (Hex package)
Checking package (https://s3.amazonaws.com/s3.hex.pm/tarballs/ssl_verify_hostname-1.0.4.tar)
Fetched package
Unpacked package tarball (/Users/javier/.hex/packages/ssl_verify_hostname-1.0.4.tar)
hex.pm
iEx
iex
Erlang/OTP 17 [erts-6.3.1] [source] [64-bit] [smp:8:8] [async-threads:10] [hipe] [kernel-poll:false] [dtrace]
Interactive Elixir (1.0.3) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> IO.puts "Hello World"
Hello World
:ok
iex(2)> import_file "~/.iex.exs"
iex(3)> [1, 2, 3, 4, 5]
[1,2,3,...]
ExUnit
ExUnit
defmodule CliTest do
use ExUnit.Case
import Issues.CLI, only: [
parse_args: 1
]
test ":help returned by option parsing with -h and --help options" do
assert parse_args(["-h", "anything"]) == :help
assert parse_args(["--help", "anything"]) == :help
end
test "three values returned if three given" do
assert parse_args(["user", "project", "99"]) == { "user", "project", 99 }
end
test "count is defaulted if two values given" do
assert parse_args(["user", "project"]) == { "user", "project", 4 }
end
end
ExUnit
Compiled lib/issues.ex
Compiled lib/issues/cli.ex
Compiled lib/issues/github_issues.ex
Compiled lib/issues/table_formatter.ex
Generated issues.app
..............
Finished in 0.1 seconds (0.1s on load, 0.00s on tests)
14 tests, 0 failures
Randomized with seed 399755
ExDoc
ExDoc
ExDoc
1) test doc at Issues.TableFormatter.split_into_columns/2 (4) (DocTest)
test/doc_test.exs:3
Doctest failed
code: list = [Enum.into([{"a", "1"},{"b", "2"},{"c", "3"}], HashDict.new),
Enum.into([{"a", "4"},{"b", "5"},{"c", "6"}], HashDict.new)]
Issues.TableFormatter.split_into_columns(
list, [ "b", "b", "c" ]) === [ ["1", "4"], ["2", "5"], ["3", "6"] ]
lhs: [["2", "5"], ["2", "5"], ["3", "6"]]
stacktrace:
lib/issues/table_formatter.ex:38: Issues.TableFormatter (module)
defmodule DocTest do
use ExUnit.Case
doctest Issues.TableFormatter
end
ExDoc
Phoenix framework
Phoenix Framework
Phoenix Framework
$ mix archive.install https://github.com/phoenixframework/.../phoenix_new-0.13.0.ez
$ mix phoenix.new hello_phoenix
$ cd hello_phoenix
$ mix phoenix.server
Phoenix Framework
Cómo
aprender
Elixir
Elixir-Lang.org
Programming Elixir
Introducing Elixir
h4cc/awesome-elixir
ElixirConf
comunidad.softcraft.mx
ElixirGDL
Introducción a Elixir
@solojavier
javier@solojavier.com