You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
$ brew install elixir
$ elixir --version
# Run interactive elixir
$ iex
# Running a elixir script
$ elixir test.exs
# Compiling elixir code to generate bytecode
elixirc math.ex
Language Basics
integer
>11>0x1F31>0b01106>div(5,2)2>rem(10,3)1
float
>5/22.5>trunc(2.58)2>round(2.58)3
boolean
# true, false>is_boolean(true)true>is_boolean(:false)true# and, or, not are short circuits# They only execute the right side if needed>trueand10error>true&&1010>nil||2222>!10false# comparison# == === != !== > < >= <=
>is_bitstring<<24,104>>true><<0,1>><><<2,3>><<0,1,2,3>>>"hello"<><<0>><<104,101,108,108,111,0>>>IO.inspect("hello",binaries: :as_binaries)<<104,101,108,108,111>>><<3::4>># or <<3::size(4)>> it means use 4 bits to store 3><<0::1,0::1,1::1,1::1>>==<<3::4>>true><<1>>===<<257>>true# because by default 8 bits is used and 257 stores as 000_000_01><<0,1,x>>=<<0,1,2>># x becomes 2><<0,1,x::binary>>=<<0,1,2,3>># x becomes <<2, 3>>><<head::binary-size(2),rest::binary>>=<<0,1,2,3>># head becomes <<0, 1>> rest becomes <<2, 3>>
binary
# a bitstring whose size is byte devisiable>is_binary("hellö")true
string
>is_string"elixir"true>to_string10"10"# Each unicode char could be 1 to 4 byte long>byte_size"hellö"6# O(1)>String.length"hellö"5# O(n)>String.upcase("hellö")"HELLÖ">"hel"<>"lo""hello">"hello #{:world}""hello world">IO.puts("Hello")Hello>"\u0061"==="a"true>String.valid?<<239,191,19>>false# binaries may or maynot be a valid string><<head,rest::binary>>="banana"# head becomes first byte or ?b and rest will be "anana"><<x,rest::binary>>="über"# x != ?ü because ü is more than 1 byte long><<x::utf8,rest::binary>>="über"# x == ?ü
list (linked list)
>is_list[1,2]true>is_list'abc'true>length[1,2,3]3# O(n)>hd[1,2,3]1>tl[1,2,3][2,3]>hd[]error>tl[]error>[1,2,3]++[4,5,6][1,2,3,4,5,6]>[1,2,3,3]--[1,3][2,3]>[a,b,c]=[1,2,3]# a = 1, b = 2, c = 3>[head|tail]=[1,2,3]# head = 1, tail = [2, 3]>[head|_]=[1,2,3]# head = 1, dont care about the rest >[0|[1,2]][0,1,2]>IO.inspect('hello',charlists: :as_lists)[104,101,108,108,111]
>is_tuple{1,2,3}true>tuple_size{:ok,"hello"}2# O(1)>elem{:ok,"hello"},1"hello"# O(1)>put_elem{:ok,"hello"},1,"world"{:ok,"world"}>{a,b,c}={:hello,"world",42}# => a = :hellp, b = "world", c = 42
function
add=fn(a,b)->a+bendadd=&(&1+&2)>is_function(add)true>is_function(add,2)true>add.(1,2)3f=fn(x,y)whenx>0->x+yend(x,y)->x-yendend>f=&Math.zero?/1# & Captures definition of a function
keyword lists
# keys are always atom # keys are not uniq# order of keys matter>[{:a,1},{:b,2}]==[a: 1,b: 2]true>a=[x: 0,x: 1,y: 2]>a[:x]0# Keyword is a module to work with this
maps
# keys can be any type# keys are uniq# keys are not ordered>m=%{:a=>1,2=>:b}>m.a1>m.2error# when all keys are atom>%{:a=>1,:b=>2}==%{a: 1,b: 2}true%{:a=>a}=%{:a=>1,2=>:b}# a = 1, it does not matter there is two keys at right but one at left>Map.to_list%{:a=>1,2=>:b}[{2,:b},{:a,1}]>Map.put(%{:a=>1,2=>:b},:c,3)%{2=>:b,:a=>1,:c=>3}map=%{a: 1,b: 2}>new_map=%{map|b: 5}# can only change the value of a key, does not add new keys
# for autocomplete press tab after .# info about data type of var>ivar# print docs>hround/1# code point for unicode char a>?a97# recompile>rModule# print types available in the module>tEnum
defmoduleMathdo# module attr# used for annotation, constant, and temporary storage@module_attr1# publicdefsum(a,b)doa+bend# privatedefpsum(a,b)doa+bendenddefmoduleMathdodefzero?(0)dotrueenddefzero?(x)whenis_integer(x)dofalseendenddefmoduleConcatdo# declare default values for a paramdefjoin(a,b,sep\\" ")doa<>sep<>bendend# declare default values for a multiple clause functiondefmoduleConcatdodefjoin(a,b\\nil,sep\\" ")defjoin(a,b,_sep)whenis_nil(b)doaenddefjoin(a,b,sep)doa<>sep<>bendend
list=[1,2,3]>Enum.each(list,fn(x)->IO.puts(x)end)# prints 1 2 3>Enum.map(list,fn(x)->x*2end)[2,4,6]>Enum.reduce(list,0,fn(x,acc)->x+accend)6odd?=&(rem(&1,2)==1)>Enum.filter(1..3,odd?)[1,3]
piping
# |> it takes the output from the expression on its left side# and passes it as the first argument to the function call on its right side>1..3|>Enum.to_list|>Enum.filterfn(x)->rem(x,2)==1end|>Enum.sum4
processes
>spawnfn->1+2end# another isolated process. exceptions are not revealed.>spawn_linkfn->1+2end# linked process. exceptions will propagate>sendpid,data# sends process a messagereceivedomatch_1->match_2->end# read more here: https://elixir-lang.org/getting-started/processes.html
Tasks
>Task.start# wraps spawn for better error handling>Task.start_linked# wraps spawn_linked for better error handling # read more here: https://elixir-lang.org/getting-started/processes.html
alias, use, require, import
# Alias the module so it can be called as Bar instead of Foo.BaraliasFoo.Bar,as: Bar# same asaliasFoo.BaraliasFoo.{Bar,Jar,Dar,Var}# Require the module in order to use its macrosrequireFoo# Import functions from Foo so they can be called without the `Foo.` prefiximportFoo# Invokes the custom code defined in Foo as an extension pointuseFoo