Re: ES4 draft: Object

2008-05-15 Thread Garrett Smith
That sore thumb propertyIsEnumerable.

propertyIsEnumerable, as a setter, sets the DontEnum flag for the
object's own property. A value of 'false' makes the prop not show up
in - for in.
propertyIsEnumerable, as a getter, gets the value of the negation of
the DontEnum flag, and does not check the prototype chain. Has nothing
to do with whether or not the object shows up in - for in.

The addition adds a non-orthogonal aspect, apparently to add some
needed functionality.

This unituitive behavior is especially problematic to amateur, or
unskilled developers. The following code example from google
demonstrates this to be true:

http://doctype.googlecode.com/svn/trunk/goog/base.js

if (Object.prototype.propertyIsEnumerable) {
  /**
   * Safe way to test whether a property is enumarable.  It allows testing
   * for enumarable on objects where 'propertyIsEnumerable' is overridden or
   * does not exist (like DOM nodes in IE).
   * @param {Object} object The object to test if the property is enumerable.
   * @param {string} propName The property name to check for.
   * @return {boolean} True if the property is enumarable.
   * @private
   */
  goog.propertyIsEnumerable_ = function(object, propName) {
return Object.prototype.propertyIsEnumerable.call(object, propName);
  };
} else {
  /**
   * Safe way to test whether a property is enumarable.  It allows testing
   * for enumarable on objects where 'propertyIsEnumerable' is overridden or
   * does not exist (like DOM nodes in IE).
   * @param {Object} object The object to test if the property is enumerable.
   * @param {string} propName The property name to check for.
   * @return {boolean} True if the property is enumarable.
   * @private
   */
  goog.propertyIsEnumerable_ = function(object, propName) {

// KJS in Safari 2 is not ECMAScript compatible and lacks crucial methods
// such as propertyIsEnumerable.  We therefore use a workaround.
// Does anyone know a more efficient work around?

/ BROKEN: this approach checks the prototype chain with - if(propName in object)
// (gsmith)
if (propName in object) {
  for (var key in object) {
if (key == propName) {
  return true;
}
  }
}
return false;
  };
}

Because we can see that the author appears to have made the assumption
that propertyIsEnumerable would check the prototype chain. This is a
perfectly natural assumption.

What is more confusing is that with the new proposal:

function X(){}
X.prototype = { p : true; };

var x = new x;
x.propertyIsEnumerable('p'); // false, p is in the [[Prototype]]
for(var prop in x)
  alert(prop); // alerts 'p'

Garrett

2008/3/17 Lars Hansen [EMAIL PROTECTED]:
 Draft 3 of the spec for the Object class.  Changelog near the beginning.
 (Notably this version includes draft code for __createProperty__.)

 --lars



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


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


Re: Controlling DontEnum (was: ES4 draft: Object)

2008-04-20 Thread P T Withington
[Coming late to the party]

On 2008-03-13, at 12:47 EDT, Lars Hansen wrote:
  function __createProperty__(name:EnumerableId,
  dontEnum:boolean=false,
  dontDelete:boolean=false,
  readOnly:boolean=false): void

If I did my math right there are 8 possible flag combinations, but  
only 6 make sense.  Why not a single parameter that is a member of an  
enumeration?  Maybe the enumeration values could be named mnemonically  
to match the ES4 declarative syntax?



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


RE: ES4 draft: Object initializers

