Macros In Elixir Cassidy Gibson code that generates
Macros In Elixir Cassidy Gibson
code that generates code based on some input. ” “
Constructs such as… • defmodule • def • if • unless • defmacro …are all Macros
Macro Intensive • Minimal language core • Simplifies further extension to the language
While loop Now… We’ve seen a number of control flows in Elixir (if, for, unless, cond) but we don’t have while
To Understand Macros…
Expansion Phase • Makes it independent from the various execution paths of a program Follows Elixir’s idea of immutability More comfortable use being sure program isn’t being overwritten • No performance penalty
Creating AST fragments • AST fragments are also called quoted expressions • To generate the AST of some code we use quote
Creating AST fragments • NOTE: The quoted expression is not semantically verified * *The variables in an AST don’t exist in the current shell session
Creating AST Fragments • quote generated quoted references which only exist where AST will be interpreted • unquote directly injects its contents into the space of the AST • unquote can only exist within a quoted expression
Meta-Programing • Macros are the core to Meta-Programming Such as Objectdraw and Java are used for Object-Oriented Programming • essentially is composing AST fragments to form an alternate AST that represents code we want to produce • not interested in components or structure of ASTs • instead use quote to create and combine input fragments to make some larger program
Calling a Macro • Macros receive input AST • From which must produce output AST • Compiler replaces macro call with output AST
How It Works With The Compiler • The process is completed in increments Macros can return AST invoke other macros If such compiler re-expands to replace the macro call Will continue to do such until no more expansion is needed
Disillusioning Macro… • You haven’t gotten it figured out yet because as we’ve said before: 1. Macros run in the expansion phase 2. However the Macros are elixir code
So What Does That Mean? First • But To call a macro the containing module must already be compiled • To run macros used in a module it has to be compiled before that module We must leave hints for the compiler to follow require import
Macros are default Hygienic
Default macro variables are private, unless. . In the explicit case that the programmer wants a variable in a macro to be public it can be done The exception: var!(variable_name) use Gen. Server def call (resp) , do: {: ready, resp, state} use Plugs post ‘/…’ do send_resp(conn, 200, …) end • Both conn and state are not defined by their modules
Macro Arguments Macros are Elixir functions invoked in the expansion phase while final AST is produced For many constants their AST representations are the exact same as their input value
Syntax of AST Source Code Deconstruct it Interaction Context Variable a Variable b
Syntax of AST Source Code Deconstruct it Interaction B Interaction A Context of B Constants
Let’s Write Our First Macro! What do we have to do this? 1. defmodule 2. defmacro 3. quote 4. unquote
- Slides: 22