Re: Deleting Getters and Setters (was Re: Controlling DontEnum...)

2008-03-17 Thread Brendan Eich
On Mar 17, 2008, at 1:31 PM, Lars Hansen wrote:

 -Original Message-
 From: Kris Zyp [mailto:[EMAIL PROTECTED]

 obj = {get foo() { return 'hi' }}
 Object foo=hi
 obj.foo
 hi
 delete obj.foo
 true
 obj.foo = 'goodbye'
 goodbye
 obj.foo
 goodbye

 With ES4, obj.foo would still be returning hi at the end?
 That sounds nice, but is there no fear of compatibility
 issues with that?

 It's an interesting point.  The proposal is here:
 http://wiki.ecmascript.org/doku.php?id=proposals:getters_and_setters
 but does not mention deletion (either way).

 Brendan, opinions?

Clearly the proposal is incomplete :-/. SpiderMonkey originated three  
special forms for getters and setters, in 1999 (see rev 3.18 at  
http://bonsai.mozilla.org/cvsgraph.cgi?file=/mozilla/js/src/jsparse.c  
for one entry point into the change):

1. getter function x() { return ++i; };
2. o = {x getter: function () { return ++this.i; }};
3. o = {i: 0}; o.x getter= function () { return ++this.i; };

The first two were changed long ago, with Waldemar guiding things,  
into the ES4 syntax the RI supports today:

1'. function get x() { return ++i; };
2'. o = {get x() { return ++this.i; };

SpiderMonkey supports only form 2', while still maintaining support  
for the original 1-3.

Form 3 became

3': o = {i: 0}; o.__defineGetter__('x', function () { return + 
+this.i; });

About DontDelete: only the first form or its revised version, 1 or  
1', sets DontDelete among the bound getter's attributes, just as any  
non-eval'ed function binding created for a function definition makes  
a DontDelete property (eval makes delete-able bindings, for reasons I  
do not recall from ES1 days -- this is design flaw, btw, but I won't  
get into it here).

ES4 supports get and set methods in classes, also DontDelete or  
stronger (fixtures, so at least DontDelete).

For backward compatibility with SpiderMonkey, one might like 2' to  
make a getter that can be deleted. On the other hand, for higher  
integrity one might prefer that the object-initialiser-hosted  
syntactic form would make a DontDelete property.

The recent o = {var x: don't delete} proposal compatibly extends  
initialiser syntax to support user-created DontDelete properties, but  
whatever the outcome for that late-breaking micro-proposal, I do not  
think o = {var get x() { ... }}; is a good idea -- var and get next  
to each another do not convey DontDelete; the combo looks like a typo  
of some sort.

And would const get for a ReadOnly + DontDelete binding be wanted  
too? A getter without a setter in SpiderMonkey behaves like a const  
binding, in that assignments go into the bit bucket:

js o = {get x() ++this.i, i:0}
[object Object]
js o.x
1
js o.x
2
js o.x = 42
42
js o.x
3

A getter without a setter makes something const-like, in the sense of  
ES1-3's ReadOnly attribute and its semantics, but this kind of const  
lacks defensive consistency, to use a phrase defined in Mark  
Miller's thesis. We used to throw an error in SpiderMonkey when one  
sets a getter-only property, but we changed this to match the desired  
(for foolish consistency? ;-) ES1-3-like ReadOnly behavior. Users  
wanted only one kind of const.

A setter without a getter means property gets return undefined. We've  
always done this.

I hope this helps, even though it is about more than DontDelete.  
Given our history and the delete-ability of properties created in  
object initialisers in ES3, I favor reserving DontDelete getters and  
setters for the 1' special form: a variation on function definition  
syntax. So only

function get x() ++i;

or similar in a class (static or instance) would make a DontDelete  
binding, if not a fixture. My two cents,

/be
___
Es4-discuss mailing list
Es4-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es4-discuss


Re: Deleting Getters and Setters (was Re: Controlling DontEnum...)

2008-03-17 Thread Brendan Eich
On Mar 17, 2008, at 2:36 PM, Brendan Eich wrote:

 1. getter function x() { return ++i; };
 2. o = {x getter: function () { return ++this.i; }};
 3. o = {i: 0}; o.x getter= function () { return ++this.i; };

 The first two were changed long ago, with Waldemar guiding things,
 into the ES4 syntax the RI supports today:

 1'. function get x() { return ++i; };
 2'. o = {get x() { return ++this.i; };

 SpiderMonkey supports only form 2', while still maintaining support
 for the original 1-3.

 Form 3 became

 3': o = {i: 0}; o.__defineGetter__('x', function () { return +
 +this.i; });