2008-04-08 Thread Lars Hansen
 -Original Message-
 From: [EMAIL PROTECTED] 
 [mailto:[EMAIL PROTECTED] On Behalf Of Lars Hansen
 Sent: 7. april 2008 16:20
 To: es4-discuss@mozilla.org
 Subject: RE: ES4 draft: Object initializers
 
 Here is the second draft, which incorporates most things 
 discussed so far.  Changelog near the beginning, with an OPEN 
 ISSUES section.

One facility that was introduced in this draft copies the
type tags of 'const' and 'var' attributed properties into
the type of the object, for ease of use.  As a consequence,
this test is true:

  { const x: foo } is { x: string }

I am going to remove that facility again because it violates
the explicit is better than implicit principle.  IMO the
programmer should state her intent:

  { const x: foo } : { x: string }

Type definitions help make this somewhat less wordy.  And with
or without the type annotation x would still be a read-only
fixture, as desired, but the type of the x property would
be *, not string.

(It's easy to say that when the literals are simple then the
types are obvious, but once they involve more complicated
expressions I'm guessing the gains are illusory.)

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


RE: ES4 draft: Object initializers

2008-04-08 Thread Lars Hansen
 -Original Message-
 From: Mark S. Miller [mailto:[EMAIL PROTECTED] 
 Sent: 8. april 2008 15:38
 To: Lars Hansen
 Cc: es4-discuss@mozilla.org
 Subject: Re: ES4 draft: Object initializers
 
 On Tue, Apr 8, 2008 at 12:20 PM, Lars Hansen 
 [EMAIL PROTECTED] wrote:
   One facility that was introduced in this draft copies the type tags

  of 'const' and 'var' attributed properties into  the type of the 
  object, for ease of use.  As a consequence,  this test is true:
 
 I don't understand how this could work for var.

The type is introduced on the fixture based on the initial
value; subsequent values will be constrained to be of
that type.  In terms of Draft 2,

  obj = { var x: foo }  // same as { x:foo } : { x:string }
  obj.x = bar   // ok
  obj.x = 37  // not ok

{ const x: foo } is { x: string }
 
   I am going to remove that facility again because it violates  the 
  explicit is better than implicit principle.  IMO the  programmer 
  should state her intent:
 
{ const x: foo } : { x: string }
 
 A possible counter-argument is that the type of foo is 
 string rather than *. We don't make the programmer write
 
 foo :string
 
 in order to get the right type.

It's true, we don't.  But object initializers evaluate to new
compound objects every time, not to immutable values that 
are ===, so I'm skeptical about the analogy.  The type of
an ES3 object initializer is 'Object' (not *).  And if all the
constituents of the initializer are literal expressions it's easy
enough to see what's going on.  But not if the constituents
are not literal expressions.

   (It's easy to say that when the literals are simple then the types
  are obvious, but once they involve more complicated expressions I'm 
  guessing the gains are illusory.)
 
 That's not clear to me. The cases that come to mind compose well:
 
 { const x: { const y: bar } }
 
 has type { x: { y: string }}

I'm more concerned about cases like this:

{ const x: f() }

which are quite opaque and where the object will have a type 
that depends on the value returned by f, possibly a different
type every time the initializer is evaluated.  It's not the
unbounded number of types that worries me but the fact that the
type of that expression is at the mercy of f.

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


Re: ES4 draft: Object initializers

2008-04-07 Thread Brendan Eich
var (outside of eval, an ES1 flaw) means DontDelete.

/be

On Apr 7, 2008, at 1:50 PM, Mark S. Miller wrote:

 On Mon, Apr 7, 2008 at 10:21 AM, Lars Hansen [EMAIL PROTECTED]  
 wrote:
  IMO it ought to be possible to use 'var' in those same ways but we
  didn't discuss that much (if at all).

 I don't understand. What would it mean?

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

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


Re: ES4 draft: Object initializers

2008-04-07 Thread Mark S. Miller
On Mon, Apr 7, 2008 at 2:47 PM, Brendan Eich [EMAIL PROTECTED] wrote:
 var (outside of eval, an ES1 flaw) means DontDelete.

Excellent!

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


Re: ES4 draft: Object initializers

2008-03-21 Thread P T Withington
I can ask `o[f] !== undefined` to determine if a defined property  
named `f` exists in `o`, whether `f` is a fixture or not, correct?  If  
I only have `o`, is there a way for me to detect whether `f` is  
implemented as a getter in `o`, or is that completely invisible to me?

On 2008-03-20, at 19:42 EDT, Lars Hansen wrote:
 I've attempted to sum up everything we have decided about object
 initializers (aka object literals).  A short draft spec is included.
 Comments welcome from everyone, especially from ES4 WG members who  
 might
 remember about things I've forgotten, or correct misunderstandings.

 --lars
 object-literals.html___
 Es4-discuss mailing list
 Es4-discuss@mozilla.org
 https://mail.mozilla.org/listinfo/es4-discuss

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


RE: ES4 draft: Object initializers

2008-03-21 Thread Lars Hansen
o[f] !== undefined does not determine fixtureness, only whether f's
there.  The way to ask about fixtureness is by using a type, I think the
following should work regardless of the actual type of x in o:

  o is { x: * }

If you want to use a variable value f and not a constant name x then
(perversely) I believe the following should work:

  o is let (t = gensym())
  global.eval(type  + t +  = {  + f + :* }; return  + t,
4)

but you have to write your own gensym.

To my knowledge there is no way to ask whether something is a getter or
setter.  That said, the draft of the reflection API is not yet out and
it seems like the kind of thing that it should possibly be able to
reveal.  (The reflection API should be able to answer the previous two
questions too.)

--lars
 

 -Original Message-
 From: P T Withington [mailto:[EMAIL PROTECTED] On Behalf Of 
 P T Withington
 Sent: 21. mars 2008 05:15
 To: Lars Hansen
 Cc: es4-discuss@mozilla.org
 Subject: Re: ES4 draft: Object initializers
 
 I can ask `o[f] !== undefined` to determine if a defined 
 property named `f` exists in `o`, whether `f` is a fixture or 
 not, correct?  If I only have `o`, is there a way for me to 
 detect whether `f` is implemented as a getter in `o`, or is 
 that completely invisible to me?
 
 On 2008-03-20, at 19:42 EDT, Lars Hansen wrote:
  I've attempted to sum up everything we have decided about object 
  initializers (aka object literals).  A short draft spec is included.
  Comments welcome from everyone, especially from ES4 WG members who 
  might remember about things I've forgotten, or correct 
  misunderstandings.
 
  --lars
  
 object-literals.html___
  Es4-discuss mailing list
  Es4-discuss@mozilla.org
  https://mail.mozilla.org/listinfo/es4-discuss
 
 
___
Es4-discuss mailing list
Es4-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es4-discuss


RE: ES4 draft: Object initializers

2008-03-21 Thread Lars Hansen
A bug: repeated fields are also disallowed if the object initializer has
a type annotation.

In summary, only object initializers that look like ES3 initializers are
allowed to have repeated fields (for backward compatibility).

--lars

 -Original Message-
 From: [EMAIL PROTECTED] 
 [mailto:[EMAIL PROTECTED] On Behalf Of Lars Hansen
 Sent: 20. mars 2008 16:43
 To: es4-discuss@mozilla.org
 Subject: ES4 draft: Object initializers
 
 I've attempted to sum up everything we have decided about 
 object initializers (aka object literals).  A short draft 
 spec is included.
 Comments welcome from everyone, especially from ES4 WG 
 members who might remember about things I've forgotten, or 
 correct misunderstandings.
 
 --lars
 
___
Es4-discuss mailing list
Es4-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es4-discuss


ES4 draft: Object initializers

2008-03-20 Thread Lars Hansen
I've attempted to sum up everything we have decided about object
initializers (aka object literals).  A short draft spec is included.
Comments welcome from everyone, especially from ES4 WG members who might
remember about things I've forgotten, or correct misunderstandings.

--lars
Title: Object literals




Object initializer syntax



NAME:   "Object initializer syntax"
FILE:   spec/language/object-literals.html
CATEGORY:   Expressions (E262-3 chapter 11)
SOURCES:ES3; REFERENCES [1]-[6]
SPEC AUTHOR:Lars
DRAFT STATUS:   DRAFT 1 - 2008-03-20
REVIEWED AGAINST ES3:   YES
REVIEWED AGAINST ERRATA:YES
REVIEWED AGAINST BASE DOC:  YES
REVIEWED AGAINST PROPOSALS: YES
REVIEWED AGAINST CODE:  NO
REVIEWED AGAINST TICKETS:   YES
IMPLEMENTATION STATUS:  ?
TEST CASE STATUS:   ?


REFERENCES

[1] ES4 base document
[2] Ticket #164
[3] Ticket #165
[4] Ticket #219
[5] Ticket #319
[6] Bug fixes proposal, item about comma at the end of the field list




Synopsis

 This note tries to pin down all that has been decided about object
initializer syntax.  A brief rationale is attached at the end.


Primary syntax

 In its general form an object initializer is comprised of a
brace-delimited comma-separated list of fields with the last field
optionally followed by a comma, followed by an optional type
annotation (which has to be a structural record type).


ObjInit ::= "{" ( ( Field "," )* Field ","? )? "}" [ ":" RecType ]
Field   ::= FieldName ":" AssignmentExpression
  | "var" FieldName ":" AssignmentExpression
  | "const" FieldName ":" AssignmentExpression
  | "get" FieldName "(" ")" [":" Type] FunctionBody
  | "set" FieldName "(" Param ")" [ ":" "void" ] FunctionBody
FieldName ::= AnyIdentifier | AnyIdentifier "::" AnyIdentifier | LiteralString | LiteralNumber
AnyIdentifier ::= Identifier | ReservedWord


 The FunctionBody of a getter can be a block or an _expression_.
The FunctionBody of a setter can only be a block (until we decide
that ": void" on an _expression_ closure transforms the value computed
to void before "returning").

 It is possible to have a getter without a setter and a setter
without a getter.  A compatible getter or setter will be generated for
the missing method.  The generated setter method receives a value and
discards it silently (this corresponds with the view that writing to
ReadOnly properties fails silently).  The generated getter method
throws a ReferenceError.

 Fields names may be repeated only if none of the instances of a
name are qualified by var, const, get, or set.

Construction

 Unlike the case in ES3, the program can't shadow the binding for
Object in order to invoke an alternative object constructor for
object initializers.


Secondary syntax

 Suppose T is a structural record type:


type T = { x: int, y: double }


 Then the new operator can be used as follows:


new T(10, 2.5)


 The meaning of this is precisely:


{ x: 10, y: 2.5 } : T


 There must be as many arguments to new as there are fields in
T.  The initializers are matched with fields by the order in which
they appear.


Semantics of subphrases

Types and fixtures

 If a property name in the record type that annotates the literal
matches a field name in the literal then the field is a fixture (as
opposed to a dynamic property) and the type of the fixture is the type
of the property given in the record type.  The following makes x a
fixture and gives it the type int:


{ x: 10 } : { x: int }


 The type of the value must be of the type of the field, or must be
convertible to the type of the field.

 If a property name in the record type matches a field name that is
a getter and/or a setter then:


 either the getter has no return type annotation (in which case
the type from the record type will be applied to the getter) or the
return type must be equal to the type present for the property in the
record type;

 either the setter has no parameter type annotation (in which case
the type from the record type will be applied to the parameter) or the
parameter type must be equal to the type present for the property in
the record type; and

 following resolution of the previous two points, the return type of the 
(generated) getter, the parameter type of the (generated) setter, and the
type in the record type must all be equal.


 Fields may be present in the field list that are not present in
the type, but not vice versa.  I.e., the following is legal:


x = { x: 10, y: 20, z: 30 } : { x: int, y: int }


 A field that does not have a matching explicit type annotation in
the record type is dynamic, which is to say it is deletable.  Note in
particular that this applies to 

Re: ES4 draft: Object initializers

2008-03-20 Thread liorean
On 21/03/2008, Lars Hansen [EMAIL PROTECTED] wrote:
 I've attempted to sum up everything we have decided about object
  initializers (aka object literals).  A short draft spec is included.
  Comments welcome from everyone, especially from ES4 WG members who might
  remember about things I've forgotten, or correct misunderstandings.

Just a few ideas, I think there's a few declarative features I'd like
to see added:
- I'd *really* like to see some declarative syntax for setting
{DontEnum} flag on properties in object initialisers.
- A declarative way to set catch-alls.
- A declarative way to set the [[Call]] property.
- And maybe declarative way to set the [[Prototype]] property. (This
would of course be const.)


var
a={
dontenum toString: function()'[object customObj]'
},
b={
[[Prototype]]: a,
[[Call]]: function()...,
get *: function(propname)...,
set *: function(propname, value)...,
...
};

The brackets for syntax would from what I can tell work here, since
they are syntax errors in ES3. Or using some double keyword syntax I
guess.
-- 
David liorean Andersson
___
Es4-discuss mailing list
Es4-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es4-discuss


Re: ES4 draft: Object initializers

2008-03-20 Thread Jon Zeppieri
On 3/20/08, Lars Hansen [EMAIL PROTECTED] wrote:
 Thanks for pointing some of these out, Brendan did the same.  This is
  already legal to define catch-alls:

   { var meta::get: function () { ... } }

Is there a more recent version of the grammar than the docs at
http://wiki.ecmascript.org/doku.php?id=proposals:normative_grammar ?

This syntax isn't legal according to the grammar there, nor is it
recognized by the RI.

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


RE: ES4 draft: Object

2008-03-17 Thread Lars Hansen
Draft 3 of the spec for the Object class.  Changelog near the beginning.
(Notably this version includes draft code for __createProperty__.)

--lars


Title: The class "Object"




 The class Object 



NAME:   "The class 'Object'"
FILE:   spec/library/Object.html
CATEGORY:   Pre-defined classes (E262-3 Chapter 15)
SOURCES:REFERENCES [1], [2]
SPEC AUTHOR:Lars
DRAFT STATUS:   DRAFT 3 - 2008-03-14
REVIEWED AGAINST ES3:   YES
REVIEWED AGAINST ERRATA:YES
REVIEWED AGAINST BASE DOC:  YES
REVIEWED AGAINST PROPOSALS: YES
REVIEWED AGAINST CODE:  YES
IMPLEMENTATION STATUS:  ES4RI
TEST CASE STATUS:   ?


CHANGES SINCE DRAFT 2 (2008-03-10)

  * Removed a "note" below

  * Fixed the spec for Object.prototype.toString (there needs to be a
space preceding the class name)

  * Removed the optional second argument on 'propertyIsEnumerable'

  * Added the method __createProperty__


CHANGES SINCE DRAFT 1 (2008-03-05)

  * More elaborate status block above

  * Prototype methods do not delegate to the corresponding intrinsic
methods, but to shared private methods that are also called by the
intrinsic method.  In this fashion, prototype method behavior is
invariant of subclassing

  * Introduction of a specification-only protocol helper::getClassName
for overriding class names for ES3 compatibility

NOTES

  * The use of 'Private' instead of 'private' below is a workaround
for a bug in the reference implementation (#368)


REFERENCES

[1] http:wiki.ecmascript.org/doku.php?id=proposals:enumerability
[2] builtins/Name.es in the ES4 RI



 The class Object is a dynamic non-final class that does not
subclass any other objects: it is the root of the class hierarchy.

 All values in ECMAScript except undefined and null are
instances of the class Object or one of its subclasses.

NOTE  Host objects may not be instances of Object or its
subclasses, but must to some extent behave as if they are (see Host objects).


Synopsis

The class Object provides this interface:


public dynamic class Object
{
public function Object(value=undefined) 
static meta function invoke(value=undefined) 

static public const length = 1

intrinsic function toString() : string 
intrinsic function toLocaleString() : string 
intrinsic function valueOf() : Object 
intrinsic function hasOwnProperty(name: EnumerableId): boolean 
intrinsic function isPrototypeOf(value): boolean 
intrinsic function propertyIsEnumerable(name: EnumerableId): boolean 
intrinsic function __createProperty__(name: EnumerableId, value, enumerable:boolean=true, removable:boolean=true, writable:boolean=true): void 
}


 The Object prototype object provides these direct properties:

toString: function () 
toLocaleString:   function () 
valueOf:  function () 
hasOwnProperty:   function (name) 
isPrototypeOf:function (value) 
propertyIsEnumerable: function (name) 
__createProperty__:   function (name, value, dontEnum=undefined, dontDelete=undefined, readOnly=undefined) 


 The Object prototype object is itself an instance of the class
Object, with the exception that the value of its [[Prototype]]
property is null.


Methods on the Object class object

newObject(value=)

Description  When the Object constructor is called with an argument
value (defaulting to undefined) as part of a new
_expression_, it transforms the value to an object in a way that
depends on the type of value.

Returns  The Object constructor returns an object (an instance of
Object or one of its subclasses, or a host object).

NOTE  The Object constructor is the only constructor function
defined on a class in the language whose result may be a value of a
different class than the one in which the constructor is defined.

Implementation  The Object constructor can't be expressed as a regular
ECMAScript constructor.  Instead it is presented below as a helper
function makeObject that the ECMAScript implementation will invoke
when it evaluates new Object.

 The helper function makeObject only is invoked on native ECMAScript
values.  If new Object is evaluated on a host object, then actions
are taken and a result is returned in an implementation dependent
manner that may depend on the host object.


helper function makeObject(value=undefined) {
switch type (value) {
case (s: string) {
return new String(s);
}
case (b: boolean) { 
return new Boolean(b);
}
case (n: (int|uint|double|decimal)) { 
return new Number(n);
}
case (x: (null|undefined)) { 
return magic::createObject();
}
case (o: Object) {
return o;
}
}
}



Object(value=)

Description  When the Object class object is called as a function with zero
or one arguments it performs a type conversion.

Returns  It returns the converted 

Re: ES4 draft: Object

2008-03-13 Thread Yuh-Ruey Chen
Brendan Eich wrote:
 If we end up making all namespaced properties non-enumerable, then we  
 may want a property iterator that returns the names of all properties  
 in a given object. Even if this is not in the standard, it's likely  
 to be an extension. Or it could be added in the future.
   

Absolutely. In fact, I thought there was already an iterator that yields 
all properties regardless of enumerability, just that this iterator 
would not be the default iterator for objects. If it's not in ES4, it 
should definitely be there because it's essential for those that want to 
customize enumerability.

 The question of whether ES3+4 mixtures might not want enumerable ES3  
 properties to appear to be in a predefined-in-ES4 namespace seems to  
 me worth considering, at the limit as a future-proofing step.
   

What do you mean by ES3+4 mixture - how would you tell that one part is 
ES3 and another part ES4, or how a program is pure ES4?

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


Re: ES4 draft: Object

2008-03-13 Thread Yuh-Ruey Chen
Peter Hall wrote:
   The latter. It is weird, I agree. But the enumerator can easily be
   customized, so I want the default enumerator be as non-magical as
   possible - and therefore, as simple as possible. In fact, I'm a bit
   bothered that propertyIsEnumerable is a method of Object yet can be
   rendered useless when changing the enumerator - along this line of
   reasoning, one would think that such a specific method shouldn't be a
   method of Object at all, but rather the enumerator itself.
 

 So how would you go about enumerating the properties of an arbitrary
 dynamic object, whose properties could be in namespaces?
   

I thought there was an iterator that would enumerate all properties 
regardless of enumerability (including those in other namespaces), but 
apparently not. There should be such an iterator though.

   Yeah, I vaguely remember some discussion concerning multiple namespaces
   per property a long time ago (maybe a year ago). It was rejected
   probably due to complexity.

 Not being able to combine them effectively makes many of the initial
 proposal's use-cases useless, because two use-cases may arise
 simultaneously when integrating two codebases, and be irreparably
 conflicting.

 Peter
   

What initial proposal are you talking about?

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


Re: Controlling DontEnum (was: ES4 draft: Object)

2008-03-13 Thread Kris Zyp
 the frequency of use).  Thus on Object.prototype and as an
 intrinsic propety on Object instances:

  function __createProperty__(name:EnumerableId,
  dontEnum:boolean=false,
  dontDelete:boolean=false,
  readOnly:boolean=false): void
I thought that this only made sense in conjunction with Neil's suggestion of 
providing the value at the same time. If you create a readonly property, how 
are you supposed to set the value otherwise? Shouldn't it be:
function __createProperty__(name:EnumerableId,
value,
dontEnum:boolean=false,
dontDelete:boolean=false,
readOnly:boolean=false): void

And if readOnly implied dontDelete, I would have guessed readOnly to be a 
little more frequent than dontDelete, but of course that is just a guess.
Kris



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


Re: ES4 draft: Object

2008-03-13 Thread Waldemar Horwat
Yuh-Ruey Chen wrote:
 Brendan Eich wrote:
 If we end up making all namespaced properties non-enumerable, then we  
 may want a property iterator that returns the names of all properties  
 in a given object. Even if this is not in the standard, it's likely  
 to be an extension. Or it could be added in the future.
   
 
 Absolutely. In fact, I thought there was already an iterator that yields 
 all properties regardless of enumerability, just that this iterator 
 would not be the default iterator for objects. If it's not in ES4, it 
 should definitely be there because it's essential for those that want to 
 customize enumerability.

As was discussed before, the language cannot have such an iterator.  Were this 
iterator to exist, an attacker could use it to discover hidden properties of 
objects, get access to private and other restricted namespaces, alter private 
state, and break through abstraction barriers.

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


Re: Controlling DontEnum (was: ES4 draft: Object)

2008-03-13 Thread Peter Hall
Is there enough value in complicating matters by adding the ability to
set dontDelete and readOnly? You can create non-deletable properties
by using a class or record type, and you can create read-only
properties by adding a get function without a corresponding set...

Are there any use cases where these solutions won't cover it?

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


RE: Controlling DontEnum (was: ES4 draft: Object)

2008-03-13 Thread Lars Hansen
 -Original Message-
 From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On 
 Behalf Of Peter Hall
 Sent: 13. mars 2008 12:38
 To: Lars Hansen
 Cc: Kris Zyp; es4-discuss@mozilla.org
 Subject: Re: Controlling DontEnum (was: ES4 draft: Object)
 
 Is there enough value in complicating matters by adding the 
 ability to set dontDelete and readOnly? You can create 
 non-deletable properties by using a class or record type, and 
 you can create read-only properties by adding a get function 
 without a corresponding set...
 
 Are there any use cases where these solutions won't cover it?

Depends on your point of view.  I wrote a paper on evolutionary
programming in ES4 (available from ecmascript.org), which demonstrates a
progression from ES3 style code to ES4 style code with various stops
along the way.  One of the holes in that story is that it's not possible
to make the properties introduced in a function-style constructor
anything but enumerable, deletable, and writable:

  function Server(host) {
this.host = host
this.database = []
  }

Both these fields are supposed to be constant, and there's no reason for
them to be enumerable.  The paper shows how you can use a user-defined
namespace to make them inaccessible (non-public namespaced properties
are not enumerated, and if the namespace is hidden from client code --
not always easy -- then the field can't be accessed or deleted), but
it's clearly a bit of a hack in that it is a consequence of other design
choices in the language.  The direct approach would set the properties
explicitly:

  function Server(host) {
this.__createProperty__(host, host, true, true, true);
this.__createProperty__(database, [], true, true, true);
  }

So this is a use case if you believe that relatively fine-grained
evolution from ES3 style to ES4 style is a feature of the language.  (I
do.)

There are declarative ways of solving the problem -- essentially
annotating the function, saying this is a constructor function and the
fields named such and so are going to have these and those attributes,
but they add yet more features to an already fairly feature-laden
language.

(One proposal goes like this:

  constructor function Server(host) : { const host: string, const
database: array } {
this.host = host
this.database = []
  }

and it's not all that heavyweight, but it's a new, ad hoc feature all
the same.)

I'm mostly agnostic about __createProperty__ being able to set
DontDelete and ReadOnly; DontEnum is the really important one.  At the
same time, it seems silly not to just solve the general problem when we
have a chance.  Just because you can't enumerate a property doesn't mean
that you -- or a library you import -- can't accidentally -- or
maliciously -- overwrite it.

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


Re: Controlling DontEnum (was: ES4 draft: Object)

2008-03-13 Thread Kris Zyp
 set dontDelete and readOnly? You can create non-deletable properties
 by using a class or record type
They can't be added after an object is created.

 and you can create read-only
 properties by adding a get function without a corresponding set...
Unless behavior is different than ES3, setters (and lack thereof) are not 
dontDelete, therefore still easily mutated:
 obj = {get foo() { return 'hi' }}
Object foo=hi
 obj.foo
hi
 delete obj.foo
true
 obj.foo = 'goodbye'
goodbye
 obj.foo
goodbye

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


Re: Controlling DontEnum (was: ES4 draft: Object)

2008-03-13 Thread liorean
On 13/03/2008, Lars Hansen [EMAIL PROTECTED] wrote:
  Since our method is creating a new property and not setting
  one, I suggest __createProperty__ as the most appropriate
  name, so I'm going to use that below.

Sounds perfectly reasonable to me.

  I still think it may be right that properties in non-public
  namespaces should not be enumerated, but I also think that's
  orthogonal to the discussion that's going on here, about
  dynamic properties and their attributes.  We've pretty much
  decided (ticket #233 has some of the discussion) that for
  future compatibility there ought to be a difference between
  fixture properties and DontDelete dynamic properties.  So
  dynamic properties have at least one attribute bit like they
  do in ES3 (for deletability).  Consequently, they might as
  well have all the ES3 bits: for enumerability and writability.

For ES4, shouldn't this function also take a type binding?

  Ergo, let's assume that we are not finessing more than we
  have to, and dynamic properties have all these attribute bits.
  I don't know why __createProperty__ should not be able to
  set all of these.

Neither can I.

  (They're not independent, ReadOnly implies DontDelete.)

  __createProperty__ should throw an exception (TypeError?) if
  the property already exists on the object or would shadow a
  ReadOnly property, a la [[CanPut]], or if the object is not
  dynamic.  It should probably throw an exception if its
  arguments are not consistent (ReadOnly  !DontDelete).

If ReadOnly is specified, is there even a reason to look at DontDelete?

  Pesonally I like the strings approach, but the only interface
  among these four that has good compile-time checking is the
  first one, so I'm going to propose that we use that one,
  with dontEnum as the first flag, dontDelete as
  the second, and readOnly as the third (based on a guess about
  the frequency of use).  Thus on Object.prototype and as an
  intrinsic propety on Object instances:

   function __createProperty__(name:EnumerableId,
   dontEnum:boolean=false,
   dontDelete:boolean=false,
   readOnly:boolean=false): void

ReadOnly would need to be instanciated at the same time, no? And you
probably want to be able to specify a type binding for ES4.

   * The above does not preclude complementary declarative
 mechanisms in ES4 (but not in ES3.1 obviously)

Good to hear, because I still want to see something that can be used
in object literals and property declarations.
-- 
David liorean Andersson
___
Es4-discuss mailing list
Es4-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es4-discuss


Re: Controlling DontEnum (was: ES4 draft: Object)

2008-03-13 Thread Neil Mix
On Mar 13, 2008, at 11:47 AM, Lars Hansen wrote:

  function __createProperty__(name:EnumerableId,
  dontEnum:boolean=false,
  dontDelete:boolean=false,
  readOnly:boolean=false): void


I like where this is going.  May I (in addition to Kris's suggestion  
for adding a value parameter) kindly nit on the parameter names?

function __createProperty__(name:EnumerableId,
 value:*,
 enumerable:boolean=true,
 removable:boolean=true,
 writable:boolean=true): void

Or some reasonable variant therein?  I have no strong opinions on the  
form the parameters eventually take, but trying to parse what  
dontenum=false means tends to give me headaches. ;)


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


RE: Controlling DontEnum (was: ES4 draft: Object)

2008-03-13 Thread Lars Hansen
 -Original Message-
 From: Neil Mix [mailto:[EMAIL PROTECTED] 
 Sent: 13. mars 2008 14:47
 To: Lars Hansen
 Cc: es4-discuss@mozilla.org
 Subject: Re: Controlling DontEnum (was: ES4 draft: Object)
 
 On Mar 13, 2008, at 11:47 AM, Lars Hansen wrote:
 
   function __createProperty__(name:EnumerableId,
   dontEnum:boolean=false,
   dontDelete:boolean=false,
   readOnly:boolean=false): void
 
 
 I like where this is going.  May I (in addition to Kris's 
 suggestion for adding a value parameter) kindly nit on the 
 parameter names?
 
 function __createProperty__(name:EnumerableId,
  value:*,
  enumerable:boolean=true,
  removable:boolean=true,
  writable:boolean=true): void
 
 Or some reasonable variant therein?  I have no strong 
 opinions on the form the parameters eventually take, but 
 trying to parse what dontenum=false means tends to give me 
 headaches. ;)

Well, it had to come up at some point ;)

I suspect what you're proposing is the better UI.  Obviously JS1/ES3
shows a bias for enumerable, removable, writable properties -- the
attribute bits flag exceptions from the general rule.  The more general
design has attribute bits that simply control those property aspects,
and the less biased names feel like an improvement.

Brendan, opinions?

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


Re: Controlling DontEnum (was: ES4 draft: Object)

2008-03-13 Thread Brendan Eich
On Mar 13, 2008, at 2:07 PM, Lars Hansen wrote:

 -Original Message-
 From: Neil Mix [mailto:[EMAIL PROTECTED]

 function __createProperty__(name:EnumerableId,
  value:*,
  enumerable:boolean=true,
  removable:boolean=true,
  writable:boolean=true): void

 Or some reasonable variant therein?  I have no strong
 opinions on the form the parameters eventually take, but
 trying to parse what dontenum=false means tends to give me
 headaches. ;)

 Well, it had to come up at some point ;)

 I suspect what you're proposing is the better UI.  Obviously JS1/ES3
 shows a bias for enumerable, removable, writable properties -- the
 attribute bits flag exceptions from the general rule.  The more  
 general
 design has attribute bits that simply control those property aspects,
 and the less biased names feel like an improvement.

 Brendan, opinions?

Neil's names are much better. For the record, I didn't come up with  
DontDelete and DontEnum in ES1 daze. SpiderMonkey internally uses  
PERMANENT for the former and ENUMERATE for the inverse of the latter  
(since the native-biased API finds callers wanting enumerable pre- 
defined properties to be the exception).

/be

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


Re: ES4 draft: Object

2008-03-13 Thread Jeff Dyer
FWIW, AS3, which doesn't have iterators, enumerates only the expando
properties of an object. This was in part because we didn't have (qualified)
name objects that could be enumerated, and in part because of it being
complicated to determine the set of names that could be safely exposed (e.g.
all the names in open namespaces, all the public names regardless of their
current visibility, etc). IOW, we punted.

Jd


On 3/13/08 11:29 AM, Waldemar Horwat wrote:

 Yuh-Ruey Chen wrote:
 Brendan Eich wrote:
 If we end up making all namespaced properties non-enumerable, then we
 may want a property iterator that returns the names of all properties
 in a given object. Even if this is not in the standard, it's likely
 to be an extension. Or it could be added in the future.
   
 
 Absolutely. In fact, I thought there was already an iterator that yields
 all properties regardless of enumerability, just that this iterator
 would not be the default iterator for objects. If it's not in ES4, it
 should definitely be there because it's essential for those that want to
 customize enumerability.
 
 As was discussed before, the language cannot have such an iterator.  Were this
 iterator to exist, an attacker could use it to discover hidden properties of
 objects, get access to private and other restricted namespaces, alter private
 state, and break through abstraction barriers.
 
 Waldemar
  
 ___
 Es4-discuss mailing list
 Es4-discuss@mozilla.org
 https://mail.mozilla.org/listinfo/es4-discuss

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


Re: Controlling DontEnum (was: ES4 draft: Object)

2008-03-13 Thread Mark S. Miller
 From: Neil Mix [mailto:[EMAIL PROTECTED]

 function __createProperty__(name:EnumerableId,
  value:*,
  enumerable:boolean=true,
  removable:boolean=true,
  writable:boolean=true): void



On Thu, Mar 13, 2008 at 2:21 PM, Lars Hansen [EMAIL PROTECTED] wrote:
 This feels like convergence.  I'll hook this into the RI and
  write it up in the next couple of days (barring further
  discussion, of course).

I've been following this discussion and am quite happy with the
overall direction! With these changes, ES3.1 should be a much
friendlier base to subset into a Caja-like secure language. I'm
hopeful that the resulting Caja-like language could safely be a much
larger subset of ES3.1 than with current Caja vs ES3. I haven't yet
thought these issues through well, but I'll offer some half baked
suggestions for now.

* As someone pointed out, using positional boolean flag parameters
(..., false, true, false, ...) makes call-site readability too hard.
This point was raised earlier but seems to have been dropped. IIRC,
*all* the other parameterization suggestions had better call site
readability. My favorite was simply a list of strings. OTOH, an
advantage of the bit-mask approach is that sensible combinations of
flags can be named and used simply.

* I love Neil's suggestion of moving towards names saying what's
allowed, rather than saying what's denied. I'd like to go further and
suggest that __createProperty__ adopt the security best-practice of
default-deny: When a property is explicitly created by this mechanism,
only those operations that are explicitly allowed are permitted. All
others attributes default to denying permission. To maintain
compatibility of course, a property created the old fashioned way is
implicitly fully permissive.

* As Brendan reminds us, an erroneous __createProperty__ request
should throw rather than failing silently or merely returning false.
And a property access that fails because __createProperty__ did not
allow it should also fail with a throw rather than silently. If we
want to be strictly legacy compatible, then these throws should only
happen for properties created with __createProperty__. Unfortunately,
that means the semantics and implementations would need to
distinguish, for example, legacy silently non-writable properties from
new noisily non-writable properties. Can we instead specify that all
these failures will be noisy?

* Kris raises, we need to think about the interaction of these
attributes with the notion of virtual properties defined using getters
and setters. In particular, how does one create a non-removable
virtual property? Should virtual properties have deleters in addition
to getters and setters?

* Might there be a sensible way to extend this mechanism to
distinguish public from non-public properties? Based on the Caja
design, might we adopt the rule that non-public property foo can only
be addressed as this.foo or this['foo']. In other words, x.foo would
only work is foo is public or unrestricted.


The general approach we're following here for properties is: default
to legacy-compatible overly-permissive behavior, but allow restriction
to a fail-stop subset of this behavior. We should prefer to make
expressible those restrictions that contribute to reasoning about
integrity. (This is the right criteria whether on not one is trying to
define a secure subset.)

We should apply this general approach to objects as well as individual
properties of objects. The most important, borrowed from ES4, is
fixture vs dynamic. The Caja concept frozen then becomes exactly:
fixture + all existing properties are non-writable and non-removable.

We can even use this approach to clean up the main source of confusion
in ES3 while preserving compatibility: What is the intended behavior
of a function? It would be great to explicitly restrict a function to
be callable only as a function, or only as a method, or only as a
constructor, or only as a final constructor. An unrestricted function
could continue to be callable in all these ways, as with ES3
functions. Moving these restrictions into the language would clear up
a major source of vulnerability in the current Caja design: confused
deputy dangers at the taming boundary between cajoled code and
uncajoled code. If there's interest, I can expand on this issue.

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


RE: Controlling DontEnum (was: ES4 draft: Object)

2008-03-13 Thread Lars Hansen
Speaking for myself, I should say from the outset that I am
not in favor of taking this much further than it has been
taken.  The base language is ES3; we're trying to fix a
small problem in that language in the cheapest possible way.
I would rather backtrack to a solution that only fixes the
DontEnum problem than to go forward into an elaborate
design that attempts to fix various dodgy (or perceived as
dodgy) features in the base language.

Getters and setters should not be an issue.  There is
no way in ES4 to add a getter or setter to an object after
the fact; getters and setters defined by an object initializer
or in a class are fixtures and hence not deletable.

(Some browsers have functions __defineGetter__ and 
__defineSetter__ that allow getters and setters to be
added after the fact.  Those are normally deletable.
I suggest that these browsers expand their API to match
that of __createProperty__.)

--lars

 -Original Message-
 From: Mark S. Miller [mailto:[EMAIL PROTECTED] 
 Sent: 13. mars 2008 17:22
 To: Lars Hansen
 Cc: es4-discuss@mozilla.org
 Subject: Re: Controlling DontEnum (was: ES4 draft: Object)
 
  From: Neil Mix [mailto:[EMAIL PROTECTED]
 
  function __createProperty__(name:EnumerableId,
   value:*,
   enumerable:boolean=true,
   removable:boolean=true,
   writable:boolean=true): void
 
 
 
 On Thu, Mar 13, 2008 at 2:21 PM, Lars Hansen 
 [EMAIL PROTECTED] wrote:
  This feels like convergence.  I'll hook this into the RI 
 and  write it 
  up in the next couple of days (barring further  discussion, of 
  course).
 
 I've been following this discussion and am quite happy with 
 the overall direction! With these changes, ES3.1 should be a 
 much friendlier base to subset into a Caja-like secure 
 language. I'm hopeful that the resulting Caja-like language 
 could safely be a much larger subset of ES3.1 than with 
 current Caja vs ES3. I haven't yet thought these issues 
 through well, but I'll offer some half baked suggestions for now.
 
 * As someone pointed out, using positional boolean flag 
 parameters (..., false, true, false, ...) makes call-site 
 readability too hard.
 This point was raised earlier but seems to have been dropped. IIRC,
 *all* the other parameterization suggestions had better call 
 site readability. My favorite was simply a list of strings. 
 OTOH, an advantage of the bit-mask approach is that sensible 
 combinations of flags can be named and used simply.
 
 * I love Neil's suggestion of moving towards names saying 
 what's allowed, rather than saying what's denied. I'd like to 
 go further and suggest that __createProperty__ adopt the 
 security best-practice of
 default-deny: When a property is explicitly created by this 
 mechanism, only those operations that are explicitly allowed 
 are permitted. All others attributes default to denying 
 permission. To maintain compatibility of course, a property 
 created the old fashioned way is implicitly fully permissive.
 
 * As Brendan reminds us, an erroneous __createProperty__ 
 request should throw rather than failing silently or merely 
 returning false.
 And a property access that fails because __createProperty__ 
 did not allow it should also fail with a throw rather than 
 silently. If we want to be strictly legacy compatible, then 
 these throws should only happen for properties created with 
 __createProperty__. Unfortunately, that means the semantics 
 and implementations would need to distinguish, for example, 
 legacy silently non-writable properties from new noisily 
 non-writable properties. Can we instead specify that all 
 these failures will be noisy?
 
 * Kris raises, we need to think about the interaction of 
 these attributes with the notion of virtual properties 
 defined using getters and setters. In particular, how does 
 one create a non-removable virtual property? Should virtual 
 properties have deleters in addition to getters and setters?
 
 * Might there be a sensible way to extend this mechanism to 
 distinguish public from non-public properties? Based on the 
 Caja design, might we adopt the rule that non-public property 
 foo can only be addressed as this.foo or this['foo']. In 
 other words, x.foo would only work is foo is public or unrestricted.
 
 
 The general approach we're following here for properties is: 
 default to legacy-compatible overly-permissive behavior, but 
 allow restriction to a fail-stop subset of this behavior. We 
 should prefer to make expressible those restrictions that 
 contribute to reasoning about integrity. (This is the right 
 criteria whether on not one is trying to define a secure subset.)
 
 We should apply this general approach to objects as well as 
 individual properties of objects. The most important, 
 borrowed from ES4, is fixture vs dynamic. The Caja concept 
 frozen then becomes exactly:
 fixture + all existing properties are non

Re: ES4 draft: Object

2008-03-11 Thread Maciej Stachowiak

On Mar 10, 2008, at 7:01 PM, Lars Hansen wrote:

 We are the WG.  Are you saying that substantive discussions
 of your proposals are not welcome?  Not sure what the point
 of participating is if that's the case.

 Sorry, I didn't realize that I find it abhorrent qualified as
 substantive discussion.  My fault.  Won't happen again.

The optional second argument to make propertyIsEnumerable a setter has  
some practical problems:

1) It violates the very strong norm that getter and setter functions  
are separate and have their own different arguments. It will make the  
feature harder to use and code using it harder to understand, to some  
extent.
2) It makes it impossible to feature test for the ability to disable  
enumerability, compared to a separate setter.

Against the argument that it is too risky compatibility-wise to add a  
new method to the object prototype (apparently the only reason things  
were done), I propose that it is overblown. Mozilla has defined new  
methods and properties on all objects. We have copied some in Safari  
and seen no web compatibility issues, I assume Mozilla has not had any  
as well. Specifically, I am thinking of __defineSetter__,  
__defineGetter__, __lookupSetter__, __lookupGetter__, and __proto__.

Has any study been done on how many sites currently make use of the  
property names of a likely setter for propertyIsEnumerable?

 I'm dealing with a serious insurrection of folks who believe
 that the ES4 working group has a bad attitude, based on
 Brendan's public comments and responses to issues like this
 one.  They're quite visible.

 Debate is only good.  I merely pointed out the obvious thing, namely
 that until there is an alternative proposal written up to deal with
 this issue, the current design stands unless the WG, as a group,
 decides to just get rid of it (leaving the problem it was designed
 to solve solution-less).

Surely reviewing this spec is the appropriate time to revisit this  
issue. I'd like to propose the following three alternatives to the  
current proposal:

1) Remove the feature entirely from ES4 (as part of the judicious  
feature cuts process) until a more appropriate syntax is found
2) Replace two-argument form of propertyIsEnumerable with  
setPropertyIsEnumerable
3) Replace two-argument form of propertyIsEnumerable with  
__setPropertyIsEnumerable__

I think each of these options is so trivial as to not require a  
lengthy write-up.

What is the process for the WG deciding whether to make one of these  
changes, or something else?

 I like the idea of making non-public-namespaced properties be
 not-enumerable and getting rid of DontEnum.  We've talked loosely
 about it for a while.  But it's remained loose talk, it has never
 made it to the stage where it is a coherent proposal.

I don't like syntax-based alternatives since they cannot be made to  
degrade gracefully in ES3 UAs.

Regards,
Maciej


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


Re: Insurrection (was: ES4 draft: Object)

2008-03-11 Thread Maciej Stachowiak

On Mar 10, 2008, at 9:54 PM, Mark Miller wrote:

 ES3 has several abstraction mechanisms:
 * lambda abstraction, which it gets approximately as right as Scheme!
 * objects as a generalization of records, which has some pros and cons
 * prototype-based sharing of common behavior, which is used almost
 exclusively by JavaScript programmers to express only class-like
 patterns.

 Altogether, ES3 has many virtues and many problems. One of its great
 virtues is its almost perfect support for lexical nesting. Virtually
 any thisless construct that could appear at top level can also appear
 within a nested lexical context with the same meaning. ES3 also avoids
 the CommonLisp trap of multiple namespaces, instead siding with
 Scheme's single namespace approach.

 Even ignoring ES4's type system, ES4 adds all the following
 abstraction mechanisms to those in ES3:
 * classes
 * packages
 * units
 * namespaces

You forgot interfaces (and the type system also adds record types,  
(sort-of)-tuples, typed arrays and parametric types). That does seem  
like a lot.

  - Maciej

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


Re: Insurrection (was: ES4 draft: Object)

2008-03-11 Thread Geoffrey Garen
 ES3 has several abstraction mechanisms:
 * lambda abstraction, which it gets approximately as right as Scheme!
 * objects as a generalization of records, which has some pros and  
 cons
 * prototype-based sharing of common behavior, which is used almost
 exclusively by JavaScript programmers to express only class-like
 patterns.

 Altogether, ES3 has many virtues and many problems. One of its great
 virtues is its almost perfect support for lexical nesting. Virtually
 any thisless construct that could appear at top level can also appear
 within a nested lexical context with the same meaning. ES3 also  
 avoids
 the CommonLisp trap of multiple namespaces, instead siding with
 Scheme's single namespace approach.

 Even ignoring ES4's type system, ES4 adds all the following
 abstraction mechanisms to those in ES3:
 * classes
 * packages
 * units
 * namespaces

 You forgot interfaces (and the type system also adds record types,
 (sort-of)-tuples, typed arrays and parametric types). That does seem
 like a lot.

There are also like / wrap types.

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


Re: ES4 draft: Object

2008-03-11 Thread Maciej Stachowiak

On Mar 10, 2008, at 11:14 PM, Maciej Stachowiak wrote:

 The optional second argument to make propertyIsEnumerable a setter has
 some practical problems:

 1) It violates the very strong norm that getter and setter functions
 are separate and have their own different arguments. It will make the
 feature harder to use and code using it harder to understand, to some
 extent.
 2) It makes it impossible to feature test for the ability to disable
 enumerability, compared to a separate setter.

 Against the argument that it is too risky compatibility-wise to add a
 new method to the object prototype (apparently the only reason things
 were done), I propose that it is overblown. Mozilla has defined new
 methods and properties on all objects. We have copied some in Safari
 and seen no web compatibility issues, I assume Mozilla has not had any
 as well. Specifically, I am thinking of __defineSetter__,
 __defineGetter__, __lookupSetter__, __lookupGetter__, and __proto__.

 Has any study been done on how many sites currently make use of the
 property names of a likely setter for propertyIsEnumerable?

I forgot to mention, making two-argument propertyIsEnumerable have  
setter semantics can be a tiny compatibility risk too, if any code  
accidentally calls it with two args and does not expect it to act as a  
setter in this case. Do we have any way to quantify the relative  
compatibility risk of the current design vs. a separate setter?

Regards,
Maciej


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


Re: ES4 draft: Object

2008-03-11 Thread Mark S. Miller
On Mon, Mar 10, 2008 at 11:14 PM, Maciej Stachowiak [EMAIL PROTECTED] wrote:
 [...] I'd like to propose the following three alternatives to the
  current proposal:

  1) Remove the feature entirely from ES4 (as part of the judicious
  feature cuts process) until a more appropriate syntax is found
  2) Replace two-argument form of propertyIsEnumerable with
  setPropertyIsEnumerable
  3) Replace two-argument form of propertyIsEnumerable with
  __setPropertyIsEnumerable__

