Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to interpolate a symbol as a Symbol in a Julia Expr?

I would like to create a quote which gets the symbol :abc saved in variable x and push it into the array a. However I could only get the variable abc. The syntax :$x seems incorrect (not what I desired). What is the syntax to do this?:

julia> x = :abc
julia> expr = quote
         a = []
         push!(a, $x)
         push!(a, :($x))
         push!(a, :$x)
         a
       end
quote  
    a = [] 
    push!(a, abc) 
    push!(a, $(Expr(:quote, :($(Expr(:$, :x))))))
    push!(a, :$ * x) 
    a
end

The desired output is:

quote  
    a = [] 
    push!(a, :abc) 
    a
end
like image 775
Phuoc Avatar asked Jan 16 '18 01:01

Phuoc


People also ask

What is a symbol in Julia?

This is the essence of a symbol: a symbol is used to represent a variable in metaprogramming. Once you have symbols as a data type, of course, it becomes tempting to use them for other things, like as hash keys. But that's an incidental, opportunistic usage of a data type that has another primary purpose.

What is metaprogramming in Julia?

Meta-programming is when you write Julia code to process and modify Julia code. With the meta-programming tools, you can write Julia code that modifies other parts of your source files, and even control if and when the modified code runs. In Julia, the execution of raw source code takes place in two stages.

What is a macro in Julia?

Answer: Macros are sort of functions which take as input unevaluated expressions. ( Expr ) and return as output. another expression, whose code is then regularly evaluated at runtime. This post isn't a. substitute for reading the section about macros in the Julia.

What is quote in Julia?

This is referred to as quoting. The : character, followed by paired parentheses around a single statement of Julia code, produces an Expr object based on the enclosed code. Here is an example of the short form used to quote an arithmetic expression: julia> ex = :(a+b*c+1) :(a + b * c + 1) julia> typeof(ex) Expr.


1 Answers

You need to add another layer of quotation, using $(Meta.quot(:abc)) which is equivalent to $(Expr(:quote, :abc)).

Using:

              _
   _       _ _(_)_     |  A fresh approach to technical computing
  (_)     | (_) (_)    |  Documentation: https://docs.julialang.org
   _ _   _| |_  __ _   |  Type "?help" for help.
  | | | | | | |/ _` |  |
  | | |_| | | | (_| |  |  Version 0.6.2 (2017-12-13 18:08 UTC)
 _/ |\__'_|_|_|\__'_|  |  Official http://julialang.org/ release
|__/                   |  x86_64-pc-linux-gnu

Setup:

julia> x = :abc
:abc

julia> es = [x, :x, :(:x), Expr(:quote, x), Meta.quot(x)]    # :(x) is parsed as :x
5-element Array{Any,1}:                                  
 :abc                                                    
 :x                                                      
 :(:x)                                                   
 :(:abc)                                                 
 :(:abc)                                                 

julia> blk = Expr(:block)
quote
end

Push!:

julia> push!(blk.args, :(a = []))
1-element Array{Any,1}:
 :(a = [])

julia> blk
quote
    a = []
end

julia> for e in es
           push!(blk.args, :(push!(a, $e)))
       end

julia> blk
quote
    a = []
    push!(a, abc)
    push!(a, x)
    push!(a, :x)
    push!(a, :abc)
    push!(a, :abc)
end

julia> push!(blk.args, :a)
7-element Array{Any,1}:
 :(a = [])
 :(push!(a, abc))
 :(push!(a, x))
 :(push!(a, :x))
 :(push!(a, :abc))
 :(push!(a, :abc))
 :a

Eval:

julia> blk
quote
    a = []
    push!(a, abc)
    push!(a, x)
    push!(a, :x)
    push!(a, :abc)
    push!(a, :abc)
    a
end

julia> eval(ans)
ERROR: UndefVarError: abc not defined
Stacktrace:
 [1] eval(::Module, ::Any) at ./boot.jl:235
 [2] eval(::Any) at ./boot.jl:234

Fix:

julia> deleteat!(blk.args, 2)
6-element Array{Any,1}:
 :(a = [])
 :(push!(a, x))
 :(push!(a, :x))
 :(push!(a, :abc))
 :(push!(a, :abc))
 :a

julia> blk
quote
    a = []
    push!(a, x)
    push!(a, :x)
    push!(a, :abc)
    push!(a, :abc)
    a
end

julia> eval(ans)
4-element Array{Any,1}:
 :abc
 :x
 :abc
 :abc

Finally:

julia> using Base.Meta: quot

julia> x = :abc
:abc

julia> expr = quote
           a = []
           push!(a, $(quot(x)))
           a
       end
quote
    #= REPL[16]:2 =#
    a = []
    #= REPL[16]:3 =#
    push!(a, :abc)
    #= REPL[16]:4 =#
    a
end

julia> eval(ans)
1-element Array{Any,1}:
 :abc
like image 115
HarmonicaMuse Avatar answered Sep 19 '22 03:09

HarmonicaMuse