Re: weird macro params issue
Attila Szegedi <[email protected]>
| Newsgroups | gmane.comp.web.freemarker.user |
|---|---|
| Message-ID | <[email protected]> |
On 2008.05.21., at 22:01, Jonathan Revusky wrote:
>> <#macro m3 d b=c[a] a=d c={"3":"4"}>
>
> I'm looking at this and getting confused. Okay, a human looks at this
> and untangles it as follows: if d is "3" and and a's default value is
> d, then a is "3" as well and c[a] is c["3"] which is "4".
>
> Okay, fine. But this is constructed so that nothing circular is going
> on.
What I did in 2.3 code would of course indicate a circular dependency
and fail on it.
> You could throw a monkey wrench in the works by putting in a
> circular thing, like:
>
> <#macro m3 d b=c[a] a=d c={"3" : b}>
>
> That would seem to lead you into an infinite recursive loop, of
> course. It also has me wondering offhand if you could construct
> examples that evaluated differently depending on the order, which
> incomplete expression you started with first.
The 2.3 stuff I wrote evaluates parameters in the order they are
listed in macro definition, not invocation (and does another pass
until either all params got resolved, or a pass failed to resolve any
further variable), so it is fully deterministic and doesn't depend on
order of expressions in the invocation.
> (I honestly don't know.)
> But, you know, when presented this usage pattern my initial reaction
> was just that it wasn't worth supporting, though I didn't think about
> it all that much. But just to say, basically, that b, a, and c have to
> evaluate in the enclosing scope and not be referring to one another,
> which seems like it could get rather hairy, and also, allows people to
> write code like this unit test example that, to me, just looks too
> tricky, excessively clever in an 'emits a bad smell' sort of way.
It is horrible, but it's horrible on purpose. It's a test case :-)
As for people wanting to do this, well, we had the guy who started
this thread who was doing it, and now it also turned out that the
"fmdoc" project announced here few days ago also relies on it. I'm
not 100% sure either whether I personally like this or not, but it
seems like people already rely on it's current, partially working, not
really deterministic manifestation. I was reluctant to do this based
on a single user reporting it, but now we have 2, and one of them
("fmdoc") is actually a quite nice project (FreeMarker macro library
documenting tool written in FreeMarker :-) ) that looks like it was
written by people who know what they're doing, so I thought we could
implement this in a documented, deterministic manner then.
> Well, this is arguably correct, if we say that the default b=c[a] has
> to evaluate in the enclosing scope.
That's the crux of the issue here -- if they have to evaluate in the
enclosing scope, then this feature (defaults containing a reference to
another parameter) can't be implemented at all. I believe this usage
already does always fail in 2.4. That's why I proposed that
ParameterList have an "applyToScope" method that'd define all
parameters into the scope, and also resolving defaults against it.
> Well, hold on. Established languages that have default parameters,
> like Python, say. Does Python let you do this? I have to check.
> Somehow, my sense of this is that this is not something that Guido
> would care for.
:-)
> Larry Wall, OTOH, loves weird stuff like this.
Double :-) Let me know what you found out.
> Well, I'm not married to the current implementation. But to tell the
> truth, I'm looking at this pragmatically and just thinking it's likely
> better just to disallow the whole coding pattern and just say that
> when it throws the exception in the unit test case above, it's
> behaving correctly because c is not in fact defind at that exact point
> in the code, and anybody who relied on this in earlier versions was
> relying on buggy behavior. now, I grant, it's not that person's fault
> because the behavior was never really fully specified.
>
> So, I mean, I'm not married to the current implementation just because
> I wrote or anything, but I would be very reluctant to tear it apart
> and redo it just to support this coding pattern.
I'm not sure it's so much a matter of tearing it apart; it's more of a
minor surgical intervention. And you'd need to do some parts of it
anyway -- i.e. add fillInDefaults() behavior to everything invoked
through UnifiedCall (or a call expression), since various
TemplateModels that take arguments can have defaults defined on them
via Java annotations.
Attila.
-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/