cocoon-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Daniel Fagerstrom <dani...@nada.kth.se>
Subject Variable Asignment in JXTG (was: xml languages)
Date Sun, 23 Jan 2005 15:42:51 GMT
Leszek Gawron wrote:
> Daniel Fagerstrom wrote: 
>> BURGHARD √Čric wrote:
<snip/>
>>> Variable nature and scope (kind of non-mutable that you can overwrite 
>>> ?),
>>> but someone could tell me this a feature :-). Perhaps i've miss 
>>> something,
>>> but look what i need to do to retrieve a value incremented inside a 
>>> forEach
>>> loop:
>>>
>>> <jx:set var="globalvars" value="${java.util.HashMap(5)}"/>
>>> <jx:set var="dummy" value="${globalvars.put('a_count', 0)}"/>
>>> ...
>>> <jx:set var="a_count" value="${globalvars.a_count}"/>
>>> <jx:forEach begin="1" end="3" varStatus="i">
>>>    ...
>>>    <jx:if test="#{$node/@path != ''}">
>>>       ...
>>>       <jx:set var="a_count" value="${a_count+1}"/>
>>>       <jx:set var="dummy" value="${globalvars.put('a_count', 
>>> a_count)}"/>
>>>   </jx:if>
>>> </jx:forEach>
>>>
>>> <jx:out>this is my count: ${globalvars.a_count}</jx:out>
>>>
>>> It would be easiest (and efficient) to do
>>> <jx:set var="a_count" value="0"/>
>>> <jx:forEach begin="1" end="3" varStatus="i">
>>>    ...
>>>    <jx:if test="#{$node/@path != ''}">
>>>       ...
>>>       <jx:set var="a_count" value="${a_count+1}"/>
>>> </jx:forEach>
>>>
>>> <jx:out>this is my count: ${a_count}</jx:out>
>>>
>>> the fact that "set" make always a "new define" is quite annoying at 
>>> first
>>> glance (functional programming ?).
>>
>> The expression context is implemented as a stack of maps and the put 
>> instruction on the context is a put on the top map. ForEach is 
>> implemented in such way that the loop is performed in a local map that 
>> is pushed on stack before the loop and poped afterwards. The set 
>> instruction will do a put on the top map and will disapear afterwards 
>> because of that.
>>
>> Ok, that explains the behaviour, the question is what we should do 
>> about the, admitingly, weird behaviour.
>>
>> One possibilty would be to decide that we want JXTG to be more like a 
>> functional language. In that case we should deprecate jx:set and 
>> introduce a jx:let instead that just gives a local name for an 
>> expression and that gives an exception if you try to set the 
>> "variable" to a new value. I think I would prefer this behaviour as I 
>> would prefer having a template language without side effects.
> 
> This proposal does not solve the use case provided.

Could possibly be done with:

<jx:forEach items="#{$node[@path]}">
...

But it wasn't clear to me what the use case does.

> I also had several 
> cases where I wanted the numbering to be consistent across several 
> forEach calls and also had to implement hacks.

Can possibly be done by adding count($node[@path]) to the counter.

I'm certain that you can find cases that not are solved with this. The 
question is how much of a programming language we want our template 
language to be, and my opinion is that we should contain as little 
"programming" constructs as possible while still being usable as a view. 
We must of course discuss where we should draw the line. But I would go 
for less. WDOT?

>> Another possibility is to let set asign the value to the first 
>> variable binding with the same name that it finds when the stack is 
>> searched, instead of creating a new binding at the top of the stack if 
>> the name doesn't exist on the top of the stack. If we go for this we 
>> need two constructions one that declare and possibly gives an intial 
>> value to a variable in the current context and one that binds the 
>> uppermost occurance of the name, a jx:declare and a jx:set e.g.
>>
>> Also we would need to change the API and behaviour of 
>> ExpressionContext so that we both have a declare and a set method. 
>> This should probably be done anyway.
>>
>> WDYT?
>>
>> /Daniel
>>
> I prefer the second solution. The only thing to make the use case work 
> is the ability to set the variable without implicit declaration.
> 
> One more question: should jx:set automatically declare if there is no 
> previous declaration? I think yes.
> 
> When we reach an agreement I can implement it as it looks quite 
> straightforward.

Thinking a little bit more about it, we can't change the current 
behavoiur of jx:set in the indicated dirresction, it will break peoples 
templates and we don't want that.

I suggest that (given that we decide to go the "assignment" way, that we 
introduce two new constructions: jx:define (or declare, let, variable 
etc) and jx:assign. jx:define introduces a new variable in the current 
context and give it an initial value, it is an error to use jx:define 
for the same variable two times in the same context. jx:asign assigns 
the value of a previous declared variable and it is an error to assign 
an undefined variable. I prefer to not have any implicit declaration of 
undefined variable from jx:assign.

 From an implementation POV the ExpressionContext must be extended with 
new methods for assignment and declaration of variables as the put 
instruction supports the current jx:set behaviour.

/Daniel

Mime
View raw message