So long as setPropertyIsEnumerable is a method of Object.prototype, it
raises the otherwise pointless question of the meaning of overriding
it. At the last ES3.1 face-to-face, we agreed instead on the following
static method on Object, as recorded at
http://wiki.ecmascript.org/doku.php?id=es3.1:targeted_additions_to_array_string_object_date:

-
Object.dontEnum(object, memberName)

The own property memberName of object is marked to be excluded for the
for in enumeration.

If a new object is made that delegates to object, the new object may
create and change its own memberName property, and that property will
be enumerable.
-

That page also lists static methods on Object to set the attributes
DontDelete and ReadOnly. The proposed static Object.fix(obj) is
inspired by proposed ES4's notion of a fixture -- a non-dynamic
object. Such static methods allow most of the restrictions associated
with ES4's classes to be expressed without new syntax or major new
concepts.

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


Re: ES4 draft: Object

2008-03-11 Thread Maciej Stachowiak

On Mar 10, 2008, at 11:35 PM, Mark S. Miller wrote:

 On Mon, Mar 10, 2008 at 11:14 PM, Maciej Stachowiak [EMAIL PROTECTED]  
 wrote:
 [...] I'd like to propose the following three alternatives to the
 current proposal:

 1) Remove the feature entirely from ES4 (as part of the judicious
 feature cuts process) until a more appropriate syntax is found
 2) Replace two-argument form of propertyIsEnumerable with
 setPropertyIsEnumerable
 3) Replace two-argument form of propertyIsEnumerable with
 __setPropertyIsEnumerable__

 So long as setPropertyIsEnumerable is a method of Object.prototype, it
 raises the otherwise pointless question of the meaning of overriding
 it.

