[Laszlo-dev] Constraint function generator

Donald Anderson dda at ddanderson.com
Fri Feb 22 10:13:48 PST 2008


I'm deeper into this today and trying to figure out how it all ties  
together.
It's fine for the compiler to spit out these functions that reference  
each other,
but someone needs to invoke a dependency to begin with.
I'm assuming that there will be something in the tag compiler that
emits an explicit call, something like:

     X = $lzc$foo_dependencies();

in the right spot in the generated code?  The calculation of what to  
call cannot happen at
runtime (like the rp.dependencies.call(this) that is in LzNode.lzx), I  
don't see any way
to lookup a function by variable name and then call it in the  
reflection API.
[Aside: it appears the flex reflection API is different then ES4  
proposal].

Henry, is this something that you'll do, once I have this in hand?
I'm wondering about logistics of the change, since it involves sc,  
tagcompiler
and runtime.  I could hand off the sc changes to you, or you could hand
off tagcompiler changes to me.  Or I could do a phase-one-commit:
keeping current implementation in place with a new API for the
new stuff (it's not that onerous).

Also, in LPP-5452, Tucker wrote that the first two args (who,  
self,...) to the current
dependencies function may not be needed - I agree with 'self' as it  
can be obtained
from 'this' - and if there is no this, then self is also undefined.   
But as for 'who',
I see a complex dependencies function in LaszloView.lzs:  
setAttributeRelative.dependencies
that uses 'who'.

Looking through sources, there are a few dozen spots to change in  
runtime on the 'flag day':

/lps/components/extensions/views/richinputtext.lzx
./test/constraints.lzx
./test/lfc/testmethoddepend.lzx
./WEB-INF/lps/lfc/core/LzNode.lzs
./WEB-INF/lps/lfc/data/LzDataElement.lzs
./WEB-INF/lps/lfc/data/LzDataNode.lzs
./WEB-INF/lps/lfc/data/LzDatapointer.lzs
./WEB-INF/lps/lfc/data/LzReplicationManager.lzs
./WEB-INF/lps/lfc/views/LaszloView.lzs
./WEB-INF/lps/lfc/views/LzInputText.lzs
./WEB-INF/lps/lfc/views/LzText.lzs

Most would be mechanical, but a few, like setAttributeRelative will  
need special care.

- Don

On Feb 20, 2008, at 1:07 PM, P T Withington wrote:

> You'll want to follow closely http://jira.openlaszlo.org/jira/browse/LPP-5452
>
> However we go, there is a flag day to do this when the compiler and  
> the LFC must be changed in sync.  IWBN to fix everything at once.
>
> The pattern I have been using is `$lzc$` as a prefix and  
> `_<qualifier>` as a suffix.  So, for instance, the setter method for  
> `foo` is called `$lzc$foo_setter`, and I would make the dependencies  
> method for `Fcn` be `$lzc$Fcn_depenencies`.
>
> [It would be a groovy optimization to have the unparser compress all  
> the $lzc$ names in production mode.]
>
> On 2008-02-20, at 12:34 EST, Donald Anderson wrote:
>
>> Did we come up with a decision for the new dependency function  
>> naming?
>> Since there are recursive dependency computation, I'll need to know  
>> how to call
>> (and name) the new functions.  At the moment (using the old naming  
>> style), the expression
>>    a.b.c + this.something.Fcn(1)
>>
>> Returns this dependency array:
>>   [a.b,  
>> "c"].concat(this.something.Fcn.hasOwnProperty("dependencies") ?  
>> this.something.Fcn.dependencies(this, this.something, 1) : [])
>>
>> If we use $lzsc$dep$Fcn for function Fcn, then this becomes:
>>   [a.b, "c"].concat(this.something.hasOwnProperty("$lzsc$dep 
>> $Fcn") ? this.something.$lzsc$dep$Fcn(this, this.something, 1) : [])
>>
>> I think we discussed this, not sure what was decided.
>>
>> - Don
>>
>> On Feb 20, 2008, at 5:05 AM, P T Withington wrote:
>>
>>> On 2008-02-19, at 19:00 EST, Donald Anderson wrote:
>>>
>>>> Henry,
>>>>
>>>> I have the constraint function generator mostly ready.
>>>>
>>>> First question - do we need an option to compute meta references?
>>>> That's apparently a compile time option, but I don't see when  
>>>> it's turned on.
>>>
>>> That was a failed experiment.  Correct, but determined to be too  
>>> slow.  For now, we are just keeping the code as a reference  
>>> implementation, turned off.  It is trying to solve the problem  
>>> that if a constraint says `a.b.c`, we only listen for `c` changing  
>>> in `a.b`; if `b` changes in `a`, we won't notice.
>>>
>>>> In my current version, I am accepting as arguments 1) the name of  
>>>> the original function,
>>>> and 2) the source for the function, for the moment I expect the  
>>>> source
>>>> to look just like what you are now generating.
>>>>
>>>> I am returning the source of a function with the name  
>>>> XXX_dependencies.
>>>
>>> I agree with you and Henry that it will be more useful going  
>>> forward if you accept an arbitrary expression (as a string) and  
>>> return the expression that computes the dependencies for that  
>>> (also as a string).  Thus, to retrofit your code to the current  
>>> "pattern" you would analyze the expression that is the second  
>>> argument to setAttribute in the current constraint functions.
>>>
>>> Are you doing this in RingDing?  I think that would be the best  
>>> place, since then we can test against the known-working test cases.
>>>
>>>> For example, input source is this: (culled from where this string  
>>>> is made in NodeModel.java):
>>>>
>>>> ===
>>>> function $base$2Fbasefocusview$2Elzx_282_41_x_always () {
>>>> #pragma 'constraintFunction'
>>>>
>>>> #pragma 'withThis'
>>>> this.setAttribute("x",
>>>> #beginAttribute
>>>>
>>>> #file base/basefocusview.lzx
>>>> #line 282
>>>>                                      -classroot.offset
>>>> #endAttribute
>>>> )}
>>>> ===
>>>>
>>>> Output source is currently:
>>>>
>>>> ===
>>>> /* -*- file: Compiler.substitute#-1.1 -*- */
>>>> function $base$2Fbasefocusview$2Elzx_282_41_x_always_dependencies  
>>>> () {
>>>> #pragma "warnUndefinedReferences=false";
>>>> with (this) {
>>>> return [classroot, "offset"]
>>>> }}
>>>> ===
>>>>
>>>> I'm thinking instead I could accept simply '-classroot.offset'
>>>> and return just the text of the statements:
>>>> with (this) {
>>>> return [classroot, "offset"]
>>>> }
>>>
>>> I would leave out the `with (this)` and have that be an implicit  
>>> burden on the callee.  (Especially because that is implicit in JS2  
>>> method bodies).
>>>
>>>> Then you could name the function whatever you want or
>>>> use it as a function expression.  Or I could return just the
>>>> array (as an expression) like '[classroot, "offset"]' .  It depends
>>>> on how you plan to use it,  vs. how much of the details you need  
>>>> to know.
>>>>
>>>> - Don
>>>>
>>>> --
>>>>
>>>> Don Anderson
>>>> Java/C/C++, Berkeley DB, systems consultant
>>>>
>>>> voice: 617-547-7881
>>>> email: dda at ddanderson.com
>>>> www: http://www.ddanderson.com
>>>>
>>>>
>>>>
>>>>
>>>
>>
>>
>> --
>>
>> Don Anderson
>> Java/C/C++, Berkeley DB, systems consultant
>>
>> voice: 617-547-7881
>> email: dda at ddanderson.com
>> www: http://www.ddanderson.com
>>
>>
>>
>>
>


--

Don Anderson
Java/C/C++, Berkeley DB, systems consultant

voice: 617-547-7881
email: dda at ddanderson.com
www: http://www.ddanderson.com






More information about the Laszlo-dev mailing list