On 2009-05-11, at 11:00EDT, Henry Minsky wrote:

On Mon, May 11, 2009 at 10:40 AM, P T Withington <[email protected]> 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.

Reply via email to