I don't see how it raises any special questions - it's not called  
internally by the implementation or anything.

 At the last ES3.1 face-to-face, we agreed instead on the following
 static method on Object, as recorded at
 http://wiki.ecmascript.org/doku.php?id=es3.1:targeted_additions_to_array_string_object_date
  
 :

That proposal seems to depart markedly from the past plan that ES 3.1  
is to be a subset of ES4. Has that plan been abandoned? ES3.1  
organizers, what's up?

(If you'd like to propose this design for ES4 as well then the basic  
approach seems sound, in that it avoids whatever risk there is to  
polluting the namespace of all objects without being conceptually  
confusing. Also the names lean too much towards terse instead of  
descriptive for such obscure operations. For instance  
Object.readOnly(o, p) would read much better as something like  
Object.makePropertyReadOnly(o, p).)

Regards,
Maciej

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


Re: ES4 draft: Object

2008-03-11 Thread liorean
On 11/03/2008, Maciej Stachowiak [EMAIL PROTECTED] wrote:
 This is not unreasonable, but if adding to Object.prototype is truly
  terrifying then I think the approach Mark Miller linked to, of static
  methods on the Object constructor, is cleaner:
/snip/
  It might even be better to make this transition one-way, since it
  shouldn't be allowed to make built-in properties that are DontEnum
  enumerable:

Could as well make it a global function then. Just give it an obscure
__preventEnumeration__(obj, propName) signature or something.

I would very much like to see a declarative keyword for use with
global, class and namespace variable and function declarations and in
object literals. There's really not much reason to require a function
call for a declarative feature if there's a cheap and much nicer way
to do it in ES4, as long as you have a solution for ES3.

(Kinda like how there's a specific slice syntax in ES4, but the slice
functionality itself is ES3 compatible.)
-- 
David liorean Andersson
___
Es4-discuss mailing list
Es4-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es4-discuss


Re: ES4 draft: Object

2008-03-11 Thread Peter Hall
Yuh-Ruey Chen [EMAIL PROTECTED] wrote:
  Which gets me back to the cognitive load issue. Even with a name like
  'hidden', they may think they may have to do some funky syntax like
  |obj.hidden::other_ns::prop| do hide a prop in another namespace.


This was confusing me... How would you define a property to have a
qualified name and be in the dontenum namespace at the same time? Or
are namespaced properties non-enumerable anyway? (That would feel
wrong to me..)

namespace dontenum_ns = dontenum other_ns;
obl.dontenum_ns::prop = 1;

?

The problem here would be the property would always be accessible to
all scopes, since only one of the namespaces needs to be open. ES4
doesn't currently have a way to express AND/OR namespace combinations.


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


Re: Insurrection (was: ES4 draft: Object)

2008-03-11 Thread Dave Herman
Hi Mark, I agree with a number of your objections. I hope you don't mind 
if I try to distinguish between some of the points I agree with and 
disagree with.

 The current fad in language design is expressive static type systems.
 As a result, several recent type systems have grown eat their
 language. Java 1.5 is a particularly nasty example. Simple bits of
 Java code become so overwhelmed by complex type declarations as to
 obscure the logic of the code itself. Proposed ES4 suffers from the
 same disease, though it has not (yet) come down with as bad a case as
 Java.

I'd love for us to get past the points about popularity and fads. I know 
that static types are all the rage and that dynamic languages have 
consequently suffered in the court of popular opinion. I'm a member of 
the Scheme community so I feel it acutely.

But I'm skeptical of your comparison to Java 5. Java is a statically 
typed language that gained even more types. The ES4 proposal is a 
dynamic language with optional type annotations. These are there to help 
people when they feel that types would serve to document their code and 
type checking would help improve the robustness of their code and/or 
make the kinds of ad-hoc checking (hand-written assertions) cleaner. 
When people don't feel they add value, they don't have to use them.

In Java 5, you're locked in to complex type annotations and can't get 
out. An important design goal in the ES4 type system has been to make 
the relationship between typed and untyped code relaxed enough that this 
doesn't happen.

 Even ignoring ES4's type system, ES4 adds all the following
 abstraction mechanisms to those in ES3:
 * classes
 * packages
 * units
 * namespaces

I'm sympathetic-- I've always been uncomfortable with packages and 
namespaces. (My reaction to units was more hopeful, since the global 
object is so problematic in ES3, but I'm not yet up to speed on the 
proposal.)

 If instead classes, for example, were defined purely by syntactic
 expansion to the constructs in ES3.1, then classes would inherit the
 lexical nestability of the constructs they expand into. Even Java's
 classes are lexically nestable!

Nestability is a good design goal, and I'm glad you brought it up.

Syntactic expansion has many benefits, too, of course. I just want to 
point out the main pitfall in making classes syntactic sugar. One of the 
real problems with ES3 is the inability to make guarantees about any 
bindings except for lexical ones. With vanilla ES3 objects, there's no 
way to share information between (conceptual) modules of code and 
preserve the integrity of the container, unless you either a) hide the 
data in a closure or b) copy the data into a dummy container.

Classes, in addition to being a well-understood mechanism and the de 
facto style of the JS community, should help the programmer protect the 
integrity of their bindings. For example, a class declaration in ES4 
creates fixtures for its properties-- meaning that the programmer can 
rely on them not being deleted. The current ad hoc approaches in use in 
ES3 can't guarantee that, and manually using closures is too heavyweight.

That said, you've hinted at alternative approaches, perhaps with 
constructs desugaring to closures of some sort:

 The namespace mechanism seems motivated by a failure to appreciate the
 power available by modest extensions of simple lambda abstraction.

I'd certainly like to hear what you're thinking here.

 Why should we prefer foo::bar::baz?
 What is gained by having two mechanisms?

Fair criticisms (and I personally feel the namespace mechanism is one of 
the most deserving of criticism). Primarily, the purpose it's serving is 
a way to protect object properties with a key that you can then 
control via e.g. lexical hiding. The Foo.Bar.baz pattern in ES3 doesn't 
provide a way to hide such bindings.

 When I first read the overview, I was puzzled by the lack of
 uniformity between the types [int] and [int, String]. IIUC, the first
 represents the type of all arrays *all* of whose elements are ints.

That's not my understanding. IIRC, for a type [T1,...,Tn,Tn+1] there are 
required to be zero or more array elements of Tn+1. So [int] is the type 
of arrays with zero or more ints, and [int, String] is the type of 
arrays with an int at index 0 followed by zero or more Strings.

I'll grant that this is unconventional. But it's an attempt to make the 
type structure match actual usage in JS: people use arrays both as 
arrays and as tuples. So we have a type that accomodates the idiomatic 
usage of the language.

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


Re: ES4 draft: Object

2008-03-11 Thread Kris Zyp
  1) Remove the feature entirely from ES4 (as part of the judicious
  feature cuts process) until a more appropriate syntax is found

Setting dontEnum is immensely valuable as a framework developer. I realize
that is not a very technical argument, but controlling dontEnum is of more
value than many of the other features in ES4, and would certainly hope it is
not omitted.

 So long as setPropertyIsEnumerable is a method of Object.prototype, it
 raises the otherwise pointless question of the meaning of overriding
 it. At the last ES3.1 face-to-face, we agreed instead on the following
 static method on Object, as recorded at
 http://wiki.ecmascript.org/doku.php?id=es3.1:targeted_additions_to_array_string_object_date:

 -
 Object.dontEnum(object, memberName)

I realize I wasn't there (at the ES3.1 F2F, only called in), but why was
this discussed for ES3.1? I thought the page you are referencing was simply
items that hadn't been cleaned up yet, since it clearly does not subset ES4
(as I noted in my comments on that page). If we desire that this be a part
of ES3.1, it should be brought up as a proposal for ES4, so that ES3.1 can
safe subset it, rather than creating new divergent features for ES3.1.
Frankly, I like the idea of using Object.dontEnum(object, memberName),
that sounds great to me, but it should be an ES4 proposal first and should
not be considered for inclusion in ES3.1 unless and until accepted by ES4.
BTW, Another possible syntax could be:
Object.setAttribute(object, memberName,attributeFlag)
which could be used to set the dontEnum, readOnly, and dontDelete flags and
probably more closely follows the internal structure of implementations as
well.
Thanks,
Kris


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


Re: ES4 draft: Object

2008-03-11 Thread Yuh-Ruey Chen
Peter Hall wrote:
 Yuh-Ruey Chen [EMAIL PROTECTED] wrote:
   Which gets me back to the cognitive load issue. Even with a name like
   'hidden', they may think they may have to do some funky syntax like
   |obj.hidden::other_ns::prop| do hide a prop in another namespace.


 This was confusing me... How would you define a property to have a
 qualified name and be in the dontenum namespace at the same time? Or
 are namespaced properties non-enumerable anyway? (That would feel
 wrong to me..)
   

The latter. It is weird, I agree. But the enumerator can easily be 
customized, so I want the default enumerator be as non-magical as 
possible - and therefore, as simple as possible. In fact, I'm a bit 
bothered that propertyIsEnumerable is a method of Object yet can be 
rendered useless when changing the enumerator - along this line of 
reasoning, one would think that such a specific method shouldn't be a 
method of Object at all, but rather the enumerator itself.

 ES4
 doesn't currently have a way to express AND/OR namespace combinations.
   

Yeah, I vaguely remember some discussion concerning multiple namespaces 
per property a long time ago (maybe a year ago). It was rejected 
probably due to complexity.

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


Re: ES4 draft: Object

2008-03-11 Thread Peter Hall
  The latter. It is weird, I agree. But the enumerator can easily be
  customized, so I want the default enumerator be as non-magical as
  possible - and therefore, as simple as possible. In fact, I'm a bit
  bothered that propertyIsEnumerable is a method of Object yet can be
  rendered useless when changing the enumerator - along this line of
  reasoning, one would think that such a specific method shouldn't be a
  method of Object at all, but rather the enumerator itself.


So how would you go about enumerating the properties of an arbitrary
dynamic object, whose properties could be in namespaces?

  Yeah, I vaguely remember some discussion concerning multiple namespaces
  per property a long time ago (maybe a year ago). It was rejected
  probably due to complexity.

Not being able to combine them effectively makes many of the initial
proposal's use-cases useless, because two use-cases may arise
simultaneously when integrating two codebases, and be irreparably
conflicting.

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


Re: ES4 draft: Object

2008-03-11 Thread Brendan Eich
On Mar 11, 2008, at 1:14 AM, Maciej Stachowiak wrote:

 The optional second argument to make propertyIsEnumerable a setter has
 some practical problems:

 1) It violates the very strong norm that getter and setter functions
 are separate and have their own different arguments. It will make the
 feature harder to use and code using it harder to understand, to some
 extent.
 2) It makes it impossible to feature test for the ability to disable
 enumerability, compared to a separate setter.

I agree with these points.

 Against the argument that it is too risky compatibility-wise to add a
 new method to the object prototype (apparently the only reason things
 were done),

No, that was not the only reason. The other reason (it may be a bad  
reason, but I pointed it out in an earlier message to make it  
apparent): so calls passing two arguments would not cause ES3  
implementations to fail as would undetected calls to a new method.

But I agree that the numbered points you make are sufficient to  
reconsider the two-argument proposal that was accepted a while go.

Just for the es4-discuss list's information, I want to provide some  
historical context. the working group at that time had many large and  
small issues to grapple with, so we did not dedicate too much time to  
the Prototype Ajax library problem (wanting to set DontEnum on user- 
defined properties). We were not so much in favor of the _de minimus_  
second argument idea that was quickly settled on, as we were opposed  
to adding another method with a plain name to Object.prototype. And  
even that wasn't a strong objection, in light of namespaces (more  
below on that).

This was at the time very much small potatoes, which I for one am  
happy to revisit (I've already sketched a namespace-based  
alternative). It should not be used to impeach the entirely of the  
group's work.

 I propose that it is overblown. Mozilla has defined new
 methods and properties on all objects.

In 1998 or 1999, we added meta methods and properties,  
distinguished (after Python) by leading and trailing double underscores.

We haven't tried adding a plainly named property to Object.prototype  
in quite a while.

 We have copied some in Safari
 and seen no web compatibility issues, I assume Mozilla has not had any
 as well. Specifically, I am thinking of __defineSetter__,
 __defineGetter__, __lookupSetter__, __lookupGetter__, and __proto__.

