20 message = "Hello, " <> name <> "!"
25 Greeter.greet("world")
50 IO.puts "Hello, " <> user.name
57 users = [ "Tom", "Dick", "Harry" ]
62 Enum.map(users, fn user ->
63 IO.puts "Hello " <> user
78 print(transform(source, :hello))
81 These two are equivalent.
86 user = %{name: "Tom", age: 23}
87 %{name: username} = user
91 This sets `username` to `"Tom"`.
93 ### Pattern matching in functions
96 def greet(%{name: username}) do
97 IO.puts "Hello, " <> username
100 user = %{name: "Tom", age: 23}
104 Pattern matching works in function parameters too.
114 "This will never be seen"
124 "This clause won't match"
126 "This will match and bind x to 2"
128 "This will match any value"
137 "I will never be seen"
141 "But I will (this is essentially an else)"
148 with {:ok, {int, _asdf}} <- Integer.parse("123asdf"),
149 {:ok, datetime, _utc_offset} <- DateTime.from_iso8601("2021-10-27T12:00:00Z") do
150 DateTime.add(datetime, int, :second)
151 # optional else clause. if not provided and an error occurs, the error is returned
153 :error -> "couldn't parse integer string"
154 {:error, :invalid_format} -> "couldn't parse date string"
155 _ -> "this will never get hit because all errors are handled"
165 message -> "Got #{message}."
167 IO.puts("I'm the after clause.")
178 | `true` _/_ `false` | Boolean |
180 | `?a` | Integer (ASCII) |
184 | `'hello'` | Charlist |
185 | `<<2, 3>>` | Binary |
186 | `"hello"` | Binary string |
192 | `%{a: "hello"}` | Map |
193 | `%MyStruct{a: "hello"}` | Struct |
194 | `fn -> ... end` | Function |
226 left != right # equal
227 left !== right # match
228 left ++ right # concat lists
229 left <> right # concat string/binary
230 left =~ right # regexp
239 require Redux # compiles a module
240 import Redux # compiles, and you can use without the `Redux.` prefix
242 use Redux # compiles, and runs Redux.__using__/1
243 use Redux, async: true
245 import Redux, only: [duplicate: 2]
246 import Redux, only: :functions
247 import Redux, only: :macros
249 import Foo.{Bar, Baz}
255 alias Foo.Bar, as: Bar
256 alias Foo.Bar # same as above
272 str |> length() # → 5
273 str |> codepoints() # → ["h", "e", "l", "l", "o"]
274 str |> slice(2..-1) # → "llo"
275 str |> split(" ") # → ["hello"]
276 str |> capitalize() # → "Hello"
280 ### Inspecting objects
283 inspect(object, opts \\ [])
286 value |> IO.inspect()
289 value |> IO.inspect(label: "value")
299 rem(a, b) # remainder (modulo)
300 div(a, b) # integer division
317 n |> ceil(2) # → 11.30
318 n |> to_string() # → "1.030000+e01"
319 n |> to_string([decimals: 2, compact: true])
323 Float.parse("34") # → { 34.0, "" }
339 n |> digits() # → [1, 2]
340 n |> to_charlist() # → '12'
341 n |> to_string() # → "12"
348 n |> digits(2) # → [1, 1, 0, 0]
349 n |> to_charlist(2) # → '1100'
350 n |> to_string(2) # → "1100"
354 parse("12") # → {12, ""}
355 undigits([1, 2]) # → 12
361 Float.parse("34.1") # → {34.1, ""}
362 Integer.parse("34") # → {34, ""}
366 Float.to_string(34.1) # → "3.4100e+01"
367 Float.to_string(34.1, [decimals: 2, compact: true]) # → "34.1"
375 m = %{name: "hi"} # atom keys (:name)
376 m = %{"name" => "hi"} # string keys ("name")
387 m = %{m | name: "yo"} # key must exist
391 m |> put(:id, 2) # → %{id: 2, name: "hi"}
392 m |> put_new(:id, 2) # only if `id` doesn't exist (`||=`)
396 m |> put(:b, "Banana")
397 m |> merge(%{b: "Banana"})
398 m |> update(:a, &(&1 + 1))
399 m |> update(:a, fun a -> a + 1 end)
403 m |> get_and_update(:a, &(&1 || "default"))
410 m |> delete(:name) # → %{}
411 m |> pop(:name) # → {"John", %{}}
418 m |> keys() # → [:id, :name]
419 m |> values() # → [1, "hi"]
423 m |> to_list() # → [id: 1, name: "hi"]
424 # → [{:id, 1}, {:name, "hi"}]
430 put_in(map, [:b, :c], "Banana")
431 put_in(map[:b][:c], "Banana") # via macros
435 get_and_update_in(users, ["john", :age], &{&1, &1 + 1})
438 ### Constructing from lists
441 Map.new([{:b, 1}, {:a, 2}])
442 Map.new([a: 1, b: 2])
443 Map.new([:a, :b], fn x -> {x, x} end) # → %{a: :a, b: :b}
446 ### Working with structs
451 Map.from_struct(%AnyStruct{a: "b"}) # → %{a: "b"}
457 struct(AnyStruct, %{a: "b"}) # → %AnyStruct{a: "b"}
473 l = l ++ [5] # push (append)
474 l = [ 0 | list ] # unshift (prepend)
487 Also see [Enum](#enum).
506 list |> count() # → 3
507 list |> empty?() # → false
508 list |> any?() # → true
512 list |> concat([:d]) # → [:a, :b, :c, :d]
515 Also, consider streams instead.
521 list |> reduce(acc, fn)
530 |> Enum.reduce(0, fn(x, acc) -> x + acc end)
547 t |> elem(1) # like tuple[1]
548 t |> put_elem(index, value)
555 list = [{ :name, "John" }, { :age, 15 }]
560 # For string-keyed keyword lists
561 list = [{"size", 2}, {"type", "shoe"}]
562 List.keyfind(list, "size", 0) # → {"size", 2}
570 square = fn n -> n*n end
580 square = &Math.square/1
588 apply(module, fun, args)
594 def join(a, b \\ nil)
595 def join(a, b) when is_nil(b) do: a
596 def join(a, b) do: a <> b
605 defstruct name: "", age: nil
608 %User{name: "John", age: 20}
610 %User{}.struct # → User
613 See: [Structs](http://elixir-lang.org/getting-started/structs.html)
617 ### Defining protocols
621 @doc "Returns true if data is considered blank/empty"
627 defimpl Blank, for: List do
628 def blank?([]), do: true
629 def blank?(_), do: false
632 Blank.blank?([]) # → true
638 defimpl Blank, for: Any do ... end
641 @derive Blank # Falls back to Any
648 - `Enumerable` and `Enum.map()`
649 - `Inspect` and `inspect()`
656 for n <- [1, 2, 3, 4], do: n * n
657 for n <- 1..4, do: n * n
661 for {key, val} <- %{a: 10, b: 20}, do: val
666 for {key, val} <- %{a: 10, b: 20}, into: %{}, do: {key, val*val}
672 for n <- 1..10, rem(n, 2) == 0, do: n
680 file <- File.ls!(dir), # nested comprehension
681 path = Path.join(dir, file), # invoked
682 File.regular?(path) do # condition
695 @after_compile __MODULE__
696 def __before_compile__(env)
697 def __after_compile__(env, _bytecode)
698 def __using__(opts) # invoked on `use`
700 @on_definition {__MODULE__, :on_def}
701 def on_def(_env, kind, name, args, guards, body)
720 ~s|strings with #{interpolation} and \x20 escape codes|
721 ~S|no interpolation and no escapes|
725 Allowed chars: `/` `|` `"` `'` `(` `[` `{` `<` `"""`.
726 See: [Sigils](http://elixir-lang.org/getting-started/sigils.html)
731 @spec round(number) :: integer
733 @type number_with_remark :: {number, String.t}
734 @spec add(number, number) :: number_with_remark
737 Useful for [dialyzer](http://www.erlang.org/doc/man/dialyzer.html).
738 See: [Typespecs](http://elixir-lang.org/getting-started/typespecs-and-behaviours.html)
744 @callback parse(String.t) :: any
745 @callback extensions() :: [String.t]
750 defmodule JSONParser do
753 def parse(str), do: # ... parse JSON
754 def extensions, do: ["json"]
758 See: [Module](http://elixir-lang.org/docs/stable/elixir/Module.html)
763 - [Learn Elixir in Y minutes](https://learnxinyminutes.com/docs/elixir/)