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> >>