reformed with

# Yuh-Ruey Chen (19 years ago)

I've been looking at the reformed with proposal. It seems that using a let statement would be much easier than writing a reformed with statement. Compare:

with (obj.obj2: {a: int, b:Object, c:String, d:Array) { a = 10; var x = b; c = 'hi'; d.push(5.5); }

vs.

let (o = obj.obj2) { o.a = 10; var x = o.b; o.c = 'hi'; o.d.push(5.5); }

Brendan makes the argument that "migrating code should not require hand-expanding with to get precise types", but I would argue it would take just as much time (if not more) to look within the |with| block to see what properties need to be in the object literal and defining their types there, than to change the whole thing into a let statement. An example (sample code found with google code search):

with ( this.DOMTable )
{
    // Sets the toolbar direction. IE uses "styleFloat" and Gecko

uses "cssFloat". style.styleFloat = style.cssFloat = FCKLang.Dir == 'rtl' ? 'right' : 'left' ;

    cellPadding = 0 ;
    cellSpacing = 0 ;
    border = 0 ;
}

What's easier here? Changing the first line to |with(this.DOMTable: {style: Object, cellPadding: int, cellSpacing: int, border: int})|. Or changing the first line to |let(o = this.DOMTable)| and prefixing each appropriate property with |o.|. Note that in both cases, the author has to search through the |with| block to see which names are properties of DOMTable. It's bad either way. Moreso for reformed with IMO, since you also have to enter the types of each property.

There's also the argument of discoverability. Script authors are likely to learn the new let syntax since it can be used pretty much anywhere. The reformed with syntax, on the other hand, is a bit obscure. If a feature isn't that discoverable and there's an alternative feature that is and is just as good, I'd say drop the less discoverable feature.

Unless there's reformed with would result in noticeably better performance than the let equivalent, I'd say that |with| is a lost cause and reforming |with| is unnecessary.

# Lars T Hansen (19 years ago)

On Feb 4, 2007, at 1:31 PM, Yuh-Ruey Chen wrote:

I've been looking at the reformed with proposal. It seems that using a let statement would be much easier than writing a reformed with statement. Compare:

with (obj.obj2: {a: int, b:Object, c:String, d:Array) { a = 10; var x = b; c = 'hi'; d.push(5.5); }

vs.

let (o = obj.obj2) { o.a = 10; var x = o.b; o.c = 'hi'; o.d.push(5.5); }

Brendan makes the argument that "migrating code should not require hand-expanding with to get precise types", but I would argue it would take just as much time (if not more) to look within the |with|
block to see what properties need to be in the object literal and defining
their types there, than to change the whole thing into a let statement. An example (sample code found with google code search):

with ( this.DOMTable )
{
    // Sets the toolbar direction. IE uses "styleFloat" and Gecko

uses "cssFloat". style.styleFloat = style.cssFloat = FCKLang.Dir == 'rtl' ? 'right' : 'left' ;

    cellPadding = 0 ;
    cellSpacing = 0 ;
    border = 0 ;
}

What's easier here? Changing the first line to |with(this.DOMTable: {style: Object, cellPadding: int, cellSpacing: int, border: int})|. Or changing the first line to |let(o = this.DOMTable)| and prefixing each appropriate property with |o.|. Note that in both cases, the author
has to search through the |with| block to see which names are
properties of DOMTable. It's bad either way. Moreso for reformed with IMO, since you also have to enter the types of each property.

In practice your object would probably be of some named type, so you
would really do something like this:

 with (this.DOMTable : domtable_t) {
     ...
 }

Whether you define domtable_t yourself or the environment defines it
for you, having named types makes reformed with (as well as most uses of the
structural type system) much more pleasant.

If you need a subset view on the object (with access to other
variables outside the with having the same name as properties of the object) then I
agree with you, reformed with is cumbersome and most people would not use it,
unless the subset view could be named and used several places.

There's also the argument of discoverability. Script authors are
likely to learn the new let syntax since it can be used pretty much anywhere. The reformed with syntax, on the other hand, is a bit obscure. If a feature isn't that discoverable and there's an alternative feature
that is and is just as good, I'd say drop the less discoverable feature.

I agree. At the last committee meeting we discussed putting some
restrictions on classical "with" in strict mode (though the minutes do not record any conclusions). If we were to do that, however, the reformed with
might fare better.

Unless there's reformed with would result in noticeably better performance than the let equivalent,

Depends on the implementation and the exact context, but a loop inside a classical "with" could be a performance drain because all name
lookups would normally be searches by name, not by lexical address.

I'd say that |with| is a lost cause and reforming |with| is unnecessary.

I'd like to remove both kinds of "with" from the language. But I
lost that battle :-)

# Yuh-Ruey Chen (19 years ago)

Lars T Hansen wrote:

In practice your object would probably be of some named type, so you
would really do something like this:

 with (this.DOMTable : domtable_t) {
     ...
 }

Whether you define domtable_t yourself or the environment defines it
for you, having named types makes reformed with (as well as most uses of the
structural type system) much more pleasant.

Ah, thanks for the clarification. That does makes reformed with much more appealing. It would help if this was mentioned in the proposal in prose :)

