- Elixir - Libraries
- Elixir - Macros
- Elixir - Errors Handling
- Elixir - Behaviours
- Elixir - Typespecs
- Elixir - Comprehensions
- Elixir - Sigils
- Elixir - Processes
- Elixir - File I/O
- Elixir - Protocols
- Elixir - Structs
- Elixir - Streams
- Elixir - Enumerables
- Elixir - Loops
- Elixir - Recursion
- Elixir - Functions
- Elixir - Aliases
- Elixir - Modules
- Elixir - Maps
- Elixir - Keyword Lists
- Elixir - Lists and Tuples
- Elixir - Char Lists
- Elixir - Strings
- Elixir - Decision Making
- Elixir - Pattern Matching
- Elixir - Operators
- Elixir - Variables
- Elixir - Data Types
- Elixir - Basic Syntax
- Elixir - Environment
- Elixir - Overview
- Elixir - Home
Elixir Useful Resources
Selected Reading
- Who is Who
- Computer Glossary
- HR Interview Questions
- Effective Resume Writing
- Questions and Answers
- UPSC IAS Exams Notes
Epxir - Macros
Macros are one of the most advanced and powerful features of Epxir. As with all advanced features of any language, macros should be used sparingly. They make it possible to perform powerful code transformations in compilation time. We will now understand what macros are and how to use them in brief.
Quote
Before we start talking about macros, let us first look at Epxir internals. An Epxir program can be represented by its own data structures. The building block of an Epxir program is a tuple with three elements. For example, the function call sum(1, 2, 3) is represented internally as −
{:sum, [], [1, 2, 3]}
The first element is the function name, the second is a keyword pst containing metadata and the third is the arguments pst. You can get this as the output in iex shell if you write the following −
quote do: sum(1, 2, 3)
Operators are also represented as such tuples. Variables are also represented using such triplets, except that the last element is an atom, instead of a pst. When quoting more complex expressions, we can see that the code is represented in such tuples, which are often nested inside each other in a structure resembpng a tree. Many languages would call such representations an Abstract Syntax Tree (AST). Epxir calls these quoted expressions.
Unquote
Now that we can retrieve the internal structure of our code, how do we modify it? To inject new code or values, we use unquote. When we unquote an expression it will be evaluated and injected into the AST. Let us consider an example(in iex shell) to understand the concept −
num = 25 quote do: sum(15, num) quote do: sum(15, unquote(num))
When the above program is run, it produces the following result −
{:sum, [], [15, {:num, [], Epxir}]} {:sum, [], [15, 25]}
In the example for the quote expression, it did not automatically replace num with 25. We need to unquote this variable if we want to modify the AST.
Macros
So now that we are famipar with quote and unquote, we can explore metaprogramming in Epxir using macros.
In the simplest of terms macros are special functions designed to return a quoted expression that will be inserted into our apppcation code. Imagine the macro being replaced with the quoted expression rather than called pke a function. With macros we have everything necessary to extend Epxir and dynamically add code to our apppcations
Let us implement unless as a macro. We will begin by defining the macro using the defmacro macro. Remember that our macro needs to return a quoted expression.
defmodule OurMacro do defmacro unless(expr, do: block) do quote do if !unquote(expr), do: unquote(block) end end end require OurMacro OurMacro.unless true, do: IO.puts "True Expression" OurMacro.unless false, do: IO.puts "False expression"
When the above program is run, it produces the following result −
False expression
What is happening here is our code is being replaced by the quoted code returned by the unless macro. We have unquoted the expression to evaluate it in current context and also unquoted the do block to execute it in its context. This example shows us metaprogramming using macros in epxir.
Macros can be used in much more complex tasks but should be used sparingly. This is because metaprogramming in general is considered a bad practice and should be used only when necessary.
Advertisements