Only in SpiderMonkey, I should have added -- the RI and of course ES4  
do not specify support for __define[GS]etter__.

/be

___
Es4-discuss mailing list
Es4-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es4-discuss


Re: Deleting Getters and Setters (was Re: Controlling DontEnum...)

2008-03-17 Thread Mike Shaver
On Mon, Mar 17, 2008 at 5:36 PM, Brendan Eich [EMAIL PROTECTED] wrote:
  For backward compatibility with SpiderMonkey, one might like 2' to
  make a getter that can be deleted.

That pattern is used in Firefox now (and perhaps elsewhere) to do lazy
initialization of expensive objects:

this.__defineGetter__(Debug, function() {
  var d = loadModule(debug.js);
  delete this.Debug;
  this.Debug = d;
  return d;
});

We could adapt, obviously, dunno if it's widely used on the web.

Mike
___
Es4-discuss mailing list
Es4-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es4-discuss


Re: Deleting Getters and Setters (was Re: Controlling DontEnum...)

2008-03-17 Thread Brendan Eich
On Mar 17, 2008, at 3:08 PM, Mike Shaver wrote:

 On Mon, Mar 17, 2008 at 5:36 PM, Brendan Eich [EMAIL PROTECTED]  
 wrote:
  For backward compatibility with SpiderMonkey, one might like 2' to
  make a getter that can be deleted.

 That pattern is used in Firefox now (and perhaps elsewhere) to do lazy
 initialization of expensive objects:

 this.__defineGetter__(Debug, function() {
   var d = loadModule(debug.js);
   delete this.Debug;
   this.Debug = d;
   return d;
 });

 We could adapt, obviously, dunno if it's widely used on the web.

With only SpiderMonkey supporting __defineGetter__, it's not widely  
used. The canonical JS memoization pattern, presented nicely here:

http://osteele.com/archives/2006/04/javascript-memoization

changes (shadows or replaces) a function-valued property, requiring  
callers to add pesky () to invoke the property explicitly. With  
getters and setters, this noise-problem can be avoided and (beyond  
noise reduction) old client code that wanted to get a property, not  
call a method, can be made to call a memoizing wrapper without  
requiring vast or infeasible (you don't own write access to the  
client code) search and replace work.

So getters and setters plus memoization patterns do summon  
__defineGetter__, in our experience.

/be

___
Es4-discuss mailing list
Es4-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es4-discuss


Re: Deleting Getters and Setters (was Re: Controlling DontEnum...)

2008-03-17 Thread Mike Shaver
On Mon, Mar 17, 2008 at 6:14 PM, Brendan Eich [EMAIL PROTECTED] wrote:
  With only SpiderMonkey supporting __defineGetter__, it's not widely
  used. The canonical JS memoization pattern, presented nicely here:

Yeah, I would expect that only properties of new objects are lazily
defined that way, using the 2' form from above.

Mike
___
Es4-discuss mailing list
Es4-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es4-discuss


Deleting Getters and Setters (was Re: Controlling DontEnum...)

2008-03-13 Thread Kris Zyp
 the fact; getters and setters defined by an object initializer
 or in a class are fixtures and hence not deletable.
Really, that doesn't create a compatibility problem? I realize getters and 
setters aren't in ES3, but this seems like ES4 would be making a significant 
departure in behavior from the majority of current browser implementations 
of the same getter/setter syntax used by ES4:
 obj = {get foo() { return 'hi' }}
Object foo=hi
 obj.foo
hi
 delete obj.foo
true
 obj.foo = 'goodbye'
goodbye
 obj.foo
goodbye

With ES4, obj.foo would still be returning hi at the end? That sounds 
nice, but is there no fear of compatibility issues with that?
Kris 

___
Es4-discuss mailing list
Es4-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es4-discuss