Although if the environment doesn't define the types for host objects, or at least typeOf(host_object), it would be a large hassle... (typeOf is the function to get the type of an object, right?)

If you need a subset view on the object (with access to other
variables outside the with having the same name as properties of the object) then I
agree with you, reformed with is cumbersome and most people would not use it,
unless the subset view could be named and used several places.

Hmm...this should never be the case when revising an ES3 with statement.

There's also the argument of discoverability. Script authors are
likely to learn the new let syntax since it can be used pretty much anywhere. The reformed with syntax, on the other hand, is a bit obscure. If a feature isn't that discoverable and there's an alternative feature
that is and is just as good, I'd say drop the less discoverable feature.

I agree. At the last committee meeting we discussed putting some
restrictions on classical "with" in strict mode (though the minutes do not record any conclusions). If we were to do that, however, the reformed with
might fare better.

Do you mean that in strict mode, |with(o)| would be translated to |with(o:typeOf(o))| where typeOf(o) is determined at compile-time? If so, that would be nice.

Would there be any possibility of using something similar for standard mode? |with(o:typeOf(o))| would be incompatible with |with(o)| in standard mode, but it would be nice if there was a shortcut syntax for the former. In the above example, it would be nice to do |with(this.DOMTable:<something>)| instead of |with(this.DOMTable:typeOf(this.DOMTable)| (although on the other hand, I'm not a fan of adding a new syntactic construct for a possibly uncommonly used feature).

# Brendan Eich (19 years ago)

On Feb 4, 2007, at 6:45 PM, Yuh-Ruey Chen wrote:

Lars T Hansen wrote:

In practice your object would probably be of some named type, so you would really do something like this:

 with (this.DOMTable : domtable_t) {
     ...
 }

Whether you define domtable_t yourself or the environment defines it for you, having named types makes reformed with (as well as most uses of the structural type system) much more pleasant.

Ah, thanks for the clarification. That does makes reformed with much more appealing. It would help if this was mentioned in the proposal in prose :)

It's a given when you read the whole spec that structural types can
have names, via the 'type T = ...' declaration or the embedding host.
But yeah, could be repeated here.

Although if the environment doesn't define the types for host objects, or at least typeOf(host_object), it would be a large hassle... (typeOf is the function to get the type of an object, right?)

intrinsic::typeOf -- see developer.mozilla.org/es4/proposals meta_objects.html. Note well that this is an optional reflection
library, not guaranteed to be present in all ES4 implementations.

It may or may not be a hassle to name or repeat a structural type,
but if you are migrating old code or dealing with the persistence of
with, and you want to avoid severe deoptimization, reformed with
gives you a way at lower cost than rewriting to eliminate the with.

If you need a subset view on the object (with access to other variables outside the with having the same name as properties of the object) then I agree with you, reformed with is cumbersome and most people would not use it, unless the subset view could be named and used several places.

Hmm...this should never be the case when revising an ES3 with
statement.

Why not? I can recall ES3 (ES1, or JS1 would be more accurate) code
that thinks it knows what x means in a with body, but is sometimes
unpleasantly surprised. A subset view would help fix bugs while
migrating this old code.

I agree. At the last committee meeting we discussed putting some restrictions on classical "with" in strict mode (though the minutes do not
record any conclusions). If we were to do that, however, the reformed with might fare better.

Do you mean that in strict mode, |with(o)| would be translated to |with(o:typeOf(o))| where typeOf(o) is determined at compile-time? If so, that would be nice.

Not sure what Lars meant, but I saw something like that and found it
attractive at first. However, intrinsic::typeOf(o) is a runtime
expression, as well as a call to an optional library function.
Imputing it here in the case of with-under-strict-mode is unusual and
something TG1 members seem to be against, but we're still debating.

Would there be any possibility of using something similar for standard mode? |with(o:typeOf(o))| would be incompatible with |with(o)| in standard mode, but it would be nice if there was a shortcut syntax for the former. In the above example, it would be nice to do |with(this.DOMTable:<something>)| instead of |with(this.DOMTable:typeOf(this.DOMTable)| (although on the other
hand, I'm not a fan of adding a new syntactic construct for a possibly uncommonly used feature).

There's no reason for any of this given reformed with (http:// developer.mozilla.org/es4/proposals/reformed_with.html).

# P T Withington (19 years ago)

On 2007-02-05, at 20:06 EST, Brendan Eich wrote:

Do you mean that in strict mode, |with(o)| would be translated to |with(o:typeOf(o))| where typeOf(o) is determined at compile-time? If so, that would be nice.

Not sure what Lars meant, but I saw something like that and found
it attractive at first. However, intrinsic::typeOf(o) is a runtime
expression, as well as a call to an optional library function.
Imputing it here in the case of with-under-strict-mode is unusual
and something TG1 members seem to be against, but we're still
debating.

If I have:

var o:T = ...;

(or the type of o is already declared in some other fashion in the
lexical context), do I still have to say:

with (o:T) ...

?

# Brendan Eich (19 years ago)

On Feb 5, 2007, at 5:28 PM, P T Withington wrote:

On 2007-02-05, at 20:06 EST, Brendan Eich wrote:

Do you mean that in strict mode, |with(o)| would be translated to |with(o:typeOf(o))| where typeOf(o) is determined at compile- time? If so, that would be nice.

Not sure what Lars meant, but I saw something like that and found
it attractive at first. However, intrinsic::typeOf(o) is a runtime
expression, as well as a call to an optional library function.
Imputing it here in the case of with-under-strict-mode is unusual
and something TG1 members seem to be against, but we're still
debating.

If I have:

var o:T = ...;

(or the type of o is already declared in some other fashion in the
lexical context), do I still have to say:

with (o:T) ...

The two don't mean the same thing. 'var o:T = ...' first means
convert '...' to T, then constrain any further values to be
compatible with T. On the other hand, from the [reformed with] proposal:

For example, to use fields f1 and f2 of the given types from an
object denoted by obj:

with (obj : {f1: T1, f2: T2}) { // f1 and f2 are unambiguous here ... }

It is required that obj have fields of the given names and exact
types. The actual field obj.f1 must not be of a subtype of T1, e.g.,
because assignments to f1 in the with body could break the narrower
type constraint on obj.f1. And obj.f1 must not be of a supertype of
T1, because it could hold a value that is not of that subtype.

# Yuh-Ruey Chen (19 years ago)

Brendan Eich wrote:

On Feb 4, 2007, at 6:45 PM, Yuh-Ruey Chen wrote:

Although if the environment doesn't define the types for host objects, or at least typeOf(host_object), it would be a large hassle... (typeOf is the function to get the type of an object, right?)

intrinsic::typeOf -- see developer.mozilla.org/es4/proposals meta_objects.html. Note well that this is an optional reflection
library, not guaranteed to be present in all ES4 implementations.

It may or may not be a hassle to name or repeat a structural type,
but if you are migrating old code or dealing with the persistence of
with, and you want to avoid severe deoptimization, reformed with
gives you a way at lower cost than rewriting to eliminate the with.

If you need a subset view on the object (with access to other variables outside the with having the same name as properties of the object) then I agree with you, reformed with is cumbersome and most people would not use it, unless the subset view could be named and used several places.

Hmm...this should never be the case when revising an ES3 with
statement.

Why not? I can recall ES3 (ES1, or JS1 would be more accurate) code
that thinks it knows what x means in a with body, but is sometimes
unpleasantly surprised. A subset view would help fix bugs while
migrating this old code.

I wasn't disagreeing that a subset view would be nice. I meant that since they aren't supported in ES3, it should never be the case that such a feature would be useful when migrating correct ES3 with code.

I agree. At the last committee meeting we discussed putting some restrictions on classical "with" in strict mode (though the minutes do not
record any conclusions). If we were to do that, however, the reformed with might fare better.

Do you mean that in strict mode, |with(o)| would be translated to |with(o:typeOf(o))| where typeOf(o) is determined at compile-time? If so, that would be nice.

Not sure what Lars meant, but I saw something like that and found it
attractive at first. However, intrinsic::typeOf(o) is a runtime
expression, as well as a call to an optional library function.
Imputing it here in the case of with-under-strict-mode is unusual and
something TG1 members seem to be against, but we're still debating.

Well, intrinsic::typeOf doesn't have to be used - I meant what Withington said. I'll leave it at that.

Would there be any possibility of using something similar for standard mode? |with(o:typeOf(o))| would be incompatible with |with(o)| in standard mode, but it would be nice if there was a shortcut syntax for the former. In the above example, it would be nice to do |with(this.DOMTable:<something>)| instead of |with(this.DOMTable:typeOf(this.DOMTable)| (although on the other
hand, I'm not a fan of adding a new syntactic construct for a possibly uncommonly used feature).

There's no reason for any of this given reformed with (http:// developer.mozilla.org/es4/proposals/reformed_with.html).

/be

That would require knowing the structural type of this.DOMTable. Oh well, calling typeOf(this.DOMTable) would be more expensive than a persistent reference to the structural type, so I guess it's a necessary inconvenience.

# Brendan Eich (19 years ago)

On Feb 5, 2007, at 7:44 PM, Yuh-Ruey Chen wrote:

That would require knowing the structural type of this.DOMTable. Oh well, calling typeOf(this.DOMTable) would be more expensive than a persistent reference to the structural type, so I guess it's a
necessary inconvenience.

Why do you assume that this.DOMTable would not have a nominal type?

# Yuh-Ruey Chen (19 years ago)

Because of a certain browser vendor out there that's rather slow with DOM updates. ES4 compatibility and good DOM ES4 bindings are different things.