Julia Macro Summary

Julia code is represented by objects that can be created and manipulated from within the language.
Macro is used to generate code.

Expr

Abstract syntax tree

Julia code will be parsed into Expr,
eg:

 julia> dump(r)
 Expr
   head: Symbol =
   args: Array(Any,(2,))
     1: Symbol a
     2: Int64 1
   typ: Any

The expr works like other code.

Fields

head: identifying the kind of expression. eg: :call, :+, :block
args, an array of subexpressions.
typ, field is used by type inference to store type annotations,
isn't used for most time

Usage

Quoting

   ex = :(a+b*c+1)
   ex2 = quote x=1
               y=2
               x+y
        end
   ex2.head
 # block
 #+END_SRC

Use Expr

   a, b, c = 1, 2, 3
   ex1 = Expr(:call)
   ex1.args = [:*, :b, :c]

   ex = Expr(:call)
   ex.args = [:+, :a, ex1]

   eval(ex)
   7

   Meta.show_sexpr(ex)

Macro

How it works

Julia macro
A macro is a way of generating a new output expression, given an unevaluated input expression.
When your Julia program runs, it first parses and evaluates the macro,
and the processed code produced by the macro is eventually evaluated like an ordinary expression.

  macro foo()
    println("macro foo is evalued")
    :("foo")
  end


  function f()
    println("f is execulated")
    @foo()
  end

  # got 'macro foo is evalued' in REPL,
  # so this means, f is compiled and the macro generate the code.

  'f.env.defs.func.code '
  will got
  AST(:($(Expr(:lambda, Any[], Any[Any[],Any[],Any[]], :(begin  # none, line 2:
                                                           println("f is execulated") # line 3:
                                                           return "foo"
                                                         end)))))
  f()
  # f is execulated
  # "foo"

Why we need macro?

Allow the programmer to generate and include fragments of customized code before the full program is run

Methods: eval, $, :, esc

1. eval
   eval expression in top level
2. $
   will eval in a quote
3. :
   quote
4. esc
   escape
   Do not let Julia generates new symbol for a variable.

   The Clojure works in the opposite way, Clojure use variable# to generate symbol.

'$' vs 'eval'

 |       | $             | eval     |
 |-------+---------------+----------|
 | usage | :($a)         | eval(:a) |
 | scope | current place | global   |

More useful methods

 dump: dump expression
 Meta.show_sexpr: print an AST as an S-expression
 parse: parse string to expresion
 macroexpand: macroexpand(:(@macro(a)))

Tricks

Macro syntax sugar for string

   macro p_str(s)
     println(s)
   end

   p"abc"

macro with multiple lines

 @my_macro begin
    ...
    ...
 end

How to create a macro for creating a symbol in Julia

 macro s_str(p)
   :(symbol($p))
 end

 r = s"c"

 # another way
 macro s(p)
  QuoteNode(p)
 end
 r = @s(a)
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 今天的心情起起落落,期待的事情如愿实现,有种心想事成的感觉,而生活中人际关系的处理让我有点累,总是怕说话得罪那个得...
    不讲理要飞天阅读 55评论 0 0
  • 本以为今年冬天不会有雪了,可短短一夜,雪已经不经意地把城市的一砖一瓦上覆上白色。这场雪刚下在立春后面,有不怕...
    疯子安娜阅读 170评论 0 0

友情链接更多精彩内容