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/
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.