Slide 1

Slide 1 text

*OUSPUP&MJYJSNBDSP !UPOZ

Slide 2

Slide 2 text

0WFSWJFX ˙ 8IBU’TNBDSP ˙ 8IZNBDSP ˙ )PXJTNBDSPJNQMFNFOUFEJO&MJYJS ˙ )PXUPVTF ˙ 8IFOUPVTF

Slide 3

Slide 3 text

8IBU’TNBDSP

Slide 4

Slide 4 text

"NBDSPJTBOPSEJOBSZQJFDFPG-JTQDPEFUIBU PQFSBUFTPOBOPUIFSQJFDFPGQVUBUJWF-JTQ DPEF USBOTMBUJOHJUJOUP BWFSTJPODMPTFSUP FYFDVUBCMF-JTQ .BDSPJO-JTQ IUUQDMDPPLCPPLTPVSDFGPSHFOFUNBDSPTIUNM

Slide 5

Slide 5 text

"NBDSPJTBOPSEJOBSZQJFDFPG&MJYJSDPEF UIBUPQFSBUFTPOBOPUIFSQJFDFPGRVPUFE&MJYJS DPEF USBOTMBUJOHJUJOUPRVPUFE&MJYJS .BDSPJO&MJYJS

Slide 6

Slide 6 text

EFGNBDSP defmodule MyLogic do defmacro unless(expr, opts) do quote do if !unquote(expr), unquote(opts) end end end require MyLogic MyLogic.unless false do IO.puts "It works" end

Slide 7

Slide 7 text

&MJYJSDPEFUP"45 sum(1, 2, 3) => {:sum, [], [1, 2, 3]} x => {:x, [], Elixir} %{1 => 2} => {:%{}, [], [{1, 2}]} Foo.run(1, 2) => {{:., [], [{:__aliases__, [alias: false], [:Foo]}, :run]}, [], [1, 2]}

Slide 8

Slide 8 text

RVPUF quote do defmodule Foo do def foo do 1 end end end {:defmodule, [context: Elixir, import: Kernel], [{:__aliases__, [alias: false], [:Foo]}, [do: {:def, [context: Elixir, import: Kernel], [{:foo, [context: Elixir], Elixir}, [do: 1]]}]]}

Slide 9

Slide 9 text

.FUBQSPHSBNNJOH XJLJQFEJB ˙ $PNQVUFSQSPHSBNTIBWFUIFBCJMJUZUPUSFBU QSPHSBNTBTUIFJSEBUB ˙ "QSPHSBNDBOCFEFTJHOFEUPSFBE HFOFSBUF BOBMZTFPSUSBOTGPSNPUIFSQSPHSBNT

Slide 10

Slide 10 text

8IZNBDSP

Slide 11

Slide 11 text

