|
@@ -0,0 +1,80 @@
|
|
|
+# Elixir is a dynamic, functional language for building scalable
|
|
|
+# and maintainable applications. Learn more: https://elixir-lang.org
|
|
|
+
|
|
|
+"Elixir" |> String.graphemes() |> Enum.frequencies()
|
|
|
+#=> %{"E" => 1, "i" => 2, "l" => 1, "r" => 1, "x" => 1}
|
|
|
+
|
|
|
+
|
|
|
+### Scalability ###
|
|
|
+
|
|
|
+# All Elixir code runs inside lightweight threads of execution (called processes)
|
|
|
+# that are isolated and exchange information via messages:
|
|
|
+
|
|
|
+current_process = self()
|
|
|
+
|
|
|
+# Spawn an Elixir process (not an operating system one!)
|
|
|
+spawn_link(fn ->
|
|
|
+ send(current_process, {:msg, "hello world"})
|
|
|
+end)
|
|
|
+
|
|
|
+# Block until the message is received
|
|
|
+receive do
|
|
|
+ {:msg, contents} -> IO.puts(contents)
|
|
|
+end
|
|
|
+
|
|
|
+
|
|
|
+### Fault-tolerance ###
|
|
|
+
|
|
|
+# To cope with failures, Elixir provides supervisors which describe
|
|
|
+# how to restart parts of your system when things go awry, going back
|
|
|
+# to a known initial state that is guaranteed to work:
|
|
|
+
|
|
|
+children = [
|
|
|
+ TCP.Pool,
|
|
|
+ {TCP.Acceptor, port: 4040}
|
|
|
+]
|
|
|
+
|
|
|
+Supervisor.start_link(children, strategy: :one_for_one)
|
|
|
+
|
|
|
+
|
|
|
+### Functional programming ###
|
|
|
+
|
|
|
+# Functional programming promotes a coding style that helps
|
|
|
+# developers write code that is short, concise, and maintainable.
|
|
|
+# One prominent example is pattern matching:
|
|
|
+
|
|
|
+%User{name: name, age: age} = User.get("John Doe")
|
|
|
+name #=> "John Doe"
|
|
|
+
|
|
|
+# When mixed with guards, pattern matching allows us to elegantly
|
|
|
+# match and assert specific conditions for some code to execute:
|
|
|
+
|
|
|
+def drive(%User{age: age}) when age >= 16 do
|
|
|
+ # Code that drives a car
|
|
|
+end
|
|
|
+
|
|
|
+drive(User.get("John Doe"))
|
|
|
+#=> Fails if the user is under 16
|
|
|
+
|
|
|
+
|
|
|
+### Extensibility and DSLs ###
|
|
|
+
|
|
|
+# Elixir has been designed to be extensible, letting developers
|
|
|
+# naturally extend the language to particular domains,
|
|
|
+# in order to increase their productivity.
|
|
|
+
|
|
|
+defmodule MathTest do
|
|
|
+ use ExUnit.Case, async: true
|
|
|
+
|
|
|
+ test "can add two numbers" do
|
|
|
+ assert 1 + 1 == 2
|
|
|
+ end
|
|
|
+end
|
|
|
+
|
|
|
+
|
|
|
+### Erlang compatible ###
|
|
|
+
|
|
|
+# An Elixir programmer can invoke any Erlang function with no runtime cost:
|
|
|
+
|
|
|
+:crypto.hash(:md5, "Using crypto from Erlang OTP")
|
|
|
+#=> <<192, 223, 75, 115, ...>>
|