- functional programming language
- data is imutable
- key philosophy is everything runs around data transformations not mutating and managing state
- pass returned value from function to function never changing the value of the original input
- funcitons should take an input & always return the same value like a math formula
- uses pattern matching for function calling
- used to assign variables in the function
- multiple function declerations and determines what version shold get called based on the params matching
- runs on the erlang vm
- erlang vm runs everything in light weight processes instead of native threads
- crazy concurrency
- erlang has crazy uptime
- hot code deploys
- erlang runs about half the worlds telecom systems
- ruby inspired syntax
- iex a repl like rubys irb
- single quotes vs double quotes matter a lot
get helpers in iex
iex(1) h
# returns general IEx.Helpers module information
iex(2) h(IO)
# returns documentation on the IO module
iex(3) h(IO.puts)
# returns documentation on the IO module puts method
elixir uses files that end in .ex & .exs.
- .ex are files that will get compiled
- .exs are files that are run in a scripted fashion
from the console
# hello.exs
IO.puts("Hello World")
``
``` bash
$ elixir hello.exs
in iex
$ iex
iex(1) c "hello.exs"
Hello World
[]
# the c helper runs external files in iex
- uses pattern matching to assign variables
- handles structured data
- _ as a param in decleration ignores the value
- will take any value or to say it matches everything passed into it
- The = is a match operator not an assignmant
iex(1) list = [1,2,3]
iex(2) [a,b,c] = list
iex(3) a
1
iex(4) b
2
iex(5) c
3
variables bind once per match
iex(1) [a,a] = [1,1]
[1,1]
iex(2) [a,a] = [1,2]
** (MatchError) no match of right hand side value: [1, 2]
# force the use of existing assigned value with a ^ before the variable
iex(3) ^a = 2
** (MatchError) no match of right hand side value: 2
iex(4) [^a,b] = [2,2]
** (MatchError) no match of right hand side value: [2, 2]
the idea is if you pass 3 into a function regardless of what the function does 3 always is 3. Immutable data prevents a function running in parallel from changing the state. This prevents race conditions and allows for reliable concurrency.
num = 3
do_something(num)
print(num)
# 3 should be what gets printed. do something does not mutate num
elixir functions make a copy of the original data to act on. this way any functions that are working with the same data can rely on the data not to change.
this sounds super inefficient but because data is imutable other structures can be built from the existing data (see head tail recirsion as an example of this)
each process has its own heap and handles it's own garbage collection. this means smaller piles of data to gc at any given time and if the process finishes running before the heap is full it terminates and no gc run is needed.
- integers
- internal memory increases to fit the need
- floats
- atoms
- syntax looks like a ruby symbol
- are constants where the value of the atom is the name of the atom
- 2 atoms with the same name will always evaluate as being equal
- ranges
- regex
- PIDs & ports
- PID is a reference to a local or remote process
- a port is a reference to a resource (typically external to the application) that you’ll be reading or writing
- references
- tuples
- lists
- maps
- binaries