- let it crash philosophy - supervisors handle actor crashes
- most common - restart actor with initial state
- actor recieve messages in mailbox - can be across nodes
- dynamically typed and strongly typed so no implicit conversion
- atoms, tuples, pattern-matchingå
- no true strings
- atoms can't be garbage collected
- Some BIFS implemented in C for speed
- same concept of [head | tail] lists and cons (|) operator as Elixir
- list comprehensions with constraints
- guards
- slow for number crunching compared to C/C++
- great for messaging and event reactive apps
- deals with events in matter of millliseconds
- implied return statements
- macros simple expressions represented by text that get replaced pre-compile
- HIPE module to convert to native code
- not purely functional like Haskell: relies on side effects IO, send messages between actors, throw errors
- no concept of null values - elixir gets nil
- else or true branches should be avoided, have if's that cover all logical ends instead of catch-all clause
- similar to precise error handling in C++
- records are like C's structs
- i use erlang's C Nodes for clustering and ports for any data structure/algo heavy lifting - way faster
- if vs case...of same representation at lower level
- tail recursion with accumulator to avoid stacking active records in recursion (mem expensive)
- recursion and list comprehensions only looping mechanism
Variables start with Capital Letter:
> One = 1.
1
> atom.
atom
> %%enclose in '' if doesn't start with lowercase letter
> "SomeAtom".
"SomeAtom"
> 'This is an atom'.
- 4 bytes/atom 32 bit
- 8 bytes/atom 64 bit
- atom table is not garbage collected
- so never generate atoms dynamically
> true and false.
false
> false or true.
true
> true xor false.
true
> not false.
true
> not (true and true).
false
> 5 =:= 5.
true
> 1 =:= 0.
false
> 1 =/= 0.
true
> 5 =:= 5.0.
false
> 5 == 5.0.
true
> 5 /= 5.0.
false
> 1 < 2.
true
> 1 < 1.
false
> 1 >= 1.
true
> 1 =< 1.
true
> 0 == false.
false
> 1 < false.
true
number < atom < reference < fun < port < pid < tuple < list < bit string
- cannot add anything with anything, but can compare anything
- done to allow sorting algos to order any types of term
> {X,Y} = {4,5}.
> Point = {4,5}.
> NewPoint = {Point, {2,3}}.
> %% tagged tuple is of form: {atom, anything}
> {message, "some message"}.
#Lists
-
Most used data structure in Erlang
-
can contain anything: numbers, atoms, tuples, other lists
> [1,2,3, {one_atom,[4,5,6]}, 5.34, another_atom].
-
Strings are lists with exact same notation
-
Erlang will print lists of numbers as numbers only if at least one could not also be a letter
> [97,98,99]. "abc" > [97,98,3]. [97,98,3]
-
no such thing as real string in erlang - origins in telecom so no need
[1,2,3] ++ [4,5]. [1,2,3,4,5] [1,2,3,4,5] -- [4,5]. [1,2,3]
> [1,2,3] -- [1,2] -- [3].
[3]
> hd([1,2,3,4]).
1
> tl([1,2,3,4]).
[2,3,4]
> [Head | Tail] = [1,2,3,4].
> Head.
1
> Tail.
[2,3,4]
> [NewHead | NewTail] = Tail.
[2,3,4]
> NewHead.
2
-
Cons operator:
|
> %% yields improper list and cannot be used with standard erlang functions like length() > [1 | 2] [1 | 2] %% improper list > [1 | [2]] [1,2] %% proper list
-
Given the set {2n: n in L} where L is list [1,2,3,4]
> [2*N || N <- [1,2,3,4]]. [2,4,6,8]
-
add constraints by using ops that return boolean
> [X || X <- [1,2,3,4,5,6,7,8,9,10], X rem 2 =:= 0]. [2,4,6,8,10] > RestaurantMenu = [{steak, 5.99}, {beer, 3.99}, {lamb, 30.00}]. [{steak,5.99},{beer,3.99},{lamb,30.0}] > [{Item, Price * 1.07} || {Item, Price} <- RestaurantMenu, Price >= 3, Price < 10]. [{steak, 6.4093}, {beer, 4.2693}] > %% NewList = [Expression || Pattern <- List, Condition1, Condition2,... ConditionN].
- built-in functions - could not be implemented in pure erlang so defined in C
-
binary tree: {node, value, left, right} - left and right are either similar nodes or empty tuples
-
proplists - any list of tuples of form: [{key, value}]
-
orddict - ordered dictionary proplists - sorted
-
larger data - dicts (same interface as ordict) and gb trees
-
generally blanced trees - smart and naive mode
-
arrays not suited to erlang. no constant-time lookup - used Ports for this or C-Nodes if clustering needed
-
digraphs, queues