On Fri, 2016-09-30 at 00:53, Marius Millea <mariusmil...@gmail.com> 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.

I think one of the problems with macro-evals is that (at least the
advanced user) will expect a macro to do a pure syntax transform,
independent of the state of the runtime.  Anything else would be
surprising.  Maybe macros which call `eval` should have names with an
`!` to advertise their non-standard-ness?

> 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