A function which has access to the namespace in which it was defined is
also known in Julia as a closure, or simply function. All functions are
first-class objects, which don't need eval or macros. Eval and macros are
really bad at pretending to be functions.

Without a bit more example code, it is hard to understand what problem you
are trying to solve. Macros are for reducing typing (syntax transforms),
not magic (altering the environment), which is why they generally don't
have access to the environment.

On Friday, August 1, 2014, Abe Schneider <[email protected]> wrote:

> I tried a second approach where instead of keeping a function around I
> keep just the symbol. I have a `transform` function that applies the
> function to the resulting values. However, this only moves the problem to a
> new place. In my `transform` method I have:
>
> eval(Expr(:call, action, values))
>
>
> where `action` is the symbol that I am now carrying around. The `eval`
> still works in the module's namespace, so I get the same error.
>
> If Julia had a way to access the namespace from the calling function, this
> could be made to work. Or for that matter, if I could get the calling
> namespace from the macro, I could then just get the macro that way.
>
> I'm guessing Julia doesn't currently have this functionality, but would it
> be something possible to add?
>
> On Friday, August 1, 2014 12:22:46 PM UTC-4, Abe Schneider wrote:
>>
>> I think the problem is that I'm not accessing it directly through the
>> macro parameters. The call:
>>
>> @grammar foo begin ... end
>>
>> passes just the single expression block to `foo`. Thus, I'm getting the
>> function from the resulting Expr tree. Even if I quote it, it still ends up
>> as an expression that contains a symbol that must be evaluated (unless I'm
>> missing something...)
>>
>>
>> On Friday, August 1, 2014 11:42:52 AM UTC-4, Simon Kornblith wrote:
>>>
>>> That looks like the output of :(esc(fn)), but you don't want to quote
>>> that, you want to evaluate it when generating the code, i.e. use
>>> $(esc(fn)) wherever you were previously using $fn
>>>
>>> On Friday, August 1, 2014 11:38:44 AM UTC-4, Abe Schneider wrote:
>>>>
>>>> That's correct, I'm generating code that keeps a pointer to that
>>>> function to call later on.
>>>>
>>>> If I do that, I have the type `esc(fn)` in the macro (this is what I
>>>> get when printing it out), and taking a dump of that argument gives:
>>>>
>>>> Expr
>>>>   head: Symbol call
>>>>   args: Array(Any,(2,))
>>>>     1: Symbol esc
>>>>     2: Symbol fn
>>>>   typ: Any
>>>>
>>>>
>>>> Does that mean instead of carrying around a function I will need to
>>>> carry around the Expr?
>>>>
>>>> Thanks!
>>>>
>>>> On Friday, August 1, 2014 11:17:50 AM UTC-4, Simon Kornblith wrote:
>>>>>
>>>>> Assuming you're generating code that calls fn, as opposed to trying
>>>>> to call it when generating code in the macro (usually a bad idea), you
>>>>> should use esc(fn) in place of fn
>>>>>
>>>>> On Friday, August 1, 2014 10:50:15 AM UTC-4, Abe Schneider wrote:
>>>>>>
>>>>>> I've come across a problem where I have macro to define  a grammar
>>>>>> (similar to how PEGParser currently works):
>>>>>>
>>>>>> @grammar foo begin
>>>>>>   rule[fn] = "some" + ("rule" | "test")
>>>>>> end
>>>>>>
>>>>>> where the `[fn]` next to the rule defines a function to call on the
>>>>>> results (in this case it's an expansion). The issue is that parsing the
>>>>>> Expr tree, `fn` is given as a Symbol (which makes sense).
>>>>>>
>>>>>> However, if I try to turn `fn` into a function I run into the
>>>>>> namespace issue I've had previously. If `fn` is defined in my module, it
>>>>>> works without problem. If it's defined in the code that imports the 
>>>>>> module,
>>>>>> it will not work because that function doesn't exist in the namespace of
>>>>>> the module.
>>>>>>
>>>>>> I'm guessing there isn't an easy solution to fix this problem, but I
>>>>>> thought I'd check to see if someone had an idea.
>>>>>>
>>>>>> Thanks!
>>>>>>
>>>>>>

Reply via email to