erlang otp elixir - modrpc/info GitHub Wiki
- Erlang is a functional programming language - referential transparency
- however, pure functional programming paradigm has difficulty with handling the notion of time -- anyhow the world of equation has no notion of time (unless explicitly modeled)
- Erlang is impure in the sense message passing requires data copy, i.e. side effect
- Erlang program consists of concurrent processes which communicate with messages
- message-base communication means: connectionless -- cf. TCP vs UDP; telephone vs mailing system
- also, no shared memory (no shared state)
- Erlang code is compiled into bytecode and runs on a virtual machine.
- Erlang Website: http://www.erlang.org/
- Documentation: http://www.erlang.org/doc.html
- Papers: http://www.cs-lab.org/papers.html
- Erlang Factory: http://www.erlang-factory.com/
- Wikipedia
- Elixir Website: http://elixir-lang.org/
- commands finish with DOT(.):
var = 1.
-
atom is a literal: i.e. a constant where only value is its own name:
thisisatom.
-
tuple:
point = {4, 5}.
-
list:
mylist = [1,2,3]. mylist2 = mylist ++ [4,5]. hd[mylist]. tl[mylist].
-
bit values:
16#F0942A. <<312, 43, 33>>.
- module: a bunch of functions grouped togher in a single file, under a single name
- module declaration includes: functions and attributes
-module(ModuleName). -export([foo/3, bar/2, ..., funname/arity]).
- exported functions represent a module's interface
- Erlang processes are not OS processes (it's more like Verilog always process, which is conceptually a concurrent process) but sequentially executed.
- Erlang system consists of events, processes (or 'reactors' i.e. "contiguously executable code blocks") and event-reactor associations.
- Doesn't depend on shared memory since frequent crash in a distributed system could easily result in inconsistent global state.
- One big challenge in distributed system is: you cannot assume that because a remote node was there when you made a function call
- it will still be there for the whole communication of the call,
- it will eventually execute the call correctly
- it is hanging in the remote node or it's just taking too long or etc.
-
Failure model -- Let it crash
- No try/catch
- Restart monitored process that die
- Three concurrency primitives in process in Actor model of computation
-
spawn a process:
-
<0.44.0>
is a process identifier (pid), used as an address to communite with this process
-
- send messages
- receive messages
-
spawn a process:
// spawn spawn(fun() -> 2 + 2 end). <0.44.0> //send dest_process() ! my_message. // receive myfun() -> receive msg1 -> dothis; msg2 -> dothat; _ -> dorest; end.
-
timers:
receive <...> after 3000 -> timeout_error
-
flush:
flush() -> receive _ -> flush() after 0 -> ok end.
- link: specific kind of relationship that can be created between two processes
- usages:
- establish larger groups of proceses that should die together:
chain(0) -> receive _ -> ok after 2000 -> exit("chain dies here") end; chain(N) -> Pid = spawn(fun() -> chain(N-1) end), link(Pid), receive _ -> ok end.
Erlang is not just a language but also a development environment as a whole. To support "distributed computing", dwelling inside a language scope is no longer possible. We need to jump out of that and handle meta-level concepts such as processes (denotations of functions) and machines (entities which executes programs).
Components of standard Erlang distribution include:
- Development tools (compilers,d ebugger, profiler, test frameworks, optional type analyzer)
- OTP (Open Telecom Platform) Framework
- Web server
- Advanced tracing tools
- Mnesia database (key/value storage system able to replicate itself on many servers, which supports nested transactions and lets you store any kind of Erlang data)
- BEAM instruction set: http://www.cs-lab.org/historical_beam_instruction_set.html
- Erlang's process model is very efficient and scalable. Maybe close to the performance of HDL native simulator.
- Erlang syntax is unorthodox from mainstream programmer's viewpoint -- I don't think this will get wide acceptance
- The destination of messages are processes:
- P0 -> P1
- cf. P0 -> channel -> P1 (Golang)
- Channels can have some property -- e.g. buffered vs non-buffered, queue-length, etc.
- Above two are equivalent, though
- Handling of strings as list of integers
- Functional programming with referential transparency is simply lame -- notion of time (and thus state change) is difficult to represent.