If you need to generate code where the outer function has access to some
part of a local scope, you can generate the entire function and then call
it:
julia> ex = :(x + 1)
:(x + 1)
julia> @eval function f(x)
y = $ex
return y^2
end
f (generic function with 1 method)
julia> f(2)
9
But note that if you want some piece of f to be "pasted" from the user and
have access to certain parts of the local state of f, it's probably a much
better design to let the user pass in a function which f calls, passing the
function the state that it should have access to:
julia> f(2)
9
julia> function g(h, x)
y = h(x)
return y^2
end
g (generic function with 1 method)
julia> g(x->x+1, 2)
9
It's three more characters to type, but the way you call g isn't coupled to
the local variable names that g happens to use (x), and you can pass named
functions like `abs` to g more easily. It also prevents someone from
passing in a bit of code that completely breaks the caller in unexpected
ways.
On Tue, Sep 27, 2016 at 9:00 AM, Fábio Cardeal <[email protected]> wrote:
> The lambda example works, but couldn't you do:
> function f(x)
> eval(:($x + 1))
> end
> ?
>
> You can still do that in a macro:
> macro m()
> quote
> ex = :($x + 1)
> eval(ex)
> end
> end
>
> function f(x)
> @m
> end
>
> f(1) == 2
>
>
> What would be a situation where this wouldn't work?
>
>
> Em terça-feira, 27 de setembro de 2016 09:36:48 UTC-3, Jussi Piitulainen
> escreveu:
>>
>> You might be able to wrap your expression so as to create a function
>> instead, and call the function with the values of the variables that the
>> actual expression depends on. In Python, because I haven't learned to
>> construct expressions in Julia yet and don't have the time to learn it now:
>>
>> def f(x): return eval("lambda x: x + 1")(x)
>>
>>
>>
>> tiistai 27. syyskuuta 2016 12.28.40 UTC+3 Marius Millea kirjoitti:
>>>
>>> Hi, is there a way to "eval" something in the current scope? My problem
>>> is the following, I've written a macro that, inside the returned
>>> expression, builds an expression which I need to eval. It looks like this,
>>>
>>> macro foo()
>>> quote
>>> ex = ...
>>> eval_in_current_scope(ex)
>>> end
>>> end
>>>
>>> Now, you might say I'm using macros wrong and I should just be doing,
>>>
>>> macro foo()
>>> ex = ...
>>> end
>>>
>>>
>>> but in this case when I build "ex", it needs to occur at runtime since
>>> it depends on some things only available then. So is there any way to go
>>> about this? Thanks.
>>>
>>>