Skip to content

Instantly share code, notes, and snippets.

@67hz
Last active July 26, 2019 01:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save 67hz/3c311dce0acf653472ab924296beccd9 to your computer and use it in GitHub Desktop.
Save 67hz/3c311dce0acf653472ab924296beccd9 to your computer and use it in GitHub Desktop.
My Erlang Notes circa 2004 with some recent additions

Erlang

  • 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

The Language

Variables start with Capital Letter:

> One = 1.
1

atoms

> 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

boolean

> true and false.
false
> false or true.
true
> true xor false.
true
> not false.
true
> not (true and true).
false

conditional testing

> 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

true and false are only atoms

> 0 == false.
false
> 1 < false.
true

ordering types for comparison

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

pattern-matching

tuple

> {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

Concat

[1,2,3] ++ [4,5]. [1,2,3,4,5] [1,2,3,4,5] -- [4,5]. [1,2,3]

right-associative

	> [1,2,3] -- [1,2] -- [3].
	[3]

[head | tail]

	> hd([1,2,3,4]).
	1
	> tl([1,2,3,4]).
	[2,3,4]

slice element off list

	> [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
    

list comprehensions

  • 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].
    

BIFS

  • built-in functions - could not be implemented in pure erlang so defined in C

Data Structures

Sets - collection of unique values

Lists and Tuples are usually enough to cover most data structures

  • 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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment