[Laszlo-dev] Constraint ordering and initial values [Was: For Review: Change 20090511-bargull-Yq7 Summary: constraint returns NaN in resizestatemin]
P T Withington
ptw at pobox.com
Tue May 12 06:54:36 PDT 2009
On 2009-05-11, at 11:00EDT, Henry Minsky wrote:
> On Mon, May 11, 2009 at 10:40 AM, P T Withington <ptw at pobox.com>
> wrote:
>
>> I'm concerned that my r13731 change that sets the initial value of
>> constrained attributes to `undefined` rather than `null` may have
>> more
>> fallout. This change by André fixes one instance, but there could
>> be many
>> more lurking.
>>
>> The issue: Constraints run in random order. Constraints that
>> depend on
>> attributes that are themselves constrained may reference those
>> attributes
>> when they are still undefined. When used in a numeric expression,
>> undefined
>> coerces to NaN. NaN's are "sticky", hence may pollute other
>> attributes, and
>> the constraint system may never recover.
>
> Yeah, I think that not only will we find that some existing code has
> gotten
> broken, but people will also get into trouble in the future with NaNs.
> Maybe we should have a way to ensure that all attributes have a
> defined
> default value?
It's just finding an initial value that will work as the constraint
system starts up. Since the order of constraints is indeterminite,
some constraints may depend on other constrained values that have not
yet had their constraint computed. So, where do you start?
Ideally, the runtime would know the actual type of each attribute and
be able to set the constrained attributes initially to some innocuous
value. (e.g., 0 for numeric, empty string for string, etc.) Barring
that, we need to at least go back to using `null` as the initial
default, since `undefined` when used in a numeric expression will
coerce to `NaN` and pollute the result (and any dependents).
>> r13731 was an attempt to make events fire less often by not having
>> them
>> fire when a constraint updated an attribute to the value it already
>> had. To
>> do this I needed a sentinel value that indicated that the attribute
>> had
>> _never_ been updated (to distinguish the case where a constraint
>> was setting
>> the attribute to `null`). `undefined` seemed to fit that bill, but
>> clearly
>> it has additional consequences, as seen in LPP-8088.
>>
>> I'm looking for a way to achieve the optimization of 13731 without
>> the NaN
>> hazard. I think this means that we have to revert to storing
>> `null` as the
>> initial value of constrained attributes (even better would be to
>> store some
>> type-correct equivalent of null). And we'll have to have some sort
>> of a
>> flag that says you always send the event the first time around
>> (e.g., when
>> called from __LZapplyArgs).
>
> That sounds like a reasonable approach; the optimization holds in
> normal
> use, but when the setter gets run the first time it always fires.
In fact, you don't even need the 'first time' flag, because if someone
depended on you and used your initial value, and your constraint set
your actual value to a value that is `===` your initial value, then
your dependents will already be correct.
I have a patch I am sending you to review that simply reverts to using
`null` as the initial value for constrained attributes. It seems to
work.
More information about the Laszlo-dev
mailing list