These are all metaprogramming hooks, but so arguably is  
__setPropertyIsEnumerable__ -- so I agree with your reasoning here.

 Has any study been done on how many sites currently make use of the
 property names of a likely setter for propertyIsEnumerable?

We have not crawled the web looking for plain-named methods, but we  
have spidered for other patterns we proposed to change incompatibly,  
and the results are not decisive. For example, looking for attempts  
to rebind standard constructors found only a dead MSN .js file  
rebinding Error, but when we tried in Firefox 3 beta 2 to lock down  
the global bindings for Date, etc., we found many sites and web apps  
breaking. This is a different case, of course, but my point stands:  
searching the web is informative, but not decisive.

 Debate is only good.  I merely pointed out the obvious thing, namely
 that until there is an alternative proposal written up to deal with
 this issue, the current design stands unless the WG, as a group,
 decides to just get rid of it (leaving the problem it was designed
 to solve solution-less).

 Surely reviewing this spec is the appropriate time to revisit this
 issue.

Yes, and this list is the right place. It's pretty clear Lars agrees,  
and nothing he wrote cited above contradicts it. So let's discuss more.

 I'd like to propose the following three alternatives to the
 current proposal:

 1) Remove the feature entirely from ES4 (as part of the judicious
 feature cuts process) until a more appropriate syntax is found
 2) Replace two-argument form of propertyIsEnumerable with
 setPropertyIsEnumerable
 3) Replace two-argument form of propertyIsEnumerable with
 __setPropertyIsEnumerable__

 I think each of these options is so trivial as to not require a
 lengthy write-up.

 What is the process for the WG deciding whether to make one of these
 changes, or something else?

Arguing here in es4-discuss might be enough, if the argument makes  
progress and the participants reach a consensus.

 I like the idea of making non-public-namespaced properties be
 not-enumerable and getting rid of DontEnum.  We've talked loosely
 about it for a while.  But it's remained loose talk, it has never
 made it to the stage where it is a coherent proposal.

 I don't like syntax-based alternatives since they cannot be made to
 degrade gracefully in ES3 UAs.

I think that's a good point too, since as noted above it was one of  
the two reasons for the lame-duck two-argument proposal we've accepted.

/be

___
Es4-discuss 

Controlling DontEnum (was: ES4 draft: Object)

2008-03-11 Thread Brendan Eich
Here is a modest proposal based on Mark's and Maciej's messages:

Goal: A detectable method requiring no new syntax to set the DontEnum  
attribute on an existing property.

Goal: Avoid breaking any existing ES3 code that might depend on a  
plainly named method not being predefined.

Anti-goal: The ability to turn off DontEnum where it has been set on  
predefined properties.

Proposal: Add Object.prototype.__makePropertyNonEnumerable__(name),  
defined as if by:

 Object.prototype.__makePropertyNonEnumerable__ = function (name) {
 if (this has a direct property identified by name) {
 set the DontEnum attribute for this[name];
 return true;
 }
 return false;
 }

Note that if this has a direct property identified by name, but this 
[name] already has the DontEnum attribute, then the function returns  
true. The specification with prose of setting DontEnum would occur  
redundantly in this case, but it is not observable in ES3 or ES4 as  
proposed, so for simplicity I left out a test of DontEnum to avoid a  
redundant set.

The use of a __-bracketed name satisfies the second goal, but it  
would be a problem for Caja or similar. This is an issue where I  
would appreciate Mark's feedback.

Comments welcome.

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


Re: Controlling DontEnum (was: ES4 draft: Object)

2008-03-11 Thread Kris Zyp
 The use of a __-bracketed name satisfies the second goal, but it
 would be a problem for Caja or similar. This is an issue where I
 would appreciate Mark's feedback.

I can't speak for Mark, but it seems like it might actually be beneficial 
that unsecured code (regular ES4) would have the ability to set DontEnum and 
secured code (Secure ES, Cajoled Caja, ADsafe, or whatever) wouldn't have 
that capability.
+1
Kris 

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


Re: Controlling DontEnum (was: ES4 draft: Object)

2008-03-11 Thread Peter Hall
If there is no method to make a property enumerable again (which I now
agree is better not to exist) it feels somehow bad to be able to make
a property non-enumerable after its declaration.

Consider:

let a = {b:2, c:3};
for(let s in a){
 print(s); // b, c
}
a.__makePropertyNonEnumerable__(b);
for(let s in a){
 print(s); // c
}


It seems wrong that the code should run once one way, and then another
way, but there be no way back. It's not so much that I think there
should be a way back, but I'd rather that than this, which I consider
a weird situation. Also the double underscores are really ugly
syntax...

Perhaps you can't achieve this without new syntax, but the declarative
approach seems cleanest and not prone to this sort of anomaly. If new
syntax could be considered, an |enumerable| attribute, complemented by
a |!enumerable| attribute seems very clean.

type T = {enumerable a:int, b:int};
let t:T = {a:1, b:2}:T; // a is enumerable, b is not

let s = {a:1, !enumerable b:1}; // a is enumerable, b is not

class C {
  enumerable var p;
}


Peter


On Tue, Mar 11, 2008 at 7:45 PM, Brendan Eich [EMAIL PROTECTED] wrote:
 Here is a modest proposal based on Mark's and Maciej's messages:

  Goal: A detectable method requiring no new syntax to set the DontEnum
  attribute on an existing property.

  Goal: Avoid breaking any existing ES3 code that might depend on a
  plainly named method not being predefined.

  Anti-goal: The ability to turn off DontEnum where it has been set on
  predefined properties.

  Proposal: Add Object.prototype.__makePropertyNonEnumerable__(name),
  defined as if by:

  Object.prototype.__makePropertyNonEnumerable__ = function (name) {
  if (this has a direct property identified by name) {
  set the DontEnum attribute for this[name];
  return true;
  }
  return false;
  }

  Note that if this has a direct property identified by name, but this
  [name] already has the DontEnum attribute, then the function returns
  true. The specification with prose of setting DontEnum would occur
  redundantly in this case, but it is not observable in ES3 or ES4 as
  proposed, so for simplicity I left out a test of DontEnum to avoid a
  redundant set.

  The use of a __-bracketed name satisfies the second goal, but it
  would be a problem for Caja or similar. This is an issue where I
  would appreciate Mark's feedback.

  Comments welcome.

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

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


Re: Controlling DontEnum (was: ES4 draft: Object)

2008-03-11 Thread Mark Miller
On Tue, Mar 11, 2008 at 2:32 PM, Peter Hall [EMAIL PROTECTED] wrote:
  Perhaps you can't achieve this without new syntax, but the declarative
  approach seems cleanest and not prone to this sort of anomaly. If new
  syntax could be considered, an |enumerable| attribute, complemented by
  a |!enumerable| attribute seems very clean.

  type T = {enumerable a:int, b:int};
  let t:T = {a:1, b:2}:T; // a is enumerable, b is not

  let s = {a:1, !enumerable b:1}; // a is enumerable, b is not

  class C {
   enumerable var p;
  }


Hi Peter, I like the idea of a more declarative approach as well, if
one can be found. However, this proposal has two problems from our
perspective:

* It introduces new syntax, as you mention.

* It depends on the proposed ES4 type system which is unacceptable to
the ES3.1 effort. ES3.1 needs a way to express these integrity
constraints in the absence of ES4 types.

-- 
Text by me above is hereby placed in the public domain

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


Re: Controlling DontEnum (was: ES4 draft: Object)

2008-03-11 Thread Mark Miller
[+google-caja-discuss]

On Tue, Mar 11, 2008 at 12:53 PM, Kris Zyp [EMAIL PROTECTED] wrote:
  The use of a __-bracketed name satisfies the second goal, but it
   would be a problem for Caja or similar. This is an issue where I
   would appreciate Mark's feedback.

  I can't speak for Mark, but it seems like it might actually be beneficial
  that unsecured code (regular ES4) would have the ability to set DontEnum and
  secured code (Secure ES, Cajoled Caja, ADsafe, or whatever) wouldn't have
  that capability.
  +1
  Kris

I think Kris is right, but I'm not yet sure. I've forwarded this
thread to [EMAIL PROTECTED] for discussion of what
would be the best ways to support Caja's needs.

Nono of these issues are specific to DontEnum. They affect all other
integrity restriction attributes, such as ReadOnly, DontDelete, and
fixture (i.e., non-dynamic).

-- 
Text by me above is hereby placed in the public domain

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


Re: Controlling DontEnum (was: ES4 draft: Object)

2008-03-11 Thread Kris Zyp
 It seems wrong that the code should run once one way, and then another
 way, but there be no way back. It's not so much that I think there
 should be a way back, but I'd rather that than this, which I consider
 a weird situation.

Declarative is nice, but as mentioned before, it ignores one of the primary 
use cases: addition of non-enumerable properties to built-ins (by libraries, 
primarily).

 Also the double underscores are really ugly
 syntax...

That's the idea, no one is currently using such an ugly method ;).

Kris

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


Re: Controlling DontEnum (was: ES4 draft: Object)

2008-03-11 Thread Neil Mix

On Mar 11, 2008, at 5:16 PM, Kris Zyp wrote:

 Declarative is nice, but as mentioned before, it ignores one of the  
 primary
 use cases: addition of non-enumerable properties to built-ins (by  
 libraries,
 primarily).

I've read mention of the weirdness of the timing window between the  
property definition and it's marking as non-enumerable.  That combined  
with the above observation makes me wonder if this should really be  
obj.__setNonEnumerableProperty__(name, value);
___
Es4-discuss mailing list
Es4-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es4-discuss


Re: Controlling DontEnum (was: ES4 draft: Object)

2008-03-11 Thread Brendan Eich
On Mar 11, 2008, at 3:21 PM, Neil Mix wrote:

 On Mar 11, 2008, at 5:16 PM, Kris Zyp wrote:

 Declarative is nice, but as mentioned before, it ignores one of the
 primary
 use cases: addition of non-enumerable properties to built-ins (by
 libraries,
 primarily).

 I've read mention of the weirdness of the timing window between the
 property definition and it's marking as non-enumerable.  That combined
 with the above observation makes me wonder if this should really be
 obj.__setNonEnumerableProperty__(name, value);

+1

/be

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


Re: Controlling DontEnum (was: ES4 draft: Object)

2008-03-11 Thread Kris Zyp
 I've read mention of the weirdness of the timing window between the
 property definition and it's marking as non-enumerable.  That combined
 with the above observation makes me wonder if this should really be
 obj.__setNonEnumerableProperty__(name, value);

 +1
I like it too. Any chance that by setting the attribute at the same time of 
setting the property value, we could resurrect the possibility of setting 
other attributes as well (with a single method):

Object.prototype.__setPropertyWithAttributes__(name, value, dontEnum: 
boolean, readOnly: boolean, dontDelete: boolean);

And various proposed syntax like:
obj = {dontenum a: 1, const b: 2, var c: 3};

could be written:
obj = {};
obj.__setPropertyWithAttributes__(a,1,true); // property a is not 
enumerable

obj.__setPropertyWithAttributes__(b,2,false,true); // property b is 
readonly

obj.__setPropertyWithAttributes__(c,3,false,false,true); // propery c is 
permanent

I wonder if readonly and dontdelete are other attributes where there might 
be benefits derived from trusted code (regular ES3/4) being able to control, 
and untrusted code (ses, caja) not being able to control. I can't think of 
what those benefits might be, maybe another question for Mark or Doug to 
think on.

Kris 

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


RE: ES4 draft: Object

2008-03-10 Thread Lars Hansen
Draft 2 of the spec for the Object class.  Changelog near the beginning.

--lars
Title: The class "Object"




 The class Object 



NAME:   "The class 'Object'"
FILE:   spec/library/Object.html
CATEGORY:   Pre-defined classes (E262-3 Chapter 15)
SOURCES:REFERENCES [1], [2]
SPEC AUTHOR:Lars
DRAFT STATUS:   DRAFT 2 - 2008-03-10
REVIEWED AGAINST ES3:   YES
REVIEWED AGAINST ERRATA:YES
REVIEWED AGAINST BASE DOC:  YES
REVIEWED AGAINST PROPOSALS: YES
REVIEWED AGAINST CODE:  YES
IMPLEMENTATION STATUS:  ES4RI
TEST CASE STATUS:   ?


CHANGES SINCE DRAFT 1 (2008-03-05)

  * More elaborate status block above

  * Prototype methods do not delegate to the corresponding intrinsic
methods, but to shared private methods that are also called by the
intrinsic method.  In this fashion, prototype method behavior is
invariant of subclassing.

  * Introduction of a specification-only protocol helper::getClassName
for overriding class names for ES3 compatibility.

NOTES

  * The use of 'Private' instead of 'private' below is a workaround
for a bug in the reference implementation (#368).

  * The function 'helper::toEnumerableId' converts an arbitrary value
to a member of 'EnumerableId': int, uint, string, or Name.  It is
specified elsewhere but in general you can think of it as
converting any number to int or uint, leaving strings and Names
alone, and converting everything else to string.


REFERENCES

[1] [1] http:wiki.ecmascript.org/doku.php?id=proposals:enumerability
[2] builtins/Name.es in the ES4 RI



 The class Object is a dynamic non-final class that does not
subclass any other objects: it is the root of the class hierarchy.

 All values in ECMAScript except undefined and null are
instances of the class Object or one of its subclasses.

NOTE  Host objects may not be instances of Object or its
subclasses, but must to some extent behave as if they are (see Host objects).


Synopsis

The class Object provides this interface:


public dynamic class Object
{
public function Object(value=undefined) 
static meta function invoke(value=undefined) 

static public const length = 1

intrinsic function toString() : string 
intrinsic function toLocaleString() : string 
intrinsic function valueOf() : Object 
intrinsic function hasOwnProperty(name: EnumerableId): boolean 
intrinsic function isPrototypeOf(value): boolean 
intrinsic function propertyIsEnumerable(name: EnumerableId, flag: (boolean|undefined) = undefined): boolean 
}


 The Object prototype object provides these direct properties:

toString: function ()  ,
toLocaleString:   function ()  ,
valueOf:  function ()  ,
hasOwnProperty:   function (name)  ,
isPrototypeOf:function (value)  ,
propertyIsEnumerable: function (name, flag=undefined)  ,


 The Object prototype object is itself an instance of the class
Object, with the exception that the value of its [[Prototype]]
property is null.


Methods on the Object class object

newObject(value=)

Description  When the Object constructor is called with an argument
value (defaulting to undefined) as part of a new
_expression_, it transforms the value to an object in a way that
depends on the type of value.

Returns  The Object constructor returns an object (an instance of
Object or one of its subclasses, or a host object).

NOTE  The Object constructor is the only constructor function
defined on a class in the language whose result may be a value of a
different class than the one in which the constructor is defined.

Implementation  The Object constructor can't be expressed as a regular
ECMAScript constructor.  Instead it is presented below as a helper
function makeObject that the ECMAScript implementation will invoke
when it evaluates new Object.

 The helper function makeObject only is invoked on native ECMAScript
values.  If new Object is evaluated on a host object, then actions
are taken and a result is returned in an implementation dependent
manner that may depend on the host object.


helper function makeObject(value=undefined) {
switch type (value) {
case (s: string) {
return new String(s);
}
case (b: boolean) { 
return new Boolean(b);
}
case (n: (int|uint|double|decimal)) { 
return new Number(n);
}
case (x: (null|undefined)) { 
return magic::createObject();
}
case (o: Object) {
return o;
}
}
}



Object(value=)

Description  When the Object class object is called as a function with zero
or one arguments it performs a type conversion.

Returns  It returns the converted value.

Implementation

static meta function invoke(value=undefined)
new Object(value);



Methods on Object instances

 The intrinsic methods on Object instances delegate to private
methods that are also 

Re: ES4 draft: Object

2008-03-10 Thread liorean
On 10/03/2008, Lars Hansen [EMAIL PROTECTED] wrote:
 Draft 2 of the spec for the Object class.  Changelog near the beginning.

The draft HTML seems a little broken. There's amp;#x0085 in it early
on, later these appear raw in the source (which displays as an empty
square in Opera and IE8).

And near the end of the document you have
/p/p/p/p/p/p/p/p/p/p/p/p/p/p/p/p/p/p/p/p/p/p/p/p/p/p/p/p/p/p/p/p/p/p/p/p/p/p/p/p/p/p/p/p/p/p/p/p/p/p/p/p/p/p/p/p/p/p/p/p/p/p/p/p/p/p/p/p/p/p/div

Slightly broken conversion tool?
-- 
David liorean Andersson
___
Es4-discuss mailing list
Es4-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es4-discuss


Re: ES4 draft: Object

2008-03-10 Thread Yuh-Ruey Chen
Brendan Eich wrote:
 On Mar 9, 2008, at 3:01 PM, Yuh-Ruey Chen wrote:

  Brendan Eich wrote:
  ES3 code can't detect namespaces, so arguably shouldn't care if we
  were to implement DontEnum using an open namespace. But this could be
  a problem for mixed ES3 and ES4 scenarios where the ES4 code does
  introspect via Name objects and is surprised to find ES3 objects
  with qualified property names.
 
 
  I'm talking about how the enumerability (or lack thereof) of
  Object.prototype.* are determined. Or are prototype methods also not
  enumerable by default like fixtures?

 My reply was not meant to be an answer, but a question: should we  
 drop this dontenum-namespace idea because it will break ES3+ES4  
 mixtures where the ES4 code reflects on a property's namespace  
 qualifier by using a Name object?
   

  Does this included ES3-style prototype methods? And would it
  be possible to init a fixture to be enumerable?

 In the sketch I mailed, you didn't see any mention of fixtures --  
 IIRC you asked about them in reply. Just to explain what my proposal  
 was aiming to do: It seems to me that if we have to add a magic bit  
 back into the skinny is-it-enumerable decision tree, we may as well  
 keep DontEnum.

  And the RI does print
  it, so I'm not sure what you're talking about.

 The RI is (a) not normative (nothing apart from ES3+fixes is yet),  
 (b) based on a DontEnum attribute model, not on my proposal. Not sure  
 why you thought I was talking about it. I was making a new proposal.
   
Ok, that cleared things up a bit. I didn't realize you were making a 
proposal and asking questions based off it :) I thought you were 
mentioning how the RI was implemented today at the moment.

