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: [EMAIL PROTECTED]
www: http://www.ddanderson.com







--

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

Reply via email to