# Problem with Macro expression evaluation

**URL:** <https://discourse.julialang.org/t/problem-with-macro-expression-evaluation/24281>\
**Category:** New to Julia\
**Created:** [May 16, 2019, 1:30pm UTC](https://discourse.julialang.org/t/problem-with-macro-expression-evaluation/24281 "2019-05-16T13:30:50Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![mwolff](https://avatars.discourse-cdn.com/v4/letter/m/c2a13f/32.png) [@mwolff](https://discourse.julialang.org/u/mwolff)\
**Post date:** [May 16, 2019, 1:30pm UTC](https://discourse.julialang.org/t/problem-with-macro-expression-evaluation/24281/1 "2019-05-16T13:30:50Z")

</div>

Hello,

this is my first post and i need a little help with my macro problem

```julia
macro foo(f, x)
    Expr(:call, f, x)
end

macro foo(exp)
    quote
        $(esc(exp))
    end
end

function test(f)
    exp = Meta.parse(f)
    return @foo(exp)
end

p=@foo(cos, 30)
println(p, " : ", typeof(p))

p=test("cos(30)")
println(p, " : ", typeof(p))

```

The output from @foo is what i want and shows me the correct value  
But the output from test returns only the expression cos(30) and no value.

How can i change that without using eval?

best regards

Michael

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [May 16, 2019, 2:08pm UTC](https://discourse.julialang.org/t/problem-with-macro-expression-evaluation/24281/2 "2019-05-16T14:08:17Z")

</div>

> [@mwolff](#):
>
> How can i change that without using eval?

But isn’t that literally want you want to do? You want to take a string of arbitrary julia code, parse it to an expression and then evaluate that expression. That is done using `eval`.

---

<div class="post-metadata">

**Author:** ![mwolff](https://avatars.discourse-cdn.com/v4/letter/m/c2a13f/32.png) [@mwolff](https://discourse.julialang.org/u/mwolff)\
**Post date:** [May 16, 2019, 2:43pm UTC](https://discourse.julialang.org/t/problem-with-macro-expression-evaluation/24281/3 "2019-05-16T14:43:12Z")

</div>

Thanks for your reply

No i want the value of the expression like in the first example with @foo(cos, 30). Only that the value should returned by the function without the slow eval.

Everytime i read about julia macros i should not use eval because the macro do that supposedly. I don’t know

best regards

Michael

---

<div class="post-metadata">

**Author:** ![mwolff](https://avatars.discourse-cdn.com/v4/letter/m/c2a13f/32.png) [@mwolff](https://discourse.julialang.org/u/mwolff)\
**Post date:** [May 16, 2019, 3:28pm UTC](https://discourse.julialang.org/t/problem-with-macro-expression-evaluation/24281/4 "2019-05-16T15:28:36Z")

</div>

I changed the code a bit and escaped the parameters. That does the job what i want

```julia
macro foo(f, x)
    Expr(:call, esc(f), esc(x))
end

function test(f::Symbol, x)
    return @foo(f, x)
end

@time p=@foo(cos, 30)
println(p, " : ", typeof(p))

@time p=test(length, "justanotherText")
println(p, " : ", typeof(p))

```

best regards

Michael

---

<div class="post-metadata">

**Author:** ![rdeits](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rdeits/32/286_2.png) [@rdeits](https://discourse.julialang.org/u/rdeits)\
**Post date:** [May 16, 2019, 4:41pm UTC](https://discourse.julialang.org/t/problem-with-macro-expression-evaluation/24281/5 "2019-05-16T16:41:42Z")

</div>

Try running that code in a fresh Julia session. It actually throws an error on the call to `test()`:

```julia
julia> @time p=test(length, "justanotherText")
ERROR: MethodError: no method matching test(::typeof(length), ::String)
Closest candidates are:
  test(::Symbol, ::Any) at REPL[2]:2
Stacktrace:
 [1] top-level scope at util.jl:156

```

That makes sense, because your function `test()` is only defined on `::Symbol`, but `length` is a `Function`. I suspect that you’re actually calling some other version of `test()` which was defined earlier in your Julia session.

---

<div class="post-metadata">

**Author:** ![mwolff](https://avatars.discourse-cdn.com/v4/letter/m/c2a13f/32.png) [@mwolff](https://discourse.julialang.org/u/mwolff)\
**Post date:** [May 16, 2019, 7:07pm UTC](https://discourse.julialang.org/t/problem-with-macro-expression-evaluation/24281/6 "2019-05-16T19:07:29Z")

</div>

Hi,

thanks for your answer 🙂

Yes i have the same problem here with a new Session!  
You must delete the ::Symbol definition in test and then it should go.

best regards  
Michael

---

<div class="post-metadata">

**Author:** ![ffevotte](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ffevotte/32/6587_2.png) [@ffevotte](https://discourse.julialang.org/u/ffevotte)\
**Post date:** [May 16, 2019, 8:09pm UTC](https://discourse.julialang.org/t/problem-with-macro-expression-evaluation/24281/7 "2019-05-16T20:09:22Z")

</div>

I’m not sure I understand what you want to achieve here… Could you please explain how the last code you posted relates to the title of this thread? Or maybe take a step back and explain what your bigger problem is?

Also, consider your proposed solution:

```julia
macro foo(f, x)
    Expr(:call, esc(f), esc(x))
end

function test(f, x)
    return @foo(f, x)
end

```

which benchmarks like this (`BenchmarkTools`, which is more reliable than just `@time` since it avoids measuring compilation times):

```julia
julia> @btime test(length, "justanotherText");
  15.426 ns (0 allocations: 0 bytes)

julia> p=test(length, "justanotherText");
julia> println(p, " : ", typeof(p))
15 : Int64

```

Is this not a rather complicated way of applying a function to a value, like for example:

```julia
function apply(f, x)
    f(x)
end

```

```julia
julia> @btime apply(length, "justanotherText");
  15.062 ns (0 allocations: 0 bytes)

julia> p = apply(length, "justanotherText");
julia> println(p, " : ", typeof(p))
15 : Int64

```

or even a plain

```julia
julia> @btime length("justanotherTest")
  15.421 ns (0 allocations: 0 bytes)
15

```

These ways of expressing things have the same performance as your proposed solution, which is arguably more difficult to understand; wouldn’t you think?

---

<div class="post-metadata">

**Author:** ![mwolff](https://avatars.discourse-cdn.com/v4/letter/m/c2a13f/32.png) [@mwolff](https://discourse.julialang.org/u/mwolff)\
**Post date:** [May 16, 2019, 9:45pm UTC](https://discourse.julialang.org/t/problem-with-macro-expression-evaluation/24281/8 "2019-05-16T21:45:15Z")

</div>

Hello,

I am currently working on a oldschool basic interpreter for fun, where every detail in a line is a string array.  
Example of a function

```julia
10 x = Mid ("justanothertext", 5, 3)
becomes
line = ["10", "x", "Mid", "\"justanothertext\"", "5", "3"]

```

if the function is recognized as existing, I create an expression with e = Expr (: call, symbol (“MID”), line, pos).  
pos points to the first parameter in my function.  
It looks like this

```julia
function MID (line :: Array {String, 1}, pos :: Int) # s = Mid ("NocheinText", 5,3) => ein
    s = ""; start = 0; num = 0; erg = ""
    try
        s = getCheckedValue (MEMDICT, line, pos)
        start = getCheckedValue (MEMDICT, line, pos + 1)
        num = getCheckedValue (MEMDICT, line, pos + 2)
        erg = s [start: start + num-1]
    catch e
        printError (e, line)
    end

    return pos + 2, erg
end

```

Will then be executed with eval (e). Works well too …  
MEMDICT is my variable memory as a dictionary  
x = 5 =\> MEMDICT [“x”] = 5  
getCheckedValue checks if variable exists or a value(number…)!

---

<div class="post-metadata">

**Author:** ![ffevotte](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ffevotte/32/6587_2.png) [@ffevotte](https://discourse.julialang.org/u/ffevotte)\
**Post date:** [May 16, 2019, 10:04pm UTC](https://discourse.julialang.org/t/problem-with-macro-expression-evaluation/24281/9 "2019-05-16T22:04:48Z")

</div>

Couldn’t you have some sort of dictionary storing all recognised functions? You probably already have some sort of dynamic data structure listing existing functions in order to recognize legit calls… (or you could use the same `MEMDICT` as for variables)

This would allow to avoid expressions, macros and `eval` altogether, and do simple things like:

```julia
foo(line) = "foo($(line[2]))"
bar(line) = "bar($(line[2]))"

const functions = Dict("FOO" => foo,
                       "BAR" => bar)

interpret(line) = functions[uppercase(line[1])](line)

```

```julia
julia> interpret(["foo", "arg"])
"foo(arg)"

```

---

<div class="post-metadata">

**Author:** ![mwolff](https://avatars.discourse-cdn.com/v4/letter/m/c2a13f/32.png) [@mwolff](https://discourse.julialang.org/u/mwolff)\
**Post date:** [May 17, 2019, 9:54am UTC](https://discourse.julialang.org/t/problem-with-macro-expression-evaluation/24281/10 "2019-05-17T09:54:39Z")

</div>

Yes you are right. Have a separate dictionary for almost everything.  
Jump table for GOTO and FOR … NEXT. For IF … THEN I take the Dictionary of GOTO  
Thank you for your suggestions.

best regards

Michael
