# Problem with local scope

**URL:** <https://discourse.julialang.org/t/problem-with-local-scope/110556>\
**Category:** General Usage\
**Created:** [February 22, 2024, 2:42am UTC](https://discourse.julialang.org/t/problem-with-local-scope/110556 "2024-02-22T02:42:30Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![co1emi11er](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/co1emi11er/32/206849_2.png) [@co1emi11er](https://discourse.julialang.org/u/co1emi11er)\
**Post date:** [February 22, 2024, 2:42am UTC](https://discourse.julialang.org/t/problem-with-local-scope/110556/1 "2024-02-22T02:42:30Z")

</div>

I am faced with an issue that I can’t seem to figure out. Here is the source code (sorry I couldn’t come up with a more simple example):

```julia
macro handfunc(expr, kwargs...)
    expr = unblock(expr) # cleans expression
	expr = rmlines(expr) # cleans expression
    var = esc(expr.args[1]) # pulls variable name
    eq = esc(expr.args[2]) # pulls expression
    func_args = QuoteNode(expr.args[2]) #pulls function arguments to pass to function below
    found_func = InteractiveUtils.gen_call_with_extracted_types_and_kwargs( __module__ , :code_expr, (expr.args[2],)) # returns expression
    return quote
        x = handfunc($found_func, $func_args) # handfunc returns expression
        latex = $Main.eval(x) # need to evaluate it (but want to do it in calling scope)
        $var = $eq # evaluates expression
        latex # returns latex rendering
    end

end

```

Here is a snip of what it does (it currently works in main scope):

![image](https://global.discourse-cdn.com/julialang/original/3X/5/1/5142bd8d7d6cbae5abb8d7884115470afed93702.png)

It basically parses through the called function body and returns the latex rendering of it, while also evaluating the `Ix = Handcalcs.calc_Ix(b, h)` portion as well.

Here is my issue. I would like to return just the function and then the macro would automatically evaluate the returned expression, but I can’t since `found_func` is an expression that, if inside the function, wouldn’t be evaluated.

Basically, it seems like I am left with trying to use the eval function, but that is for global scope and I am not sure how to get it to evaluate in calling scope.

1. Is there a way to build an expression that would evaluate both?
2. Or is there a way to get eval to work for calling scope?

Here is the source code: [Handcalcs.jl-handfunc\_branch](https://github.com/co1emi11er2/Handcalcs.jl/blob/handfunc/src/Handcalcs.jl). Macro starts at line 183.

Any help is much appreciated.

---

<div class="post-metadata">

**Author:** ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)\
**Post date:** [February 22, 2024, 3:00am UTC](https://discourse.julialang.org/t/problem-with-local-scope/110556/2 "2024-02-22T03:00:39Z")

</div>

Don’t use `eval` — especially not in macros. Their job is to generate code, and it’ll get evaluated soon enough.

I think you want to call `handfunc` outside the `quote` block and then interpolate it in twice, once normally (which will be code that executes) and once into a quote node (to get the expression itself).

---

<div class="post-metadata">

**Author:** ![co1emi11er](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/co1emi11er/32/206849_2.png) [@co1emi11er](https://discourse.julialang.org/u/co1emi11er)\
**Post date:** [February 22, 2024, 3:36am UTC](https://discourse.julialang.org/t/problem-with-local-scope/110556/3 "2024-02-22T03:36:02Z")

</div>

```julia
macro handfunc(expr, kwargs...)
    expr = unblock(expr) # cleans expression
	expr = rmlines(expr) # cleans expression
    var = esc(expr.args[1]) # pulls variable name
    eq = esc(expr.args[2]) # pulls expression
    func_args = QuoteNode(expr.args[2]) #pulls function arguments to pass to function below
    found_func = InteractiveUtils.gen_call_with_extracted_types_and_kwargs( __module__ , :code_expr, (expr.args[2],)) # returns expression
    ret_expr = handfunc(found_func, func_args)
    return quote
        latex = $ret_expr
        $var = $eq # evaluates expression
        latex # returns latex rendering
    end

end

```

I just tried one interpolation first. This results in an error though because the found\_func is an expression that needs to be evaluated first.  
Before:

```julia
found_func = code_expr($(Expr(:escape, :calc_Ix)), (Base.typesof)($(Expr(:escape, 5)), $(Expr(:escape, 15))))

```

After:

```julia
found_func = :(function calc_Ix(b, h)
    #= C:\Users\CMILLER\.julia\dev\Handcalcs\src\Handcalcs.jl:158 =#
    #= C:\Users\CMILLER\.julia\dev\Handcalcs\src\Handcalcs.jl:159 =#
    Ix = (b * h ^ 3) / 12
    #= C:\Users\CMILLER\.julia\dev\Handcalcs\src\Handcalcs.jl:160 =#
    return Ix
end)

```

Could you give an example?

Thanks.

---

<div class="post-metadata">

**Author:** ![jules](https://avatars.discourse-cdn.com/v4/letter/j/41988e/32.png) [@jules](https://discourse.julialang.org/u/jules)\
**Post date:** [February 22, 2024, 11:28am UTC](https://discourse.julialang.org/t/problem-with-local-scope/110556/4 "2024-02-22T11:28:48Z")

</div>

Maybe this section of an older post of mine might help [jkrumbiegel.com - Julia macros for beginners](https://jkrumbiegel.com/pages/2021-06-07-macros-for-beginners/#whats-escaping)

I don’t understand the code you have there so I can’t really comment on it in detail. But when you get errors due to expressions like `$(Expr(:escape, :calc_Ix))` it usually means that you are escaping some piece of code twice.

Escaping has to be done at exactly the right granularity, ask yourself which of your code should appear in place of the macro _as if the user had written it_ (often this is a verbatim or almost verbatim copy of the actual code written by the user) and which of the code is helper code that relates only to your module and shouldn’t in any way interact with the other top-level user code. That’s the stuff you do not want to escape.

So when you have a double escaping error, your logic was flawed because marked a piece of code as user code, interpolated it into some other code, but then also marked that code as user code. In this case, the inner interpolated code should not have been escaped first because it was going to be anyway, as part of the escaped outer code. (Admittedly, this is sometimes an annoying complexity when writing macros, because you have to know for each expression fragment you generate what the final context it ends up in has to be, and if you’re allowed to escape or not.)

---

<div class="post-metadata">

**Author:** ![co1emi11er](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/co1emi11er/32/206849_2.png) [@co1emi11er](https://discourse.julialang.org/u/co1emi11er)\
**Post date:** [February 22, 2024, 1:56pm UTC](https://discourse.julialang.org/t/problem-with-local-scope/110556/5 "2024-02-22T13:56:05Z")

</div>

Yeah I don’t know… That code you are referring to is generated by a function in the InteractiveUtils library which is code I did not write. Even the function parameters I pass to it is copied from CodeTacking.jl. That code works great when I interpolate it into the quote.

The problem is (at least I think) I need to pass the interpolated code from that InteractiveUtils function to the function I wrote (handfunc). But my function also returns an expression, but since it is within a quote, it doesn’t evaluate when macro is called… That is why I am using the eval function to force it to evaluate, but eval is global scope only…

I guess a general question: Can you within a macro, use a function that generates an expression. This expression then needs to be evaluated somehow. Let’s call the evaluated expression `x`. Then use that `x` within another function that generates an expression that then needs to be evaluated?

---

<div class="post-metadata">

**Author:** ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)\
**Post date:** [February 22, 2024, 2:43pm UTC](https://discourse.julialang.org/t/problem-with-local-scope/110556/6 "2024-02-22T14:43:36Z")

</div>

At a fundamental level, macros should just generate the code to do what you want — they aren’t the ones to do it.

So yes, your macro can output code that defines a function and then calls it.

But I think you’re getting tied in knots because you’re currently outputting code that happens to evaluate to an expression. But that might be backwards — you probably want to just construct the expression at macro-time (outside the `quote`). Then you can reference the expression in two ways: once that defines the function and once quoted-ly.

To simplify this, here’s a macro only deals with functions of two arguments named `x` and `y`:

```julia-repl
julia> macro xy(expr)
           quote
               fun = ($(esc(:x)),$(esc(:y)))->$(esc(expr))
               ret = fun($(esc(:x)), $(esc(:y)))
               Expr(:(=), $(QuoteNode(expr)), ret)
           end
       end
@xy (macro with 1 method)

julia> let x=1, y=2
           @xy x+y^2
       end
:(x + y ^ 2 = 5)

julia> let x=3, y=2
           @xy x+y^2
       end
:(x + y ^ 2 = 7)

```
