reformed with

classic Classic list List threaded Threaded
9 messages Options
Reply | Threaded
Open this post in threaded view
|

reformed with

Yuh-Ruey Chen
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.

-Yuh-Ruey

Reply | Threaded
Open this post in threaded view
|

Re: reformed with

Lars T Hansen-2
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 :-)

--lars




Reply | Threaded
Open this post in threaded view
|

Re: reformed with

Yuh-Ruey Chen
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).

-Yuh-Ruey

Reply | Threaded
Open this post in threaded view
|

Re: reformed with

Brendan Eich-2
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 http://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).

/be


Reply | Threaded
Open this post in threaded view
|

Re: reformed with

P T Withington
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) ...

?

Reply | Threaded
Open this post in threaded view
|

Re: reformed with

Brendan Eich-2
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.

/be



Reply | Threaded
Open this post in threaded view
|

Re: reformed with

Yuh-Ruey Chen
In reply to this post by Brendan Eich-2
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 http://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.

-Yuh-Ruey

Reply | Threaded
Open this post in threaded view
|

Re: reformed with

Brendan Eich-2
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?

/be


Reply | Threaded
Open this post in threaded view
|

Re: reformed with

Yuh-Ruey Chen
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.

-Yuh-Ruey

Brendan Eich wrote:

> 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?
>
> /be
>
>
>