.FUBQSPHSBNNJOH XJLJQFEJB ˙ .JOJNJ[FUIFBNPVOUPGDPEFUPFYQSFTTB TPMVUJPO BOEUIVTSFEVDJOHUIFEFWFMPQNFOU UJNF ˙ .PWFDPNQVUBUJPOTGSPNSVOUJNFUPDPNQJMF UJNF ˙ (FOFSBUFDPEFVTJOHDPNQJMFUJNF DPNQVUBUJPOT

Slide 12

Slide 12 text

MFTTDPEF NPSFFFDUJWF defmodule MyRouter do use Plug.Router plug :match # middleware plug :dispatch # middleware get "/hello" do # logic for a route send_resp(conn, 200, "world") end end

Slide 13

Slide 13 text

DPNQVUFBUDPNQJMFUJNF # config.yml web_port: 8080 Config.get(:web_port) => 8080 OPUBHPPEFYBNQMF

Slide 14

Slide 14 text

(FOFSBUFDPEF iex> String.upcase("Elixir Shànghăi") "ELIXIR SHÀNGHĂI" IUUQTHJUIVCDPNFMJYJSMBOHFMJYJSCMPCNBTUFS MJCFMJYJSVOJDPEFVOJDPEFFY-

Slide 15

Slide 15 text

)PXJTNBDSPJNQMFNFOUFE JO&MJYJS

Slide 16

Slide 16 text

$PNQJMJOHPG&MJYJS

Slide 17

Slide 17 text

"OFYBNQMF defmodule Foo do defmacro add1(x) do quote do x + 1 end end end Foo.add1(2)

Slide 18

Slide 18 text

$PEFUP"45 quote do: Foo.add1(2) => { {:., [], [{:__aliases__, [alias: false], [:Foo]}, :add1]}, [], [2]}

Slide 19

Slide 19 text

.BDSPFYQBOTJPO require Foo Macro.expand(quote(do: Foo.add1(2)), __ENV__) => {:+, [context: Foo, import: Kernel], [{:x, [], Foo}, 1]} quote do: Foo.add1(2) => { {:., [], [{:__aliases__, [alias: false], [:Foo]}, :add1]}, [], [2]}

Slide 20

Slide 20 text

Macro.to_string({:+, [context: Foo, import: Kernel], [{:x, [], Foo}, 1]}) => "x + 1" "45UPDPEF

Slide 21

Slide 21 text

4PPVSDPEFDIBOHFTBGUFSFYQBOTJPO Foo.add1(2) => x + 1

Slide 22

Slide 22 text

No content

Slide 23

Slide 23 text

)PXUPVTF

Slide 24

Slide 24 text

5IJOLPGUIFOBMDPEF BGUFSFYQBOTJPO %FOFNBDSPTUPHFOFSBUFUIFDPEF 8SJUFBOESVOVOJUUFTUT PSSVOJOJFY  3FQFBU

Slide 25

Slide 25 text

&YBNQMFBTJNQMF'4.MJC VTJOH%4-

Slide 26

Slide 26 text

6TBHFPGUIFMJC defmodule Door do trans :push, "closed", "opened" trans :pull, "opened", "closed" end state0 = "closed" state1 = Door.push(state0) # "opened" state2 = Door.pull(state1) # "closed"

Slide 27

Slide 27 text

5IFFYQBOEFEDPEF defmodule Door do def push("closed") do "opened" end def pull("opened") do "closed" end end

Slide 28

Slide 28 text

4PXFOFFE  5IFBCJMJUZUPJOKFDUNBDSPUSBOT  6TFUSBOTUPHFOFSBUFGVODUJPOT

Slide 29

Slide 29 text

IUUQTIFYEPDTQNFMJYJS,FSOFMIUNMVTF VTFUPJOKFDUBNPEVMF

Slide 30

Slide 30 text

defmodule Door do use FSM trans :push, "closed", "opened" trans :pull, "opened", "closed" end # expanded => defmodule Door do import FSM.DSL, only: [trans: 3] # ... end

Slide 31

Slide 31 text

defmodule FSM do defmacro __using__(opts) do quote do import FSM.DSL, only: [trans: 3] end end end defmodule FSM.DSL do defmacro trans(name, from, to) do # ... end end

Slide 32

Slide 32 text

*NQMFNFOUUSBOTJO'4.%4- defmacro trans(name, from, to) do quote do def name(from) do to end end end 5IJTJTXSPOH

Slide 33

Slide 33 text

(FOFSBUFEDPEFXJMMCF defmodule Door do def name(from) do to end def name(from) do to end end 5IJTJTXSPOH

Slide 34

Slide 34 text

VORVPUFUPDPNQVUFFYQSFTTJPO CFGPSFNBDSPFYQBOTJPO defmacro trans(name, from, to) do quote do def unquote(name)(unquote(from)) do unquote(to) end end end

Slide 35

Slide 35 text

5IFDPEFDBOCFSVOJOJFY IUUQTHJTUHJUIVCDPN UPOZDDGFCCDBCFB MFGTNFYT

Slide 36

Slide 36 text

"OBEWBODFEGFBUVSF -JTUBMMFWFOUTPGUIF'4.

Slide 37

Slide 37 text

defmodule Door do use FSM trans :push, "closed", "opened" trans :pull, "opened", "closed" end Door.__events__ # => [:push, :pull]

Slide 38

Slide 38 text

˙ 8FDBOVTFNPEVMFBUUSJCVUFTUPTBWFBMMFWFOUT ˙ #VUNPEVMFBUUSJCVUFTDBO’UCFBDDFTTFEJO SVOUJNF ˙ 4PXFOFFEBGVODUJPOUPTBWFUIFBUUSJCVUFTJOB NPEVMFKVTUCFGPSFDPNQJMJOH DPNQJMFEUP CZUFTDPEF

Slide 39

Slide 39 text

IUUQTIFYEPDTQNFMJYJS.PEVMFIUNMNPEVMFDPNQJMFDBMMCBDLT

Slide 40

Slide 40 text

defmodule Door do @before_compile FSM.DSL # ... # expanded def __events__ do # ... end end

Slide 41

Slide 41 text

defmodule FSM do defmacro __using__(opts) do quote do @before_compile FSM.DSL end end end defmodule FSM.DSL do defmacro __before_compile__(env) do quote do def __events__ do # ... end end end end

Slide 42

Slide 42 text

6TFNPEVMFBUUSJCVUFTUPMJTUFWFOUT defmodule FSM do defmacro __using__(opts) do quote do Module.register_attribute(__MODULE__, :events, accumulate: true) end end end defmacro trans(name, from, to) do quote do @events unquote(name) # ... end end

Slide 43

Slide 43 text

BOEEFOF@@FWFOUT@@ CFGPSFDPNQJMJOH defmodule FSM.DSL do defmacro __before_compile__(env) do fields = Module.get_attribute(env.module, :events) quote do def __events__ do unquote(Enum.reverse(fields)) end end end end

Slide 44

Slide 44 text

5IFDPEFDBOCFSVOJOJFY IUUQTHJTUHJUIVCDPN UPOZDDGFCCDBCFBMFGTN FYT

Slide 45

Slide 45 text

8IFOUPVTFNBDSP

Slide 46

Slide 46 text

˙ 8IFOZPVOFFEUIFCFOFUTPGNBDSPT ˙ 8IFOGVODUJPOTDBO’UTPMWFZPVSQSPCMFNT ˙ 8IFOZPVXSJUFBMJCBOEXBOUUPQSPWJEF “GSJFOEMZ”"1* ˙ .BDSPTTIPVMEPOMZCFVTFEBTBMBTUSFTPSU

Slide 47

Slide 47 text

IUUQFMJYJSMBOHPSHHFUUJOHTUBSUFENFUBNBDSPTIUNMXSJUFNBDSPTSFTQPOTJCMZ 8SJUFNBDSPTSFTQPOTJCMZBOELFFQZPVS NBDSPEFOJUJPOTTIPSU

Slide 48

Slide 48 text

IUUQFMJYJSMBOHPSHHFUUJOHTUBSUFENFUBNBDSPTIUNM &YQMJDJUJTCFUUFSUIBOJNQMJDJU$MFBSDPEF JTCFUUFSUIBODPODJTFDPEF

Slide 49

Slide 49 text

2"