julia學習筆記:元編程-表達式

簡介編程


元編程是Lisp最強大的特性(參考官方文檔介紹,我沒有用過Lisp),元編程即將代碼視做程序自己的數據結構,它使得程序能夠改變生成本身的代碼。
一、程序表示數據結構


這裏介紹兩種建立表達式的方式Meta.parse和Expr。code

1). 用字符串表示代碼,而後用Meta.parse轉換成表達式,如:對象

julia> prog = "1 + 1"
"1 + 1"

julia> ex1=Meta.parse(prog)
:(1 + 1)

2). 也能夠直接經過表達式對象生成:element

julia> ex2 = Expr(:call, :+, 1, 1)
:(1 + 1)

3) 表達式有兩個部分,head和args:文檔

julia> ex1.head
:call

julia> ex1.args
3-element Array{Any,1}:
  :+
 1
 1

4) 或者直接用dump查看錶達式:字符串

julia> dump(ex1)
Expr
  head: Symbol call
  args: Array{Any}((3,))
    1: Symbol +
    2: Int64 1
    3: Int64 1

2.表達式與求值io


1). 冒號也能夠用來建立表達式,和Meta.parse,Expr建立的表達式是等價的變量

julia> ex = :(a+b*c+1)
:(a + b * c + 1)

2). 使用quote ... end結構建立表達式引用

julia> ex = quote
           x = 1
           y = 2
           x + y
       end
quote
    #= none:2 =#
    x = 1
    #= none:3 =#
    y = 2
    #= none:4 =#
    x + y
end

三、插值(Interpolation)


插值即插入表達式中的值,用$開頭表示,以下表達式$a即插值,

julia> a = 1;

julia> ex = :($a + b)
:(1 + b)

julia> ex1 = :(a+b)
:(a + b)

它與直接使用變量的ex1區別在於,ex中a的值已經被寫入表達式中a若是在後面改變了,ex不變;而ex1中a的值是隨a變化,如:

julia> b=4
4

julia> eval(ex)
5

julia> eval(ex1)
5

julia> a=3
3

julia> eval(ex)
5

julia> eval(ex1)
7

四、嵌套引用表達式


使用quote...end 能夠定義多行表達式,也能夠定義單行表達式。甚至能夠多層嵌套:

julia> x = :(1 + 2);

julia> e = quote quote $x end end
quote
    #= none:1 =#
    $(Expr(:quote, quote
    #= none:1 =#
    $(Expr(:$, :x))
end))
end

e是嵌套表達式。注意這裏有一個Expr(:$, :x),代表x並無被求值,它屬於內層表達式。
對e求值能夠獲得內層表達式,這時$x會被求值:

julia> eval(e)
quote
    #= REPL[2]:1 =#
    3 + 4
end

使用雙$符能夠將x的值插入:

julia> e = quote quote $$x end end
quote
    #= none:1 =#
    $(Expr(:quote, quote
    #= none:1 =#
    $(Expr(:$, :(1 + 2)))
end))
end

這裏x已經被求值了,這個表達式定義以後就不隨x改變了。
對e求值產生插值3:

julia> eval(e)
quote
    #= none:1 =#
    3
end

看一下多層嵌套的例子:

julia> e2=quote quote quote $$x end end end
quote
    #= REPL[37]:1 =#
    $(Expr(:quote, quote
    #= REPL[37]:1 =#
    $(Expr(:quote, quote
    #= REPL[37]:1 =#
    $(Expr(:$, :($(Expr(:$, :x)))))
end))
end))
end

julia> e3=quote quote quote $$$x end end end
quote
    #= REPL[38]:1 =#
    $(Expr(:quote, quote
    #= REPL[38]:1 =#
    $(Expr(:quote, quote
    #= REPL[38]:1 =#
    $(Expr(:$, :($(Expr(:$, :(4 + 6))))))
end))
end))
end
相關文章
相關標籤/搜索