Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Intro to elixir metaprogramming


Published on

Metaprogramming - the process of using code to write code - is a core feature of Elixir. You can easily extend the language and dynamically change the code. Despite knowing the first rule of metaprogramming - "Don't use metaprogramming" - every Elixir developer should have an idea what it is.
This talk will introduce the audience to the main metaprogramming concepts of Elixir. You will know about Elixir abstract syntax tree, 'quoting', macros and compile-time hooks. I'll demonstrate how this stuff works using simple examples as well as cases from popular packages.

First Kyiv Elixir Meetup, June 23

Published in: Science
  • Be the first to comment

Intro to elixir metaprogramming

  1. 1. Intro to Elixir metaprogramming First Kyiv Elixir meetup, June 23, 2016
  2. 2. Hello! I am Anton Mishchuk from Lviv ▧ Ruby Dev at Matic (and we are hiring) ▧ Fan of Elixir programming language ▧ ESpec creator & maintainer ▧ GitHub: antonmi 2
  3. 3. Elixir is Erlang with pretty syntax and metaprogramming! What is Elixir? 3
  4. 4. ▧ Elixir AST ▧ Quote and unquote ▧ Macroses ▧ DSL ▧ Introspection What will be about 4
  5. 5. Why metaprogramming ▧ Extending language ▧ Boilerplate removing ▧ Creating DSL 5
  6. 6. Ecto.Schema Elixir metaprogramming in the wild Source code 6
  7. 7. Phoenix.Router Elixir metaprogramming in the wild Source code 7
  8. 8. ESpec.Let Elixir metaprogramming in the wild Source code 8
  9. 9. Initial code parsing Elixir code Initial AST Expansion Expanded AST Byte-code generation Byte-code Compilation process Magic is here! 9
  10. 10. Compile-time metaprogramming ▧ Code will not be redefined ▧ Static code analysis still works ▧ No performance penalty 10
  11. 11. Elixir AST. Quoting ‘quote’ macro gets the representation of any expression. 11
  12. 12. Elixir AST. Quoting 12
  13. 13. ▧ The first element is an atom identifying the operation or another tuple in the same representation ▧ The second element is a keyword list containing metadata, like numbers and contexts ▧ The third element is either a list of arguments for the function call or an atom. When this element is an atom, it means the tuple represents a variable Elixir AST - 3 element tuple 13
  14. 14. Elixir AST string representation ‘Macro.to_string’ converts the given expression to a binary 14
  15. 15. Elixir AST evaluation ‘Code.eval_string’ and ‘Code.eval_quoted’ 15
  16. 16. Elixir AST. Unquoting Unquoting is a mechanism to inject code chunks into quoted expressions. i.e. inject one AST fragment into another Let’s try an example: 16
  17. 17. Elixir AST. Unquoting Trying to evaluate ‘final_expr’ I want to build AST which adds 1 + 2 17
  18. 18. Elixir AST. Unquoting ‘unquote’ helps to inject AST fragment 18
  19. 19. Magic functions - Macros ▧ Macro (which stands for "macroinstruction") is a programmable pattern which translates a certain sequence of input into a preset sequence of output ▧ Macros receive the input AST and must produce the output AST ▧ The compiler will then simply replace the macro call with the AST returned from that macro ▧ Works only at compile time 19
  20. 20. ▧ ‘defmodule’, ‘defmacro’, ‘def’, defstruct ▧ ‘require’, ‘import’, ‘use’ ▧ ‘If’, ‘unless’, ‘cond’ ▧ etc, etc Macros are everywhere 87% of Elixir code written on Elixir 20
  21. 21. Macros. Example Calculator 21
  22. 22. Macros. Example The result is expect. Nothing special. Because we see completely compiled code in the iex console 22
  23. 23. Macros. Example Remember, macros receive quoted expression and return them Let’s do what compiler did step by step 23
  24. 24. Macros. Dynamic function definition example 24
  25. 25. Macros. ‘require’ and ‘import’ We should tell the compiler which module should be compiled before we can use it. 25
  26. 26. ‘use’ macro The simplest way to bring external functionality into the current lexical scope 26
  27. 27. ‘Use’ for DSL ‘Use Ecto.Migration’ ‘Ecto.Migration.__using__’ 27
  28. 28. ‘Use’ for DSL ‘use GenServer’ 28
  29. 29. ‘Use’ for DSL ‘GenServer.__using__’ 29
  30. 30. ‘Use’ for DSL ‘use ESpec’ 30
  31. 31. ‘Use’ for DSL ‘ESpec.__using__’ 31
  32. 32. OMG! How to handle all the stuff? ▧ What function/macro I can use in current scope? ▧ Where does this function/macro come from? 32
  33. 33. Elixir introspection ▧ __ENV__ : Returns a Macro.ENV struct containing current environment information ▧ __MODULE__ : Returns the current module name as an atom ▧ __DIR__ : Returns the current directory ▧ __CALLER__ : Returns the caller’s environment information as a Macro. ENV struct 33
  34. 34. Elixir introspection ‘__ENV__’ in iex 34
  35. 35. And don’t forget about help ‘h IEx.Helpers.b’ 35
  36. 36. What is next? 36
  37. 37. With great power comes great responsibility! Thank you! 37