Can you elaborate on cases where ES4 code does introspect via Name 
objects and is surprised to find ES3 objects with qualified property 
names.? I can't think of any.

  BTW, what exactly is a fixture?

 That's a good question, and it seems the answer is not in the wiki.  
 Trying the trac:

 http://bugs.ecmascript.org/ticket/233

 which references the overview document.

 In ES3 terms, a fixture is a property with the DontDelete attribute set.

 But there's more to it than that, for reasons expanded on in #233 to  
 do with namespace lookup and early binding. And there is another case  
 that Lars pointed out recently to do with dynamic classes, but I'll  
 avoid trying to summarize it except to say that a fixture is a fixed  
 property that can't be deleted or shadowed.
   

Thanks, that's a good summary, though some of the commentary in the 
ticket was confusing (like lth's example - was x.toString decided to be 
ambiguous?).

  Is that the right design?
 
  dynamic class C {
   public var fixture;
   function C() { this.expando = 42; }
  }
  for (var i in new C)
   intrinsic::print(i);
 
  wouldn't you expect to see expando printed? Is it printed because
  the default namespace for expando is the public-default one? I
  believe it is not, in the current proposal and the RI. Rather, each
  class or package gets a nonce-named public namespace, different from
  every other such per-class or per-package public. IIRC package trumps
  class -- classes within a package share the package's nonce-named
  public namespace (Jeff, Lars, please correct me if I'm wrong).
 
 
  I meant non-expando vars and methods defined within the class,  
  whatever
  the terminology is used (I see 'fixture' thrown around everywhere), are
  not enumerable. So yes, expando should be printed.

  From your numbered steps above, step 3 must have been reached -- so  
 expando is in the public-public (null qualifier in Name object  
 reflection) namespace. Not in the class-C-public namespace. My  
 question is whether that is the right design choice.
   

Are they any particular disadvantages that you can think of? Maybe 
another ES4 designer can chime in here.

BTW, a bit off topic: if a class is defined in a namespace, are the 
properties of that class also defined in that namespace (instead of just 
public/class-public)? Namespaces aren't clearly specified in the wiki or 
the overview, the tickets are unorganized, and the RI tends to barf when 
it comes to them. Ugh, I feel Apple's pain when they complain that they 
don't know where to start...

  Are you saying that each
  property is defined in a class-specific public namespace, and
  therefore does not get enumerated? I would say that expando properties
  should be defined in the global public namespace, so that they would
  be enumerated.

 Ok, I like that. I'm not arguing a side, just showing the choice.  
 There may be other cases, though, where a class-public property name  
 might want to be enumerable. In such a case the step 2 you wrote  
 would need to elaborate its public test. But again, my proposal was  
 about enumerability, independent of fixture-ness.

 /be
   

Yeah, I asked whether it was possible to make a class-public property 
enumerable. And if so, I really 

Re: ES4 draft: Object

2008-03-10 Thread Waldemar Horwat
 intrinsic function propertyIsEnumerable(name: EnumerableId, flag: 
 (boolean|undefined) = undefined): boolean

I too find the second parameter here abhorrent.  Please find another way to 
solve it (Brendan's namespace idea maybe) or remove this feature altogether.


How does property lookup deal with properties indexed by numbers that are not 
int or uint?  toEnumerableId converts them to strings, but the Vector proposal 
indicated that vectors don't.

Waldemar

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


RE: ES4 draft: Object

2008-03-10 Thread Lars Hansen
 -Original Message-
 From: [EMAIL PROTECTED] 
 [mailto:[EMAIL PROTECTED] On Behalf Of liorean
 Sent: 10. mars 2008 17:52
 To: es4-discuss@mozilla.org
 Subject: Re: ES4 draft: Object
 
 On 10/03/2008, Lars Hansen [EMAIL PROTECTED] wrote:
  Draft 2 of the spec for the Object class.  Changelog near 
 the beginning.
 
 ~~intrinsic::toString ( )~~
 The intrinsic toString method returns the concatenation of 
 [, object, the class name of the object, and ].
 
 
 There should probably be a whitepace between object and the 
 class name, as is the case in the implementation.

There should.  Corrected.

 ~~intrinsic::valueOf ( )~~
 If the object is the result of calling the Object constructor 
 with a host object (Host objects), it is 
 implementation-defined whether valueOf returns its this value 
 or another value such as the host object originally passed to 
 the constructor.
 
 
 (Host objects) looks a bit weird like that. Should probably 
 be either (see Host objects) analogously to how you later 
 use (see HasProperty-defn) or reference style, [Host objects]

Corrected.

 ~~intrinsic::isPrototypeOf ( value )~~ The function 
 magic::getPrototype extracts the [[Prototype]] property from 
 the object. See magic:getPrototype.
 
 
 And here a reference to documentation elsewhere. Probably 
 should try to be consistent about how those look. I assume 
 these are going to be links in the finished spec?

The primary format of the final spec is word and/or pdf, so
I don't know about links there.  I hope that we can release 
an HTML version too, and obviously it would be good if there
could be good hyperlinking there.  I would like to promise
all of that but I am not going to do it.  However, there 
will at least be proper references to the sections that define
the magic functions.

In general the specification of the magic functions is somewhat
unstructured at present.  I appreciate this reminder about that :-)

--lars

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


RE: ES4 draft: Object

2008-03-10 Thread Lars Hansen
 -Original Message-
 From: Waldemar Horwat [mailto:[EMAIL PROTECTED] 
 Sent: 10. mars 2008 18:50
 To: Lars Hansen
 Cc: es4-discuss@mozilla.org
 Subject: Re: ES4 draft: Object
 
  intrinsic function propertyIsEnumerable(name: EnumerableId, flag: 
  (boolean|undefined) = undefined): boolean
 
 I too find the second parameter here abhorrent.  Please find 
 another way to solve it (Brendan's namespace idea maybe) or 
 remove this feature altogether.

The feature was approved by the WG and solves a practical problem.
If another way to solve this practical problem is proposed (in a
more structured form than in the ongoing discussion) and finds favor
with the WG, then fine -- of course we can replace it.  Until then,
this feature stays as it is until the WG can be convinced that it
needs to be removed.  Personally I think that it is ugly/abhorrent
is a weak basis on which to remove the current feature.

 How does property lookup deal with properties indexed by 
 numbers that are not int or uint?  toEnumerableId converts 
 them to strings, but the Vector proposal indicated that 
 vectors don't.

The intrinsic::hasOwnProperty and intrinsic::propertyIsEnumerable 
methods on Object require EnumerableId parameters, and no conversion
happens automatically when they are called (there should be no
automatic conversion to union types, even from a number to a number
in the type).  So programs trying to call the intrinsic methods on 
doubles (say) will receive errors.  This is true independent of
Vector.

The prototype methods inherited from Object perform conversions
explicitly, but can be overridden in Vector to prevent the 
conversion.  Ergo the hasOwnProperty and propertyIsEnumerable
methods on Vector should be able to handle arbitrary names,
and should return false for all property names that are
numbers not in the uint range -- if that's what we think is the
desired behavior.

That said, you raise a good point and I don't think the story is
fully coherent yet.  Certainly we don't have a working prototype
of this.

(And yet another point is that I expect that the int and uint types
are not going to be in the final language and that some of the
machinery in Object will have to be rethought as a consequence
of that change.)

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


RE: ES4 draft: Object

2008-03-10 Thread Lars Hansen
As far as I can see this is not a problem in the file I sent out, nor in
the one I received from the reflector.

What mailer are you using?

Anyone else see this?

--lars 

 -Original Message-
 From: [EMAIL PROTECTED] 
 [mailto:[EMAIL PROTECTED] On Behalf Of liorean
 Sent: 10. mars 2008 17:18
 To: es4-discuss@mozilla.org
 Subject: Re: ES4 draft: Object
 
 On 10/03/2008, Lars Hansen [EMAIL PROTECTED] wrote:
  Draft 2 of the spec for the Object class.  Changelog near 
 the beginning.
 
 The draft HTML seems a little broken. There's amp;#x0085 in 
 it early on, later these appear raw in the source (which 
 displays as an empty square in Opera and IE8).
 
 And near the end of the document you have 
 /p/p/p/p/p/p/p/p/p/p/p/p/p/p/p
 /p/p/p/p/p/p/p/p/p/p/p/p/p/p/p/p
 /p/p/p/p/p/p/p/p/p/p/p/p/p/p/p
 /p/p/p/p/p/p/p/p/p/p/p/p/p/p/p/p
 /p/p/p/p/p/p/p/p/div
 
 Slightly broken conversion tool?
 --
 David liorean Andersson
 ___
 Es4-discuss mailing list
 Es4-discuss@mozilla.org
 https://mail.mozilla.org/listinfo/es4-discuss
 
___
Es4-discuss mailing list
Es4-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es4-discuss


Re: ES4 draft: Object

2008-03-10 Thread liorean
On 11/03/2008, Lars Hansen [EMAIL PROTECTED] wrote:
 As far as I can see this is not a problem in the file I sent out, nor in
  the one I received from the reflector.

  What mailer are you using?

Gmail's web interface. And checking, it appears only using the View
link, not the Download link. So it appears to be GMail's fault.
-- 
David liorean Andersson
___
Es4-discuss mailing list
Es4-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es4-discuss


Re: ES4 draft: Object

2008-03-10 Thread Waldemar Horwat
Lars Hansen wrote:
 The feature was approved by the WG and solves a practical problem.
 If another way to solve this practical problem is proposed (in a
 more structured form than in the ongoing discussion) and finds favor
 with the WG, then fine -- of course we can replace it.  Until then,
 this feature stays as it is until the WG can be convinced that it
 needs to be removed.  Personally I think that it is ugly/abhorrent
 is a weak basis on which to remove the current feature.

We are the WG.  Are you saying that substantive discussions of your proposals 
are not welcome?  Not sure what the point of participating is if that's the 
case.

I'm dealing with a serious insurrection of folks who believe that the ES4 
working group has a bad attitude, based on Brendan's public comments and 
responses to issues like this one.  They're quite visible.

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


RE: ES4 draft: Object

2008-03-10 Thread Lars Hansen
 -Original Message-
 From: Waldemar Horwat [mailto:[EMAIL PROTECTED] 
 Sent: 10. mars 2008 19:40
 To: Lars Hansen
 Cc: es4-discuss@mozilla.org
 Subject: Re: ES4 draft: Object
 
 Lars Hansen wrote:
  The feature was approved by the WG and solves a practical problem.
  If another way to solve this practical problem is proposed 
 (in a more 
  structured form than in the ongoing discussion) and finds 
 favor with 
  the WG, then fine -- of course we can replace it.  Until then, this 
  feature stays as it is until the WG can be convinced that 
 it needs to 
  be removed.  Personally I think that it is ugly/abhorrent
  is a weak basis on which to remove the current feature.
 
 We are the WG.  Are you saying that substantive discussions 
 of your proposals are not welcome?  Not sure what the point 
 of participating is if that's the case.

Sorry, I didn't realize that I find it abhorrent qualified as
substantive discussion.  My fault.  Won't happen again.

 I'm dealing with a serious insurrection of folks who believe 
 that the ES4 working group has a bad attitude, based on 
 Brendan's public comments and responses to issues like this 
 one.  They're quite visible.

Debate is only good.  I merely pointed out the obvious thing, namely
that until there is an alternative proposal written up to deal with
this issue, the current design stands unless the WG, as a group,
decides to just get rid of it (leaving the problem it was designed
to solve solution-less).

I like the idea of making non-public-namespaced properties be
not-enumerable and getting rid of DontEnum.  We've talked loosely
about it for a while.  But it's remained loose talk, it has never
made it to the stage where it is a coherent proposal.

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


Re: ES4 draft: Object

2008-03-10 Thread Robert Sayre
On Mon, Mar 10, 2008 at 11:11 PM, Jeff Dyer [EMAIL PROTECTED] wrote:

  it would
  be helpful to follow up with possible solutions or at least insight into
  what makes it abhorrent (your word).

FWIW, I also did not grasp the force of the objection, and would like
to understand better.


  No doubt the WG has attitude. There are strong personalities involved and we
  have had our share of knocks. Sometimes that shows.

It can probably show less if everyone makes an effort. The WG has most
of the implementors one could hope for, so this opportunity shouldn't
be wasted.

-- 

Robert Sayre

I would have written a shorter letter, but I did not have the time.
___
Es4-discuss mailing list
Es4-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es4-discuss


Insurrection (was: ES4 draft: Object)

2008-03-10 Thread Mark Miller
On Mon, Mar 10, 2008 at 8:11 PM, Jeff Dyer [EMAIL PROTECTED] wrote:
  On 3/10/08 5:40 PM, Waldemar Horwat wrote:
   I'm dealing with a serious insurrection of folks who believe that the ES4
   working group has a bad attitude, based on Brendan's public comments and
   responses to issues like this one.  They're quite visible.

  No doubt the WG has attitude. There are strong personalities involved and we
  have had our share of knocks. Sometimes that shows. You of all people should
  understand why. But please do share more about the insurrection you are
  dealing with. Maybe then we can be more sensitive.

I hope Waldemar is not counting me as a member of that insurrection.
My problem with the ES4 proposal has nothing to do with the attitude
and personality of the ES4 WG members. Quite the opposite. I have come
to like and respect those of you I have come to know. Since Brendan is
mentioned explicitly above, I'll mention the high regard I've come to
have for Brendan in particular. I have also enjoyed every encounter I
have had with the group as a whole.

A vague disclaimer is nobody's friend.
   --Willow Rosenberg, Buffy episode: The Initiative

True friends stab you in the front.
  --Oscar Wilde

I do not wish to offend anyone. I know I am speaking harshly about
work that many here have invested in heavily. But in the interests of
clarity, I will speak plainly below. I hope the discussion will
continue from here with its customary civility.

I have serious problems with the proposed ES4 *design* -- to the point
that I have a hard time taking it seriously. I hope and expect that it
will be crushed by its own weight. I fear that it might become widely
adopted, and we will instead be crushed by it. In any case, I have
decided that my energies as a new EcmaScript committee member are
better spent on the ES3.1 WG, as the other members of that WG seem
similarly inclined to look for the *smallest* reasonable language that
meets our goals
http://wiki.ecmascript.org/doku.php?id=es3.1:es3.1_goals.

The current fad in language design is expressive static type systems.
As a result, several recent type systems have grown eat their
language. Java 1.5 is a particularly nasty example. Simple bits of
Java code become so overwhelmed by complex type declarations as to
obscure the logic of the code itself. Proposed ES4 suffers from the
same disease, though it has not (yet) come down with as bad a case as
Java.

I applaud Jeff's and Lars' recent document of proposed deferrals from
proposed ES4. After reading this document carefully, I was then able
to reread the proposed ES4 overview document and imagine the smaller
language they are suggesting. This language I still believe to be too
large, but at least it would now be small enough to be worth
criticizing.

ES3 has several abstraction mechanisms:
* lambda abstraction, which it gets approximately as right as Scheme!
* objects as a generalization of records, which has some pros and cons
* prototype-based sharing of common behavior, which is used almost
exclusively by JavaScript programmers to express only class-like
patterns.

Altogether, ES3 has many virtues and many problems. One of its great
virtues is its almost perfect support for lexical nesting. Virtually
any thisless construct that could appear at top level can also appear
within a nested lexical context with the same meaning. ES3 also avoids
the CommonLisp trap of multiple namespaces, instead siding with
Scheme's single namespace approach.

Even ignoring ES4's type system, ES4 adds all the following
abstraction mechanisms to those in ES3:
* classes
* packages
* units
* namespaces

I have not heard anyone explain any of these as syntactic sugar that
could be expanded away into remaining language elements, so I fear all
of these would be fundamental. Worse, several of these constructs can
only appear at top level, and so destroy the almost perfect lexical
nestability enjoyed by ES3.

If instead classes, for example, were defined purely by syntactic
expansion to the constructs in ES3.1, then classes would inherit the
lexical nestability of the constructs they expand into. Even Java's
classes are lexically nestable!

The namespace mechanism seems motivated by a failure to appreciate the
power available by modest extensions of simple lambda abstraction. ES3
already provides some of the features for supporting such modest
extensions: Several libraries (such as YUI) already use naming paths
such as foo.bar.baz. This is supported by ES3's lexical scoping
combined with its extensible records and its property lookup notation.
Why should we prefer foo::bar::baz?
ES3 already suffers from having two bottom values -- null and
undefined -- with no general consensus of when one should use which.
How are we to regard mixed naming paths such as foo.bar::baz? When
should one use a record as a naming container vs a namespace? What is
gained by having two mechanisms?


I could go on and on about ES4's types gone 

Re: ES4 draft: Object

2008-03-10 Thread Ian Hickson
On Mon, 10 Mar 2008, Waldemar Horwat wrote:

  intrinsic function propertyIsEnumerable(name: EnumerableId, flag: 
  (boolean|undefined) = undefined): boolean
 
 I too find the second parameter here abhorrent.  Please find another way 
 to solve it (Brendan's namespace idea maybe) or remove this feature 
 altogether.

I believe what Waldemar is saying is that the method has a name that 
implies that it is a getter, but that the proposal has it working as a 
setter. This has a number of disadvantages. Primarily, it is unintuitive 
for authors. This makes code maintenance significantly more complicated, 
as readers of code tend to assume that getters cannot have side effects. 
This leads directly to bugs.

We should design ES4 in a way that someone who is experienced with other 
programming languages, but who has never learnt ES4, can by and large 
correctly guess what any arbitrary ES4 code is doing. In this particular 
case, we have failed to achieve that.

-- 
Ian Hickson   U+1047E)\._.,--,'``.fL
http://ln.hixie.ch/   U+263A/,   _.. \   _\  ;`._ ,.
Things that are impossible just take longer.   `._.-(,_..'--(,_..'`-.;.'
___
Es4-discuss mailing list
Es4-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es4-discuss


Re: ES4 draft: Object

2008-03-09 Thread Yuh-Ruey Chen
Brendan Eich wrote:
 On Mar 8, 2008, at 1:16 PM, Yuh-Ruey Chen wrote:
  But doesn't DontEnum still have to be there for ES3 objects? How else
  would you prevent the enumeration of ES3 builtin methods, e.g.
  Object.prototype.toString()? Or is there some more open namespace  
  magic
  that I'm unware of?

 ES3 code can't detect namespaces, so arguably shouldn't care if we  
 were to implement DontEnum using an open namespace. But this could be  
 a problem for mixed ES3 and ES4 scenarios where the ES4 code does  
 introspect via Name objects and is surprised to find ES3 objects  
 with qualified property names.
   

I'm talking about how the enumerability (or lack thereof) of 
Object.prototype.* are determined. Or are prototype methods also not 
enumerable by default like fixtures?

Let me get this straight. The rules of enumerability are:
1) If a property is a fixture, it's not enumerable. BTW, what exactly is 
a fixture? Does this included ES3-style prototype methods? And would it 
be possible to init a fixture to be enumerable?
2) If a property is not in the public namespace, it's not enumerable.
3) Otherwise, it is enumerable.
4) No hidden DontEnum attribute.

Are we trying to simplify this to the last three rules using some 
namespace voodoo to handle the fixture rule? I'm confused.

  Well, I think the only overlap is that public-in-class-context methods
  (or any method really) default to be non-public in terms of  
  enumerability

 Is that the right design?

 dynamic class C {
  public var fixture;
  function C() { this.expando = 42; }
 }
 for (var i in new C)
  intrinsic::print(i);

 wouldn't you expect to see expando printed? Is it printed because  
 the default namespace for expando is the public-default one? I  
 believe it is not, in the current proposal and the RI. Rather, each  
 class or package gets a nonce-named public namespace, different from  
 every other such per-class or per-package public. IIRC package trumps  
 class -- classes within a package share the package's nonce-named  
 public namespace (Jeff, Lars, please correct me if I'm wrong).
   

I meant non-expando vars and methods defined within the class, whatever 
the terminology is used (I see 'fixture' thrown around everywhere), are 
not enumerable. So yes, expando should be printed. And the RI does print 
it, so I'm not sure what you're talking about. Are you saying that each 
property is defined in a class-specific public namespace, and 
therefore does not get enumerated? I would say that expando properties 
should be defined in the global public namespace, so that they would 
be enumerated.

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


RE: ES4 draft: Object

2008-03-08 Thread Lars Hansen
 -Original Message-
 From: [EMAIL PROTECTED] 
 [mailto:[EMAIL PROTECTED] On Behalf Of zwetan
 Sent: 7. mars 2008 19:28
 To: Brendan Eich
 Cc: es4-discuss@mozilla.org es4-discuss; Yuh-Ruey Chen; Erik Arvidsson
 Subject: Re: ES4 draft: Object
 
 why not have a global utility function, maybe in the magic namespace

The magic namespace (like informational and helper) is a
specification artifact, it does not exist in an implementation.

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


Re: ES4 draft: Object

2008-03-08 Thread P T Withington
On 2008-03-07, at 22:43 EST, Brendan Eich wrote:

 The goal is to find the minimum amount of mutating meta-programming
 sharpness for this make certain properties non-enumerable tool. If
 it can be done with a one-time namespace qualification step, that  
 wins.

A few comments:

I am confused.  I guess I thought everything was in a namespace, just  
that there is a default namespace that things with no explicit  
namespace are in.  Which makes me wonder how the namespace/not- 
enumerable proposal will really work.

I think it is absolutely right that fixtures are not enumerable.  And  
a bug that things that would have been fixtures if you had them are  
enumerable in es3.  It seems to me that for-in/enumerability are all  
about Maps, maybe now that we have Maps (and classes with fixtures),  
we don't have to worry about enumerability in Objects so much.

Finally, for debugging, I would want to be able to find all the  
properties of an object, non-enumerable and fixtures included.  Will  
there be a way to introspect like that?
___
Es4-discuss mailing list
Es4-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es4-discuss


RE: ES4 draft: Object

2008-03-08 Thread Lars Hansen
 -Original Message-
 From: [EMAIL PROTECTED] 
 [mailto:[EMAIL PROTECTED] On Behalf Of P T Withington
 Sent: 8. mars 2008 10:10
 To: Brendan Eich
 Cc: zwetan; es4-discuss@mozilla.org es4-discuss; Yuh-Ruey 
 Chen; Erik Arvidsson
 Subject: Re: ES4 draft: Object
 
 On 2008-03-07, at 22:43 EST, Brendan Eich wrote:
 
  The goal is to find the minimum amount of mutating meta-programming 
  sharpness for this make certain properties non-enumerable 
 tool. If 
  it can be done with a one-time namespace qualification step, that 
  wins.
 
 A few comments:
 
 I am confused.  I guess I thought everything was in a 
 namespace, just that there is a default namespace that things 
 with no explicit namespace are in.  Which makes me wonder how 
 the namespace/not- enumerable proposal will really work.

Some namespaces are public and distinguished thereby, properties
in these namespaces would be enumerated.  One of the public 
namespaces is the default namespace that things with no explicit
namespace are in.  (We're still fine-tuning the details of that.)

 Finally, for debugging, I would want to be able to find all 
 the properties of an object, non-enumerable and fixtures 
 included.  Will there be a way to introspect like that?

Not certain yet.  Being able to just do it is a security 
concern if you think namespaces are in part about hiding access
to private data.  (Debugging facilities in the language are
not a good idea if there is any chance at all that some of the
code in a program may be hostile.  We have to make a choice
about that when we write the spec for the reflection mechanism.)

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


Re: ES4 draft: Object

2008-03-08 Thread Yuh-Ruey Chen
Brendan Eich wrote:
  - Users may think this dontenum namespace is magical and yet another
  thing to keep in mind, when it really just relies on the namespace  
  trick
  you mentioned. With the introduction of classes and namespaces, the
  rules of enumerability are already more complex, so this adds to the
  cognitive load slightly.

 Slightly, but it takes away the magic DontEnum attribute, formerly  
 hogged by the specification and magic predefined objects.
   

But doesn't DontEnum still have to be there for ES3 objects? How else 
would you prevent the enumeration of ES3 builtin methods, e.g. 
Object.prototype.toString()? Or is there some more open namespace magic 
that I'm unware of?

  BTW, if setPropertyIsEnumerable() is added,
  would it be possible to make fixtures enumerable? Enumerability is
  orthogonal to static analysis (which fixtures are meant to help with),
  so I don't see why not.

 This gets to the heart of the public vs. public-in-context-of-class- 
 or-package issue. We need to sort this out to find out exactly how  
 orthogonal enumerability is, as well as decide how flexible it should  
 be.
   

Well, I think the only overlap is that public-in-class-context methods 
(or any method really) default to be non-public in terms of enumerability

  - The name sucks :p

 Indeed. How about 'hidden' or 'nonEnumerable'?
   

I'd prefer 'hidden', since 'nonEnumerable' implies more strongly that a 
prop needs to be in that namespace to not be enumerable, when that's not 
the case.

Which gets me back to the cognitive load issue. Even with a name like 
'hidden', they may think they may have to do some funky syntax like 
|obj.hidden::other_ns::prop| do hide a prop in another namespace.

While we're on the topic of namespaces, I read in the ES4 overview: In 
addition, the names internal, public, protected, and private denote 
namespace values, but the values depend on the context of the use. As 
the wiki doesn't talk about this, and the online spec is 
inaccessible/outdated, can you elaborate on this? I wonder if 'private' 
could be used somehow for enumerability.

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


Re: ES4 draft: Object

2008-03-07 Thread Andrea Giammarchi
Garrett Smith wrote:
 obj = {dontenum length: 10} );
 vs.

 obj = {length: 10};
 obj.propertyIsEnumerable(length, false);

 Which is more ugly?

 Garrett
Of course I prefere the first line but these two cases are different.
I wonder if a builtin method will not cause more problems instead of 
avoiding them.

What I mean is what is the expected behaviour in this case?

Object.prototype.propertyIsEnumerable(length, false);
// some stuff ... and then ...  
Object.prototype.propertyIsEnumerable(length, true);


I think Object.prototype is the perfect case scenario where this built in 
method could cause more chaos than ever, while the dontenum in declaration 
makes sense specially when I write my own object and/or prototoype and I would 
like that no one will be able to change my not enumerable property. So I guess 
built in method is error/conflicts/problems prone while the first one is quite 
safer (and at the same time, I do like to know if others add some 
Object.prototype, both to avoid conflicts, problems, and errors)

These are only my 5 cents to this interesting discussion.

Kind Regards




-- 
-
Zend Certified Engineer
ActionScript 2.0 Certified Developer
Web 2.0 Specialist
-
Cel. +39 338 7621067

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


Re: ES4 draft: Object

2008-03-07 Thread Yuh-Ruey Chen
Brendan Eich wrote:
 To avoid injecting a public name into Object.prototype, we could put  
 a new setPropertyIsEnumerable (yechh) name in the __ES4__  
 namespace. Then there's no breaking change. We do this already, of  
 course, but not for property attribute fiddling.
   

Since enumerability only applies to for-in, how about the iterator 
namespace? Object.prototype.iterator::setPropertyIsEnumerable(prop, 
enable). For consistency, you could also have 
Object.prototype.iterator::isPropertyEnumerable(prop) which delegates to 
Object.prototype.isPropertyEnumerable(prop).

 An alternative we've discussed, which Ian also brought up: add a  
 keyword for declaring DontEnum properties.

This dontenum modifier can be used in addition to the method for 
convenience - it would make class declarations cleaner.

But despite that, I think dontenum is inelegant. Its only effect would 
be on the default enumerator, which is only one iterator, and AFAIK is 
not special at all. IMO, it isn't worth the bloat. If there was a way to 
define such modifiers within script, then I think the dontenum modifier 
would be nice. If such a capability is planned for a future ES edition, 
then I think dontenum is fine.

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


Re: ES4 draft: Object

2008-03-07 Thread Brendan Eich
On Mar 7, 2008, at 1:14 PM, Yuh-Ruey Chen wrote:

 Brendan Eich wrote:
 To avoid injecting a public name into Object.prototype, we could put
 a new setPropertyIsEnumerable (yechh) name in the __ES4__
 namespace. Then there's no breaking change. We do this already, of
 course, but not for property attribute fiddling.


 Since enumerability only applies to for-in, how about the iterator
 namespace?

Good suggestion.

Here's something I wrote a while ago (minor edits to update for  
context) that attempts to subsume enumerability under namespacing:

If we say enumeration considers only public non-DontEnum properties,  
then DontEnum is always true for namespaced props. Mixing DontEnum  
magic into the

obj = {var dontDel: 42, const RO_AND_DD: foo}

idea is wrong -- these should be public and enumerable as other  
properties in object initialisers are, by default. But we are *this*  
close to eliminating an independent DontEnum attribute. The problem  
is how to express public + DontEnum.

Suppose we had a predefined, open namespace, say dontenum  (surely  
not the best name). If you write

obj = {dontenum::cant_see_me: 33}

then

for (i in obj) print(i)

shows nothing. But

obj.cant_see_me

works, because dontenum is always open. No more need for an  
orthogonal DontEnum attribute.

Instead of

obj.propertyIsEnumerable('i_want_to_hide', false)

users would just say

obj.dontenum::i_want_to_hide = ...

(typically obj is a prototype object and ... is a function). The  
setter mode (second boolean arg) of propertyIsEnumerable is ugly  
(everyone says so, no one denies). It's arguably hard to use (because  
verbose). It's racy for users who have to call it after creating a  
property (there's a window in which the property is enumerable -- not  
a threading race per se, more low-level bug habitat and needless  
worry). It's a burden on implementations that want immutable  
attributes for props.

On the down side, you can't just add

obj.dontenum::foo = function () {...}

to ES3 code that runs in ES3-only browsers, as you could with the  
propertyIsEnumerable hack. We should in any case design for the long  
run.

Note that any namespace would hide a property from enumeration;  
dontenum is not magic in that sense, only in that it is predefined  
and open by default (again, its name is a strawman).

For the long run, rationalizing dontenum via namespaces seems good to  
me.

 Object.prototype.iterator::setPropertyIsEnumerable(prop,
 enable). For consistency, you could also have
 Object.prototype.iterator::isPropertyEnumerable(prop) which  
 delegates to
 Object.prototype.isPropertyEnumerable(prop).

Clever relocation of is in the predicate names ;-). We're probably  
stuck with propertyIsEnumerable.

 An alternative we've discussed, which Ian also brought up: add a
 keyword for declaring DontEnum properties.

 This dontenum modifier can be used in addition to the method for
 convenience - it would make class declarations cleaner.

True of a namespace already, note.

 But despite that, I think dontenum is inelegant. Its only effect would
 be on the default enumerator, which is only one iterator, and AFAIK is
 not special at all. IMO, it isn't worth the bloat. If there was a  
 way to
 define such modifiers within script, then I think the dontenum  
 modifier
 would be nice. If such a capability is planned for a future ES  
 edition,
 then I think dontenum is fine.

What do you think of the only-public-properties-are-enumeable idea?

Obvious problem to be solved: public means several things: no  
namespace (backward compatible) vs. public in this package or  
class. We should discuss this more.

/be

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


RE: ES4 draft: Object

2008-03-06 Thread Lars Hansen
 -Original Message-
 From: [EMAIL PROTECTED] 
 [mailto:[EMAIL PROTECTED] On Behalf Of Brendan Eich
 Sent: 5. mars 2008 19:19
 To: Erik Arvidsson
 Cc: es4-discuss@mozilla.org es4-discuss
 Subject: Re: ES4 draft: Object
 
 To avoid injecting a public name into Object.prototype, we 
 could put a new setPropertyIsEnumerable (yechh) name in the 
 __ES4__ namespace. Then there's no breaking change. We do 
 this already, of course, but not for property attribute fiddling.

Right, it comes up from time to time.  Using __ES4__ here would set
a precedent that might not be the best.

 An alternative we've discussed, which Ian also brought up: 
 add a keyword for declaring DontEnum properties. It turns out 
 the full combination of property attributes is not 
 interesting. We have const for DontDelete+ReadOnly (ReadOnly 
 without DontDelete guarantees nothing, is worthless) 
 including in object initialisers:
 
 obj = {const PI: 22/7}; // Ohio legislature once so legislated
 
 We have (I hope it got filed) a ticket asking for DontDelete 
 by itself via var in object initialisers:
 
 obj = {var x: mutate me, but you can't delete me!}

Not filed in the Trac to my knowledge, but not forgotten.

 DontEnum is orthogonal but clear by default for binding and 
 assigning forms in ES3. It is set for built-ins, generally 
 speaking (some odd exceptions that I recall in the Error 
 objects -- I was not around much for ES3, although I did the 
 work in Netscape 4 that fed into it!).

The text of E262-3 does not reveal anything unusual about the
Error objects, as far as I can see.

 So, rather than add an ugly dontenum keyword that would be 
 seldom used, the group preferred a built-in method. But this 
 may have been a minor mistake. For those interested, here's 
 the full rationale as I remember it:
 
 Besides avoiding adding anything with a plain name to 
 Object.prototype, the appeal (if you can call it that) of 
 extending propertyIsEnumerable with an optional second 
 argument lies in the ability to call it with two arguments in 
 an ES3 implementation. That won't have any effect, but it 
 won't break callin code in ES3 implementations either.
 
 Thus Ajax libraries such as Prototype (if it still does this) 
 could add calls to turn off enumerability of properties the 
 library sets on standard prototypes, and then those 
 properties would disappear from for-in loop enumerations in 
 ES4 implementations.
 
 Mainly we do not expect the ability to turn off enumeration 
 of a given property to be a frequent programmer task, so we 
 did not want to add a new method if we could piggy-back on an 
 existing Object.prototype method. For library authors, we 
 wanted something that failed soft in ES3. And yeah, we knew 
 it was ugly, but propertyIsEnumerable is already ugly already.

Also, a declarative form is of uncertain value, since the object
that receives the new property whose attr must be set, already
exists.  Thus if there is some sort of new keyword form it needs
to be associated with the assignment somehow.

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


RE: ES4 draft: Object

2008-03-06 Thread Lars Hansen
 -Original Message-
 From: [EMAIL PROTECTED] 
 [mailto:[EMAIL PROTECTED] On Behalf Of Brendan Eich
 Sent: 6. mars 2008 18:04
 To: Garrett Smith
 Cc: es4-discuss@mozilla.org es4-discuss; Erik Arvidsson
 Subject: Re: ES4 draft: Object
 
 
 Remember that fixtures declared in classes are not enumerable, which  
 is the right default for all the native (built-in is better, since  
 these can be and are increasingly self-hosted) objects' properties.

Agreed native is misnomer now.  I've adopted predefined (or
pre-defined depending on my mood) instead of built-in but this is
something that will be cleaned up in the editorial process pretty soon.

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


ES4 draft: Object

2008-03-05 Thread Lars Hansen
This is the draft for the Object class.  It's very similar to the Object
object in ES3, the only addition (to my knowledge) is the extra
parameter to propertyIsEnumerable.  And of course the specification
formalism is new.

Please comment.

--lars
Title: The class "Object"




 The class Object 



FILE:   spec/library/Object.html
DRAFT STATUS:   DRAFT 1 - 2008-03-05
REVIEWED AGAINST ES3:   YES
REVIEWED AGAINST ERRATA:YES
REVIEWED AGAINST BASE DOC:  YES
REVIEWED AGAINST PROPOSALS: YES
REVIEWED AGAINST CODE:  YES



 The class Object is a dynamic non-final class that does not
subclass any other objects: it is the root of the class hierarchy.

 All values in ECMAScript except undefined and null are
instances of the class Object or one of its subclasses.

NOTE  Host objects may not be instances of Object or its
subclasses, but must to some extent behave as if they are (see Host objects).


Synopsis

The class Object provides this interface:


public dynamic class Object
{
public function Object(value=undefined) 
static meta function invoke(value=undefined) 

static public const length = 1

intrinsic function toString() : string 
intrinsic function toLocaleString() : string 
intrinsic function valueOf() : Object 
intrinsic function hasOwnProperty(name: EnumerableId): boolean 
intrinsic function isPrototypeOf(obj): boolean 
intrinsic function propertyIsEnumerable(name: EnumerableId, flag: (boolean|undefined) = undefined): boolean 
}


 The Object prototype object provides these direct properties:

toString: function ()  ,
toLocaleString:   function ()  ,
valueOf:  function ()  ,
hasOwnProperty:   function (V)  ,
isPrototypeOf:function (V)  ,
propertyIsEnumerable: function (name, flag=undefined)  ,


 The Object prototype object is itself an instance of the class
Object, with the exception that the value of its [[Prototype]]
property is null.


Methods on the Object class object

newObject(value=)

Description  When the Object constructor is called with an argument
value (defaulting to undefined) as part of a new
_expression_, it transforms the value to an object in a way that
depends on the type of value.

Returns  The Object constructor returns an object (an instance of
Object or one of its subclasses, or a host object).

NOTE  The Object constructor is the only constructor function
defined on a class in the language whose result may be a value of a
different class than the one in which the constructor is defined.

Implementation  The Object constructor can't be expressed as a regular
ECMAScript constructor.  Instead it is presented below as a helper
function makeObject that the ECMAScript implementation will invoke
when it evaluates new Object.

 The helper function makeObject only is invoked on native ECMAScript
values.  If new Object is evaluated on a host object, then actions
are taken and a result is returned in an implementation dependent
manner that may depend on the host object.


helper function makeObject(value=undefined) {
switch type (value) {
case (s: string) {
return new String(s);
}
case (b: boolean) { 
return new Boolean(b);
}
case (n: (int|uint|double|decimal)) { 
return new Number(n);
}
case (x: (null|undefined)) { 
return magic::createObject();
}
case (o: Object) {
return o;
}
}
}



Object(value=)

Description  When the Object class object is called as a function with zero
or one arguments it performs a type conversion.

Returns  It returns the converted value.

Implementation

static meta function invoke(value=undefined)
new Object(value);



Methods on Object instances

intrinsic::toString()

Description  The intrinsic toString method converts the this object
to a string.

Returns  The intrinsic toString method returns the concatenation of
"[", "object", the class name of the object, and "]".

Implementation

intrinsic function toString() : string
"[object " + magic::getClassName(this) + "]";


 The function magic::getClassName extracts the class name
from the object.  See magic:getClassName.


intrinsic::toLocaleString()

Description  The intrinsic toLocaleString method calls the public
toString method on the this object.

NOTE  This method is provided to give all objects a generic
toLocaleString interface, even though not all may use it.
Currently, Array, Number, and Date provide their own
locale-sensitive toLocaleString methods.

NOTE  The first parameter to this function is likely to be used in a
future version of this standard; it is recommended that
implementations do not use this parameter position for anything else.

Returns  The intrinsic toLocaleString method returns a string.

Implementation

intrinsic function toLocaleString() : string
this.toString();





intrinsic::valueOf()

Description  The intrinsic valueOf method returns its 

Re: ES4 draft: Object

2008-03-05 Thread Erik Arvidsson
We (Google) find setting the [[DontEnum]] flag with
propertyIsEnumerable(name, flag) to be quite ugly.  I can't find any
references to why the setter was tagged along onto the getter in this
way?  Is there a reason why we don't want
setPropertyIsEnumerable(name, flag) instead of overloading the getter?

2008/3/5 Lars Hansen [EMAIL PROTECTED]:
 This is the draft for the Object class.  It's very similar to the Object
  object in ES3, the only addition (to my knowledge) is the extra
  parameter to propertyIsEnumerable.  And of course the specification
  formalism is new.

  Please comment.

  --lars

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





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


Re: ES4 draft: Object

2008-03-05 Thread Brendan Eich
On Mar 5, 2008, at 5:04 PM, Erik Arvidsson wrote:

 We (Google) find setting the [[DontEnum]] flag with
 propertyIsEnumerable(name, flag) to be quite ugly.  I can't find any
 references to why the setter was tagged along onto the getter in this
 way?  Is there a reason why we don't want
 setPropertyIsEnumerable(name, flag) instead of overloading the getter?

Adding any properties to Object.prototype at this point is difficult.  
You may break object-detection tests. Is it worth the risk?

/be

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


RE: ES4 draft: Object

2008-03-05 Thread Lars Hansen
 -Original Message-
 From: Erik Arvidsson [mailto:[EMAIL PROTECTED] 
 Sent: 5. mars 2008 17:04
 To: Lars Hansen
 Cc: es4-discuss@mozilla.org
 Subject: Re: ES4 draft: Object
 
 We (Google) find setting the [[DontEnum]] flag with 
 propertyIsEnumerable(name, flag) to be quite ugly.

Can't argue with that.

 I can't 
 find any references to why the setter was tagged along onto 
 the getter in this way?  Is there a reason why we don't want 
 setPropertyIsEnumerable(name, flag) instead of overloading the getter?

It was felt, and I think it is still felt, that it is dangerous
to introduce new names on the Object prototype, because the
risk of clashes with code on the web is too great.  As the problem
that is solved by the overloading is really worth solving, the
ugliness of the solution seemed to be acceptable.

--lars

 
 2008/3/5 Lars Hansen [EMAIL PROTECTED]:
  This is the draft for the Object class.  It's very similar to the 
  Object  object in ES3, the only addition (to my knowledge) is the 
  extra  parameter to propertyIsEnumerable.  And of course the 
  specification  formalism is new.
 
   Please comment.
 
   --lars
 
  ___
   Es4-discuss mailing list
   Es4-discuss@mozilla.org
   https://mail.mozilla.org/listinfo/es4-discuss
 
 
 
 
 
 --
 erik
 
___
Es4-discuss mailing list
Es4-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es4-discuss


Re: ES4 draft: Object

2008-03-05 Thread Erik Arvidsson
I'm not sure it is such a big issue since the new method would be
[[DontEnum]] but I'm willing to let this rest.

The reason why I don't think it is that a big risk is that a lot of
people still use Array instead of Object for associative arrays and
I don't think adding the array extras introduced any problems.
Brendan, did you get any bug reports on Spidermonkey when array extras
was added?

On Wed, Mar 5, 2008 at 17:19, Brendan Eich [EMAIL PROTECTED] wrote:
 On Mar 5, 2008, at 5:04 PM, Erik Arvidsson wrote:

   We (Google) find setting the [[DontEnum]] flag with
   propertyIsEnumerable(name, flag) to be quite ugly.  I can't find any
   references to why the setter was tagged along onto the getter in this
   way?  Is there a reason why we don't want
   setPropertyIsEnumerable(name, flag) instead of overloading the getter?

  Adding any properties to Object.prototype at this point is difficult.
  You may break object-detection tests. Is it worth the risk?

  /be





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


Re: ES4 draft: Object

2008-03-05 Thread Brendan Eich
Hixie argued strongly on IRC today for something that does not  
overload set with get -- this seems to be the heart of the ugly  
objection, although there are other things to dislike about both the  
form and function of propertyIsEnumerable (it does not consider  
prototypes, as for-in does; its name is overlong and it violates  
standard naming conventions for is method).

To avoid injecting a public name into Object.prototype, we could put  
a new setPropertyIsEnumerable (yechh) name in the __ES4__  
namespace. Then there's no breaking change. We do this already, of  
course, but not for property attribute fiddling.

An alternative we've discussed, which Ian also brought up: add a  
keyword for declaring DontEnum properties. It turns out the full  
combination of property attributes is not interesting. We have const  
for DontDelete+ReadOnly (ReadOnly without DontDelete guarantees  
nothing, is worthless) including in object initialisers:

obj = {const PI: 22/7}; // Ohio legislature once so legislated

We have (I hope it got filed) a ticket asking for DontDelete by  
itself via var in object initialisers:

obj = {var x: mutate me, but you can't delete me!}

DontEnum is orthogonal but clear by default for binding and assigning  
forms in ES3. It is set for built-ins, generally speaking (some odd  
exceptions that I recall in the Error objects -- I was not around  
much for ES3, although I did the work in Netscape 4 that fed into it!).

So, rather than add an ugly dontenum keyword that would be seldom  
used, the group preferred a built-in method. But this may have been a  
minor mistake. For those interested, here's the full rationale as I  
remember it:

Besides avoiding adding anything with a plain name to  
Object.prototype, the appeal (if you can call it that) of extending  
propertyIsEnumerable with an optional second argument lies in the  
ability to call it with two arguments in an ES3 implementation. That  
won't have any effect, but it won't break callin code in ES3  
implementations either.

Thus Ajax libraries such as Prototype (if it still does this) could  
add calls to turn off enumerability of properties the library sets on  
standard prototypes, and then those properties would disappear from  
for-in loop enumerations in ES4 implementations.

Mainly we do not expect the ability to turn off enumeration of a  
given property to be a frequent programmer task, so we did not want  
to add a new method if we could piggy-back on an existing  
Object.prototype method. For library authors, we wanted something  
that failed soft in ES3. And yeah, we knew it was ugly, but  
propertyIsEnumerable is already ugly already.

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