# Macro in function scope

**URL:** <https://discourse.julialang.org/t/macro-in-function-scope/31858>\
**Category:** New to Julia\
**Tags:** macros, metaprogramming\
**Created:** [December 4, 2019, 2:53pm UTC](https://discourse.julialang.org/t/macro-in-function-scope/31858 "2019-12-04T14:53:27Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![Kruxigt](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kruxigt/32/11694_2.png) [@Kruxigt](https://discourse.julialang.org/u/Kruxigt)\
**Post date:** [December 4, 2019, 2:53pm UTC](https://discourse.julialang.org/t/macro-in-function-scope/31858/1 "2019-12-04T14:53:27Z")

</div>

Wow, I’ve been spending the last few days trying to understand metaprogramming in Julia and specifically Macros. Not much luck! Take the code below:

```julia
a = "p > 0.5"
function test(a)
   for p in [0,1,2]
      if @my_macro(a)
         # evaluate here if p (in this scope) is larger than 0.5
      end
   end
end

```

How should **my\_macro** look for this to work? Is this good practice? In reality I expect **a** to be a vector of several conditions on different variables which should all be fulfilled.

Thank you!

---

<div class="post-metadata">

**Author:** ![mauro3](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mauro3/32/292_2.png) [@mauro3](https://discourse.julialang.org/u/mauro3)\
**Post date:** [December 4, 2019, 3:21pm UTC](https://discourse.julialang.org/t/macro-in-function-scope/31858/2 "2019-12-04T15:21:15Z")

</div>

Welcome to Julia-discourse!

When the macro is evaluated it only sees `:a` and not what eventually ends up in `a`. Thus this cannot work.

Just do a double loop?

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [December 4, 2019, 3:25pm UTC](https://discourse.julialang.org/t/macro-in-function-scope/31858/3 "2019-12-04T15:25:35Z")

</div>

Macros are not magic, neither is metaprogramming. There’s almost nothing that macro can do for you if you can’t write the code without a macro (the few exceptions being syntax that we only expose via macro like `@goto`).

---

<div class="post-metadata">

**Author:** ![Kruxigt](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kruxigt/32/11694_2.png) [@Kruxigt](https://discourse.julialang.org/u/Kruxigt)\
**Post date:** [December 4, 2019, 3:34pm UTC](https://discourse.julialang.org/t/macro-in-function-scope/31858/4 "2019-12-04T15:34:13Z")

</div>

Thanks for your answers! Ok, so I take it from your answers that a macro is not suitable for this task, or even able to perform it.

My thought was that if I had the more realistic case with a vector **a** :

```julia
a = ["p1 > 1", "p1 > p2", "p1 < 9", "p2 > 3", etc..]

```

it would be really clean if i could get the expression

```julia
p1 > 1 && p1 > p2 && p1 < 9 && p2 > 3 # etc..

```

straght into my code. As it seems that I am misstaken in what is suitable for metaprogramming, how would you do this?  
Thanks!

---

<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:** [December 4, 2019, 3:38pm UTC](https://discourse.julialang.org/t/macro-in-function-scope/31858/5 "2019-12-04T15:38:33Z")

</div>

It’s almost never necessary nor useful to store expressions in Julia as strings. In fact, in your case there is no reason to store any kind of expression or do any metaprogramming: you can store _functions_ instead:

```julia
a = p -> (p > 0.5)
function test(a)
   for p in [0,1,2]
      if a(p)
         println("true")
      end
   end
end

```

---

<div class="post-metadata">

**Author:** ![Kruxigt](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kruxigt/32/11694_2.png) [@Kruxigt](https://discourse.julialang.org/u/Kruxigt)\
**Post date:** [December 4, 2019, 9:41pm UTC](https://discourse.julialang.org/t/macro-in-function-scope/31858/6 "2019-12-04T21:41:04Z")

</div>

Thanks for all the answers! The reason I wanted to use strings was for the user to be able call the function in the REPL with various conditions specified in a simple manner. Maybe the approach with **a = p → (p \> 0.5)** will do. I guess that is what I will have to examine for now.

---

<div class="post-metadata">

**Author:** ![GunnarFarneback](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gunnarfarneback/32/1827_2.png) [@GunnarFarneback](https://discourse.julialang.org/u/GunnarFarneback)\
**Post date:** [December 4, 2019, 10:47pm UTC](https://discourse.julialang.org/t/macro-in-function-scope/31858/7 "2019-12-04T22:47:04Z")

</div>

See [Passing a string into function as a expression - #14 by GunnarFarneback](https://discourse.julialang.org/t/passing-a-string-into-function-as-a-expression/31625/14) if you really want to explore evaluating strings. Be aware that it’s in many ways an inferior solution and definitely slower, but sometimes it may be what you want.

---

<div class="post-metadata">

**Author:** ![Kruxigt](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kruxigt/32/11694_2.png) [@Kruxigt](https://discourse.julialang.org/u/Kruxigt)\
**Post date:** [December 5, 2019, 11:09am UTC](https://discourse.julialang.org/t/macro-in-function-scope/31858/8 "2019-12-05T11:09:21Z")

</div>

Again, thanks for all the answers!  
I am now informed that this is bad practice but I still don’t fully understand why it can only be evaluated at runtime. Why can’t **a \> b** be inserted into the code at compile time by a macro and then later evaluated for the **a** and **b** that exist during runtime?

---

<div class="post-metadata">

**Author:** ![dawbarton](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dawbarton/32/215461_2.png) [@dawbarton](https://discourse.julialang.org/u/dawbarton)\
**Post date:** [December 5, 2019, 11:47am UTC](https://discourse.julialang.org/t/macro-in-function-scope/31858/9 "2019-12-05T11:47:00Z")

</div>

It’s because of how macros work - they see the expression passed to them and not the value of the expression. So `@my_macro(a)` sees the symbol `:a` rather than the contents of `a`. For example, the following macro sort-of does what you want but not really - notice the difference between using a string literal as the argument and a string variable.

```julia
julia> macro my_macro(a)
           println("a = ", repr(a)) # to see what a actually is
           return esc(Meta.parse(a))
       end
@my_macro (macro with 1 method)

julia> p = 0.1
0.1

julia> @my_macro("p < 0.5")
a = "p < 0.5"
true

julia> a = "p < 0.5"
"p < 0.5"

julia> @my_macro(a)
a = :a
ERROR: LoadError: MethodError: no method matching parse(::Symbol)
Closest candidates are:
  parse(::AbstractString; raise, depwarn) at meta.jl:215
  parse(::AbstractString, ::Integer; greedy, raise, depwarn) at meta.jl:176
Stacktrace:
 [1] @my_macro(::LineNumberNode, ::Module, ::Any) at .\REPL[20]:3
in expression starting at REPL[24]:1

```

The key thing is that the contents of `a` are not defined at compile time. (Also, as per the warnings above, doing this with strings is somewhat fragile and open to abuse.)

---

<div class="post-metadata">

**Author:** ![mauro3](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mauro3/32/292_2.png) [@mauro3](https://discourse.julialang.org/u/mauro3)\
**Post date:** [December 5, 2019, 12:13pm UTC](https://discourse.julialang.org/t/macro-in-function-scope/31858/10 "2019-12-05T12:13:02Z")

</div>

This one might be informative to watch: [Jacob Quinn: What happens when - From parse time to compile time - YouTube](https://youtu.be/RYZkHudRTvI)
