[Laszlo-dev] Constraint function generator
P T Withington
ptw at openlaszlo.org
Fri Feb 22 11:15:12 PST 2008
On 2008-02-22, at 13:13 EST, Donald Anderson wrote:
> 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].
If you take my changes from trunk, you will see how this will work.
In trunk, constraints come across as an LzConstraintExpr in the attrs
list of a user class. Right now this has only 1 slot, the name of the
'binder method' to call when dependencies change, and it gets the
dependencies from `.dependencies` on that, per usual.
Once your change is in, I can re-work the tag compiler to put the
dependency computing method in a second slot of LzConstraintExpr and
fix up applyArgs to work with that. (I'd like to do this in trunk, if
possible, which is why I'm hoping you'll put your changes there.)
In fact, if you make your analyzer work on an arbitrary code fragment,
and return just the body of the constraint computation, you don't need
to worry about naming at all -- I'll make up the names in the tag
compiler when I attach the binder and dependency methods to the class
and insert the LzConstraintExpr on the attrs list.
This (working in code fragments) is really the better approach because
_eventually_ all the dependency computations can be hoisted into the
body of a custom applyArgs method for each particular class and not
have to be attached as separate methods at all.
> 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'.
Ok, we gotta keep `who`. Now I know why.
We can keep self for now too, but while you are in there, you should
fix up the calls to dependency methods to pass `this` too. That
should ease transition, and will also make the broken methods that
believe `this` to be correct start working (I wonder what fixing
_that_ will break? :P).
> 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
More information about the Laszlo-dev
mailing list