Would eval'ing the type inside the macro work? This shows [:x, :y]

macro type_fields(typ)
    fields = fieldnames(eval(typ))
    @show fields
end

type A
    x
    y
end

@type_fields A

You can use that to generate the right expansion for that type.

On Thursday, September 29, 2016 at 6:53:01 PM UTC-4, Marius Millea wrote:
>
> I think there's at least once scenario where eval-in-a-macro is not a 
> mistake, mainly when you want to generate some code that depends on 1) some 
> passed in expression and 2) something which can only be known at runtime. 
> Here's my example:
>
> The macro (@self) which I'm writing takes a type name and a function 
> definition, and gives the function a "self" argument of that type and 
> rewrites all occurrences of the type's fields, X, to self.X. Effectively it 
> takes this:
>
> type MyType
>     x
> end
>
> @self MyType function inc()
>     x += 1
> end
>
> and spits out:
>
> function inc(self::MyType)
>     self.x += 1
> end
>
> (if this sounds familiar, its because I've discussed it here before, which 
> spun off this <https://github.com/fcard/SelfFunctions.jl>, that I'm 
> currently working on tweaking)
>
>
> To do this my code needs to modify the function expression, but this 
> modification depends on fieldnames(MyType), which can *only* be known at 
> runtime. Hence what I'm doing is, 
>
> macro self(typ,func)
>
>     function modify_func(fieldnames)
>         # in here I have access to `func` expression *and* 
> `fieldnames(typ)` as evaluated at runtime
>         # return modified func expression
>     end
>
>     quote
>         $(esc(:eval))($modify_func(fieldnames($(esc(typ)))))
>     end 
>  
> end
>
> I don't see a cleaner way of doing this, but I'm happy to take 
> suggestions. 
>
> (Btw: my original question was w.r.t. that last "eval', which makes it so 
> that currently this doesn't work on function closures. I'm still processing 
> the several suggestions in this context...)
>
>
> On Tuesday, September 27, 2016 at 5:12:44 PM UTC+2, Steven G. Johnson 
> wrote:
>>
>> On Tuesday, September 27, 2016 at 10:27:59 AM UTC-4, Stefan Karpinski 
>> wrote:
>>>
>>> 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:
>>>
>>
>> Right; using "eval" in a function is almost always a mistake, an 
>> indication that you should really be using a higher-order function. 
>> <https://en.wikipedia.org/wiki/Higher-order_function>
>>
>

Reply via email to