A read/write __proto__ that can vanish

2008-07-16 Thread Ingvar von Schoultz
Some people yearn hotly for __proto__, preferrably writable if
at all possible, while others point to problems with security
and software privacy.

I get the impression that this could be solved by adding a fourth
flag among the property flags Enumerable, Writable and Flexible.
There might be a flag called Visible, so you could make __proto__
apparently vanish by setting Visible to false.

As an added bonus, this solution would let code hide the prototype
property on constructors if desired.

Personally I'd love to see it defined in such a way that I could
set prototype inheritance in a simple, straightforward way at the
beginning of a constructor function:

 function $MyConstructor()
 {  this.proto = MySuperInstance;
 // Here you can hide proto if desired.
 ...
 }

If a visible proto is standardized, the name should be proto, not
__proto__, in my opinion. The underscores indicate nonstandard.

-- 
Ingvar von Schoultz

--- (My quirky use of capitals in code comes from my opinion that
reserved and predefined words should all start with lowercase, and
user-defined should all start with uppercase, because this will easily
and elegantly prevent a host of name-collision problems when things
like programming languages are upgraded with new labels.)
___
Es4-discuss mailing list
Es4-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es4-discuss


Re: A read/write __proto__ that can vanish

2008-07-16 Thread Brendan Eich
On Jul 16, 2008, at 10:29 AM, Ingvar von Schoultz wrote:

 Some people yearn hotly for __proto__, preferrably writable if
 at all possible, while others point to problems with security
 and software privacy.

I wrote recently that __proto__ should be viewed as call/cc without  
macros for common use-case (and average users) -- too sharp and low- 
level a tool for a language like JS.

 I get the impression that this could be solved by adding a fourth
 flag among the property flags Enumerable, Writable and Flexible.
 There might be a flag called Visible, so you could make __proto__
 apparently vanish by setting Visible to false.

There's no point in Visible if the property could be deleted  
altogether. What would be the difference? Note that a proto or  
__proto__ property reflecting [[Prototype]] is *not* the same as the  
internal [[Prototype]] property, which would always be visible in  
the sense of checked by [[Get]], [[Put]], etc.

We should not add property attributes that can mutate lightly. The  
motivation for __proto__ is suspect (I argue, base on our experience  
-- and I perpetrated __proto__ a long time ago). The need for Visible  
is non-existent IMHO, while the costs and ramifications of another  
single-bit attribute, one that causes the property to appear to be  
deleted, are undesirable.

Visibility control over names is an important topic, but it can't be  
served by a single-bit attribute. ES4 as proposed has namespaces to  
serve (among other use-cases) the cheap and easily expressed private  
members use-case. That's not this __proto__ case, which anyway  
depends on a suspect predicate (the need for __proto__). Better to  
settle the predicate issue first, and avoid adding general mechanism  
prematurely.

/be

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


RE: A read/write __proto__ that can vanish

2008-07-16 Thread Allen Wirfs-Brock
Personally, I don't that the internal [[Prototype]] property should reify as 
an actual property of the object.  It's really a more fundamental aspect of 
objectness than regular properties.  From that perspective, if you want to 
control access to it, it should probably be done as a flag on the object 
itself, much as the ES3.1 proposal does with the [[Extensible]] property.


-Original Message-
From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf Of Ingvar von 
Schoultz
Sent: Wednesday, July 16, 2008 10:29 AM
To: [EMAIL PROTECTED]; es4-discuss@mozilla.org
Subject: A read/write __proto__ that can vanish

Some people yearn hotly for __proto__, preferrably writable if
at all possible, while others point to problems with security
and software privacy.

I get the impression that this could be solved by adding a fourth
flag among the property flags Enumerable, Writable and Flexible.
There might be a flag called Visible, so you could make __proto__
apparently vanish by setting Visible to false.

As an added bonus, this solution would let code hide the prototype
property on constructors if desired.

Personally I'd love to see it defined in such a way that I could
set prototype inheritance in a simple, straightforward way at the
beginning of a constructor function:

 function $MyConstructor()
 {  this.proto = MySuperInstance;
 // Here you can hide proto if desired.
 ...
 }

If a visible proto is standardized, the name should be proto, not
__proto__, in my opinion. The underscores indicate nonstandard.

--
Ingvar von Schoultz

--- (My quirky use of capitals in code comes from my opinion that
reserved and predefined words should all start with lowercase, and
user-defined should all start with uppercase, because this will easily
and elegantly prevent a host of name-collision problems when things
like programming languages are upgraded with new labels.)
___
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: A read/write __proto__ that can vanish

2008-07-16 Thread Waldemar Horwat
Ingvar von Schoultz wrote:
 Some people yearn hotly for __proto__, preferrably writable if
 at all possible, while others point to problems with security
 and software privacy.
 
 I get the impression that this could be solved by adding a fourth
 flag among the property flags Enumerable, Writable and Flexible.
 There might be a flag called Visible, so you could make __proto__
 apparently vanish by setting Visible to false.

Adding switches like this is making code too complicated and will result in 
plenty of arguments about whether a particular class should have the switch 
turned on or off.  Often the classes you want to use will have it set the wrong 
way, leading to more balkanization of libraries.  In the committee we've 
already spent too much time discussing which properties should be enumerable, 
dontDelete, etc., and we still get those wrong at times.

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


Re: A read/write __proto__ that can vanish

2008-07-16 Thread Ingvar von Schoultz
Brendan Eich wrote:
 There's no point in Visible if the property could be deleted  
 altogether. What would be the difference?

Oops! Sorry! Lacking low-level insight I didn't think of that.

So my idea has no bearing at all on the inherent problems, much
less solved them. Too bad.

 That's not this __proto__ case, which anyway  
 depends on a suspect predicate (the need for __proto__). Better to  
 settle the predicate issue first, and avoid adding general mechanism  
 prematurely.

I think the only situation where I repeatedly feel a real,
serious need for something like a writable __proto__ is
the one I showed. Specifying inheritance is too spread out
and too intricate. Most of all I want the constructor to
define its own inheritance, not some outside code. Having
to set .prototype in an unrelated expression outside, with
the constructor reduced to a powerless bystander, feels like
I'm writing a goto. It's too unstructured.

Is your objection to __proto__ similar to this? Is __proto__
an inheritance goto? If that's the kind of problem it creates
I agree that it doesn't belong in this language.

If that's the case, would a writable __proto__ become well-
structured if it could be accessed only from inside the
constructor, and not by any other code? That's the only
way I'd use it anyway.

I'd love to have constructors that could write to their
[[Prototype]]. But if that isn't possible I'd be almost
as happy if we simply had the option to set both the
prototype and its constructor property in one compound
statement:

 function $MyConstructor()
 prototype MySuperInstance
 {  ...
 }

For me this would generally be the best arrangement, and
I suppose it's the same for most people. Not having analyzed
all the details, it /seems/ to me that the ideal would be
that the above syntax lock and hide [[Prototype]], while a
different syntax for exotic use would allow the constructor
added freedom.

-- 
Ingvar von Schoultz

--- (My quirky use of capitals in code comes from my opinion that
reserved and predefined words should all start with lowercase, and
user-defined should all start with uppercase, because this will easily
and elegantly prevent a host of name-collision problems when things
like programming languages are upgraded with new labels.)
___
Es4-discuss mailing list
Es4-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es4-discuss


Re: 13.2.2 [[Construct]], constructor, and [[Class]] (was __proto__)

2007-12-14 Thread Brendan Eich

On Dec 14, 2007, at 12:50 PM, P T Withington wrote:


On 2007-09-23, at 14:14 EDT, Brendan Eich wrote:


The reason for the original prototype-owned constructor was to afford
a back-pointer from prototype to constructor function without
imposing a per-instance property (which could be optimized to be
shared where possible, overridden where desired -- but at some cost
in implementation complexity).

I'm not convinced it's worth changing this for ES4. Anyway it is very
late to have a new proposal -- we are finalizing proposals next week
at the face-to-face meeting.


So, was nothing done about this?  We're starting to work on an es4
back-end for our stuff and running into this issue.  We can make sure
all our constructors give each instance a constructor slot (and we can
smash the class prototype.constructor to point to the superclass) as
we do for our es3 back end; but I was really hoping for a cleaner
solution in es4.


Nothing's changed, no proposal that avoids per-instance overhead or  
more complicated implementation strategies to avoid that. There's  
also an entrainment hazard, not huge but non-zero risk of introducing  
leaks into existing web apps if we entrain the constructor where the  
web app code intentionally clears prototype.constructor (which is  
read/write).


The constructor property is and always was intended to be a property  
of the prototype, not of each instance. Changing that now is hard.  
The merits are not compelling enough IMHO.



Is there some other way in es4 that from an instance one can navigate
up the superclass chain?  Can I say:

   super.constructor

perhaps, to find my class's superclass?


For a class C, C.prototype.constructor is indeed C. But super does  
not work that way -- it's used for invoking the super-class  
constructor, rather:


 class B { var x;function B(x) : x=x {} }
 new B(2).x
2
 class D extends B { var y; function D(x,y) : y=y, super(x) {} }
 d = new D(3,4)
[object D]
 d.x
3
 d.y
4

To reflect on inheritance and other relations, use the meta-objects  
interfaces:


http://wiki.ecmascript.org/doku.php?id=proposals:meta_objects

Given class C:

let Ctype = reflect::typeOf(C);
for (let Csup in Ctype.superTypes()) {
// Csup is a base class or interface of C here
}

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


Re: __proto__

2007-09-26 Thread P T Withington
On 2007-09-22, at 17:52 EDT, liorean wrote:

 Which could be done, of course, it should be a simple thing to add
 that in the algorithm for [[Construct]]. But then we have the question
 of what to do with constructors that return other objects than that
 set up by steps 1 through 5 of the [[Construct]] algorithm. A
 constructor can return other objects, you know. You'd have to decide
 whether this property should be set up prior to step 6 in the
 algorithm or subsequent to step 7. If prior, only the original object
 that was created in step 1 gets it, if subsequent, return values get
 it even if they are not the same as the original object.

Dylan has a rule that the constructor must return an object that is a  
subtype of the constructor.  If that were enforced, I would see no  
reason to reset the constructor property of the returned object.

 Actually, I think this would be a nice and simple fix to ES3 that
 probably wouldn't hurt much code out there.

Agreed.  As I mentioned elsewhere in this thread, we do this manually  
in our framework for now.

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


Re: 13.2.2 [[Construct]], constructor, and [[Class]] (was __proto__)

2007-09-23 Thread Garrett Smith
On 9/22/07, liorean [EMAIL PROTECTED] wrote:
 On 22/09/2007, Garrett Smith [EMAIL PROTECTED] wrote:
  What I've found is that it's always giving wrong constructor property
  with inheritance chains.
 
  A -- B -- C
  c = (new C).constructor;// A
 

snip I meant an enumerable superclass property!

 You get that if you do the following:

 function A(){}
 function B(){}
 B.prototype=new A;
 function C(){}
 C.prototype=new B;

 Because if you do that, you replace the prototype containing the
 original constructor property  (e.g. a reference back to the function
 C) with an instance of another constructor (e.g. B), but that instance
 doesn't have the constructor property that the original prototype had.
 If you want to keep the constructor properties, you need to do that
 manually. (With the obvious result that then the constructor property
 will be enumerable. Which can be changed through adding a call on
 propertyIsEnumerable in ES4.)

Ah, sorry, I said a few things wrong!

1. constructor is DontEnum.13.2 - http://bclary.com/2004/11/07/#a-13.2
(It's the user-defined superclass property that is enumerable.)

1. The constructor property should be on the object instance *created*
by the function.

snip

  How about a constructor property on the function instance?

2. (new function(){}).constructor should be Function.

But you understood what I meant even though I said it wrong. I meant
to say that the object instance's constructor property should be the
Function that new was called on.

 Which could be done, of course, it should be a simple thing to add
 that in the algorithm for [[Construct]]. But then we have the question
 of what to do with constructors that return other objects than that
 set up by steps 1 through 5 of the [[Construct]] algorithm. A
 constructor can return other objects, you know.
snip

In ES4, it is a syntax error to specify a result type of a
constructor. If someone is using new F, the constructor property of
the instance should be F.

(new F).constructor; // should be F.

The constructor property should match the [[Construct]] property. This
should happen right before the prototype. Here's 13.2.2 with my edits:

13.2.2 [[Construct]]

When the [[Construct]] property for a Function object F is called,
the following steps are taken:

1. Create a new native ECMAScript object.
2. Set the [[Class]] property of Result(1) to Object.
-- ∆ set the [[Class]] of o to reflect the name F --

3. Get the value of the prototype property of F.

   --  Set the constructor property of Result(1) to F  --

4. If Result(3) is an object, set the [[Prototype]] property of
Result(1) to Result(3).
5. If Result(3) is not an object, set the [[Prototype]] property
of Result(1) to the original Object prototype object as described in
15.2.3.1.
6. Invoke the [[Call]] property of F, providing Result(1) as the
this value and providing the argument list passed into [[Construct]]
as the argument values.
7. If Type(Result(6)) is Object then return Result(6).
8. Return Result(1).

∆ Note: Although allowed in ES3, Functions used as constructors should
not return a value. (reword)

 probably wouldn't hurt much code out there.

What could it hurt? What would get broken?

Benefits:
1) can crawl up the constructors without having to bake the
functionality into your library,
2) Doesn't force clients to use a non-standard fix.
3) [[class]] matches constructor property

The flip side of (2) is that if it stays, a client of a library that
fixes the constructor property may have objects created by an
in-house or another third party library where the library doesn't fix
the constructor property.

The constructor property is modifiable, but you cant count on third
party libraries using the same modification (I call it a nonstandard
fix) to the constructor property.

ES4 ref impl seems a bit off:

 (new function F(){}).constructor
[function Function]
 new Date(9e9).constructor
[class Class]
 1['constructor']
[class Class]


It appears that es4 ref impl has the correct result for instancof on primitives

All are true in ES4 and false in ES3:
true instanceof Boolean
oo instanceof String
2 instanceof Number
null instanceof Object
NaN instanceof Number
Number.Infinity instanceof Number

I think the change is correct. if typeof b == boolean, b instanceof
boolean seems like it must be true.

I would like to understand why it was not working right in ES3-, if
someone can explain.

Garrett

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


Re: 13.2.2 [[Construct]], constructor, and [[Class]] (was __proto__)

2007-09-23 Thread liorean
  On 23/09/2007, Garrett Smith [EMAIL PROTECTED] wrote:
  2. (new function(){}).constructor should be Function.

 On Sep 23, 2007, at 8:59 AM, liorean wrote:
  I agree. And in ES3 it is, unless the function either:

On 23/09/2007, Brendan Eich [EMAIL PROTECTED] wrote:
 No:

 js (new function(){}).constructor
 function () {
 }
 js function C(){}
 js new C().constructor
 function C() {
 }

Ah, my mistake there, was thinking of (function(){}).constructor for a
moment there.


 in no case is the value of (new function(){}).constructor Function.

Thinking about it with the new keyword in mind, I just realise that
what Garrett suggested makes no sense anyway - the function object is
the constructor. The function object is an instance of Function, but
the resulting object is an instance of the function object. Making the
object have Function as it's constructor property breaks the
prototype-constructor relationship.



  On 23/09/2007, Garrett Smith [EMAIL PROTECTED] wrote:
  It appears that es4 ref impl has the correct result for instancof
  on primitives

 On Sep 23, 2007, at 8:59 AM, liorean wrote:
  A bugfix, IIRC.

On 23/09/2007, Brendan Eich [EMAIL PROTECTED] wrote:
 Incompatbile enough that we are not taking the chance -- we are
 changing this to match ES1-3, and to avoid boolean : Boolean etc.

Sad to hear that, but I guess compatibility will have to rule here.
-- 
David liorean Andersson
___
Es4-discuss mailing list
Es4-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es4-discuss


Re: 13.2.2 [[Construct]], constructor, and [[Class]] (was __proto__)

2007-09-23 Thread Garrett Smith
On 9/23/07, liorean [EMAIL PROTECTED] wrote:
   On 23/09/2007, Garrett Smith [EMAIL PROTECTED] wrote:
   2. (new function(){}).constructor should be Function.

  On Sep 23, 2007, at 8:59 AM, liorean wrote:
   I agree. And in ES3 it is, unless the function either:

 On 23/09/2007, Brendan Eich [EMAIL PROTECTED] wrote:
  No:
 
  js (new function(){}).constructor
  function () {
  }
  js function C(){}
  js new C().constructor
  function C() {
  }

 Ah, my mistake there, was thinking of (function(){}).constructor for a
 moment there.


  in no case is the value of (new function(){}).constructor Function.

It shouldn't be, but it is in OSX Ref Impl. (I did not build this).

js (new function(){}).constructor
[function Function]

 Thinking about it with the new keyword in mind, I just realise that
 what Garrett suggested makes no sense anyway - the function object is
 the constructor. The function object is an instance of Function, but
 the resulting object is an instance of the function object. Making the
 object have Function as it's constructor property breaks the
 prototype-constructor relationship.


Correctly corrected.

In the following example:

function F(){}
F.prototype.constructor = F;
F.prototype.propertyIsEnumerable(constructor); // false, it's set to
{DontEnum} in step 10. Object.prototype.
F.prototype.constructor === F; //true
F.prototype = {
constructor : F
};
F.prototype.constructor === F; // false
F.prototype.propertyIsEnumerable(constructor); // true, now
F.prototype is an object

F.prototype is assigned to a new Object. The new Object goes through
[[construct]] getting its [[class]] property to Object. Object
instances get the constructor property from Object.prototype. The only
exception being prototype properties of Function objects, where the
constructor is flagged DontEnum.

The constructor property of an object doesn't reflect the constructor
that called it.

Garrett


   On 23/09/2007, Garrett Smith [EMAIL PROTECTED] wrote:
   It appears that es4 ref impl has the correct result for instancof
   on primitives

  On Sep 23, 2007, at 8:59 AM, liorean wrote:
   A bugfix, IIRC.

 On 23/09/2007, Brendan Eich [EMAIL PROTECTED] wrote:
  Incompatbile enough that we are not taking the chance -- we are
  changing this to match ES1-3, and to avoid boolean : Boolean etc.

 Sad to hear that, but I guess compatibility will have to rule here.
So it's going back, to (true instanceof Boolean == false), huh ?

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


Re: 13.2.2 [[Construct]], constructor, and [[Class]] (was __proto__)

2007-09-23 Thread liorean
On 23/09/2007, Garrett Smith [EMAIL PROTECTED] wrote:
 Function objects get a non-enumerable constructor.
 function F(){};
 F.constructor === Function; // true
 F.prototype.hasOwnProperty('constructor'); //true
 F.prototype.propertyIsEnumerable(constructor); // false.

Of course.

 Object instances don't, unless it's a prototype object created by 
 [[construct]]
 (new F).constructor === F.constructor; // true. Undesirable

Wrong, it's false.
(new F).constructor === F.constructor; // = false
(new F).constructor === F.prototype.constructor; // = true


 This works fine for shallow inheritance
 Objects don't get a constructor

In what way do you mean they don't? Their constructor is the Object
object, as you show next:

 ({}).constructor === Object.prototype.constructor; // True.


  On 23/09/2007, Garrett Smith [EMAIL PROTECTED] wrote:
   1. The constructor property should be on the object instance *created*
   by the function.

 On 9/23/07, liorean [EMAIL PROTECTED] wrote:
  That argument I agree with. It should be on the instance and not the 
  prototype.

On 23/09/2007, Garrett Smith [EMAIL PROTECTED] wrote:
 Which is different from the way built ins work, but seems OK.

Well, at least if you want to make sense out of the prototypal
inheritance scheme. The built ins are all single level IIRC,k and
don't need to set up their prototype relationship in user code. A
prototype system that didn't just clobber the old prototype when
setting up prototype chains maybe could have done it better. But that
won't happen in ECMAScript.



  On 23/09/2007, Garrett Smith [EMAIL PROTECTED] wrote:
   2. (new function(){}).constructor should be Function.

 On 9/23/07, liorean [EMAIL PROTECTED] wrote:
  I agree.

Actually I don't agree here, see my reply to Brendan earlier.


  And in ES3 it is, unless the function either:

And I was thinking of (function(){}).constructor here, not (new
function(){}).constructor, when I said in ES3 it is. It isn't, which
is proper since the object is constructed by the anonymous function
object, not the Function object.



On 23/09/2007, Garrett Smith [EMAIL PROTECTED] wrote:
 When there is an anonymous constructor, we have the ability to get at
 the constructor property.

I don't see this as a problem - the constructor property should be the
function that actually constructed the object. Since ES3 allows any
value (except eval, I think) to be assigned to any variable (except
read only ones and those with special setters), the difference between
function declarations and function expressions is that declarations
are *by default* accessible through a variable name only, and function
expressions are *by default* accessible through the return value of
the expression only. There's no way to actually tell a function
derived from a function expression and a function derived from a
function declaration apart after the fact. (Well, except for that
function expressions make the name optional.)

So, if we want to be able to get at constructors at all, we can't
distinguish between how functions are derived - either we provide the
functionality, or we don't.


 function Animation(element){
var looped = 0;
var e = element;

function construct() {
 this.loopCount = function() {
  return looped;
 }
 this.loop = function() {
  looped++;
 }
}
return new construct();
  }

 new new Animation().constructor().constructor; // construct

Sure. It's a closure, it exposes a property it's told to expose. (If
you use the new keyword, that it exposes the function object as the
constructor property of the constructed object should be expected.)
You can do this without the new keyword if you want to not expose the
function object, or use the delete keyword to explicitly remove it.




 On 9/23/07, liorean [EMAIL PROTECTED] wrote:
  A disagreement of terminology I think. If you ask me, a function
  instance is a function object. When using a function instance as a
  constructor, you create an instance of that constructor (== function
  instance) which is a plain, ordinary, mundane, normal,
  run-of-the-mill, typical object. (Agh, ran out of synonyms!)

On 23/09/2007, Garrett Smith [EMAIL PROTECTED] wrote:
 F is a Function instance
 f is a function instance

 The terminology is confusing.

F is an instance of Function
f is an instance of F

Function is a function object
F is a function object
f is an object


As I see it, the meaning of function instance is an object that is
function-like, in other words a function object or a special host
object (like Function.prototype, which is a function but not an
instance of Function).
-- 
David liorean Andersson
___
Es4-discuss mailing list
Es4-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es4-discuss


Re: 13.2.2 [[Construct]], constructor, and [[Class]] (was __proto__)

2007-09-23 Thread Garrett Smith
On 9/23/07, liorean [EMAIL PROTECTED] wrote:
 On 23/09/2007, Garrett Smith [EMAIL PROTECTED] wrote:
  Function objects get a non-enumerable constructor.
  function F(){};
  F.constructor === Function; // true
  F.prototype.hasOwnProperty('constructor'); //true
  F.prototype.propertyIsEnumerable(constructor); // false.

 Of course.

F.prototype = {
constructor : F
}
F.prototype.propertyIsEnumerable(constructor);


  Object instances don't, unless it's a prototype object created by 
  [[construct]]
  (new F).constructor === F.constructor; // true. Undesirable

 Wrong, it's false.
 (new F).constructor === F.constructor; // = false
 (new F).constructor === F.prototype.constructor; // = true


Right.

  This works fine for shallow inheritance
  Objects don't get a constructor

 In what way do you mean they don't? Their constructor is the Object
 object, as you show next:

  ({}).constructor === Object.prototype.constructor; // True.


({}).hasOwnProperty(constructor); //false.

{} is the same as new Object;

new Object goes through [[construct]]

The instance does not get a constructor property. No object instance
does. Well, none except objects that are prototype properties that
went through [[construct]]. This is confusing and makes the language
less clear to developers. It confuses me.



   On 23/09/2007, Garrett Smith [EMAIL PROTECTED] wrote:
1. The constructor property should be on the object instance *created*
by the function.

  On 9/23/07, liorean [EMAIL PROTECTED] wrote:
   That argument I agree with. It should be on the instance and not the 
   prototype.

 On 23/09/2007, Garrett Smith [EMAIL PROTECTED] wrote:
  Which is different from the way built ins work, but seems OK.

 Well, at least if you want to make sense out of the prototypal
 inheritance scheme. The built ins are all single level IIRC,k and
 don't need to set up their prototype relationship in user code. A
 prototype system that didn't just clobber the old prototype when
 setting up prototype chains maybe could have done it better. But that
 won't happen in ECMAScript.


I don't see a problem.

var d = new Date;
d.constructor == Date; // true
d.hasOwnProperty('constructor'); // false

The proposed change would have the result of:
d.hasOwnProperty('constructor'); // true
d.isPropertyEnumerable('constructor'); // false


   On 23/09/2007, Garrett Smith [EMAIL PROTECTED] wrote:
2. (new function(){}).constructor should be Function.

  On 9/23/07, liorean [EMAIL PROTECTED] wrote:
   I agree.

 Actually I don't agree here, see my reply to Brendan earlier.
Right.




 On 23/09/2007, Garrett Smith [EMAIL PROTECTED] wrote:
  When there is an anonymous constructor, we have the ability to get at
  the constructor property.

 I don't see this as a problem -

Right. Whether or not the Function object has a name is irrelevant.


the constructor property should be the
 function that actually constructed the object.

Exactly. That's what I'm talking about.


The fact that (new C).constructor === A; is true, by default of the
language, is counterintuitive.

[[construct]] gives a function instance a special prototype property.
That prototype property is an object, but not just an object, a
special object -- one that has a constructor property that is
specially flagged DontEnum. You lose that property the moment you give
a prototype property to F. Well, if the prototype property you give to
F is created through [[construct]], you don't.

You have to be careful.

F=function(){};
new F().constructor == F; // true.
F.propertyIsEnumerable(prototype); //true, Futhark and JScript say false.
F.prototype = {};
new F().constructor == F; // false.
F.prototype.constructor = F;
F.prototype.propertyIsEnumerable(constructor); // true, JScript says false.

var complaint = false;
for( var prop in new F )
   complaint = true;

if(!complaint) alert('failure');
The browser support is pretty inconsistent, too.


 So, if we want to be able to get at constructors at all, we can't
 distinguish between how functions are derived - either we provide the
 functionality, or we don't.

function expression/declaration, new Function -- the constructor
should all be Function

function FF(){}
FF.constructor === Function; // true
(Function()).constructor === Function; // true.
(new Function()).constructor === Function; // true.

The Object instance that is created in [[construct]] could have the
constructor property as DontEnum. This seems to be a compatibility
issue with ES3.

In ES3, you can't depend on the enumerability of an object's own
constructor property. This is because prototype objects have a
constructor property that is flagged DontEnum.

The idea is to make constructor a DontEnum property on all objects.

(not just ones that were created through [[construct]] to be used as
prototype properties).

constructor would be a default value given to the object in [[construct]]

What do you think?


 F is an instance of Function
 f is an instance of F

 Function 

Re: 13.2.2 [[Construct]], constructor, and [[Class]] (was __proto__)

2007-09-23 Thread Brendan Eich
On Sep 23, 2007, at 12:22 PM, Garrett Smith wrote:

 in no case is the value of (new function(){}).constructor Function.

 It shouldn't be, but it is in OSX Ref Impl. (I did not build this).

 js (new function(){}).constructor
 [function Function]

No, that's just http://bugs.ecmascript.org/ticket/64 -- proof:

  (new function(){}).constructor
[function Function]
  (new function(){}).constructor === Function
false
  f = function(){}
[function Function]
  (new f).constructor === f
true
 

With Function.prototype.toString buggy, you need to test identity of  
function objects.

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


Re: 13.2.2 [[Construct]], constructor, and [[Class]] (was __proto__)

2007-09-23 Thread Garrett Smith
On 9/23/07, Brendan Eich [EMAIL PROTECTED] wrote:
 On Sep 23, 2007, at 12:22 PM, Garrett Smith wrote:

  in no case is the value of (new function(){}).constructor Function.
 
  It shouldn't be, but it is in OSX Ref Impl. (I did not build this).
 
  js (new function(){}).constructor
  [function Function]

 No, that's just http://bugs.ecmascript.org/ticket/64 -- proof:

   (new function(){}).constructor
 [function Function]
   (new function(){}).constructor === Function
 false
   f = function(){}
 [function Function]
   (new f).constructor === f
 true
  

Ah, OK.

js Function().toSource()
function(){}

Works.

I usually like modifying toString anyway.

F = function(){};
F.prototype = {
toString : function() {
return Fork!;
}
};
f = new F;
f.toString()
//f.constructor


 With Function.prototype.toString buggy, you need to test identity of
 function objects.

Buggy or not, since functions could have different [[Scope]], testing
toString makes no sense.

Testing toSource is useful for seeing if it's a native function (eval,
or RegExp test), but Function.prototype.toSource() isn't provided in
the spec and isn't supported in JScript.

Garrett

 /be



-- 
Programming is a collaborative art.
___
Es4-discuss mailing list
Es4-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es4-discuss


Re: __proto__

2007-09-11 Thread Kris Zyp
Is __proto__ somehow a new security threat? __proto__ has been around for 
ages in SM/FF and not only that, but it has been there in the more hazardous 
writable form. I just wanted it be actually included in the spec. Or is 
there some new functionality in ES4 that will somehow interact with 
__proto__ to introduce a security threat?
Kris
- Original Message - 
From: Lars T Hansen [EMAIL PROTECTED]
To: Kris Zyp [EMAIL PROTECTED]
Cc: Brendan Eich [EMAIL PROTECTED]; liorean [EMAIL PROTECTED]; 
es4-discuss@mozilla.org
Sent: Tuesday, September 11, 2007 2:34 AM
Subject: Re: __proto__


 On the one hand, __proto__ is another potential security hole, and it
 prevents implementations from sharing prototype objects among multiple
 documents -- the link may be read-only but the object isn't.  Function
 B called from function A with object O may hack O.__proto__ and A can
 do nothing about it; suddenly all O-like objects in the system act
 differently.

 On the other hand, Constructor.prototype is generally available for
 any Constructor, so it's hard to see what the real damage is -- it's
 not obviously worse than some other aspects of the language.

 On the third hand, some implementations may have specialized objects
 for which no Constructor is available and for whom keeping
 [[Prototype]] unavailable is desirable.  Similarly, some toolkits may
 have private prototype objects that are not available to client code
 because the constructor is hidden in a lexical scope (ES3) or
 package/namespace (ES4).

 Introspection is great, but it assumes a lot about how trust works in
 the environment.

 --lars


 On 9/11/07, Kris Zyp [EMAIL PROTECTED] wrote:
  The alternative above would standardize read-only __proto__, which 
  would
  make that property no longer implementation-specific. But of  course we
  have no proposal to do that.
 I realize this wasn't really the main subject... but could the __proto__
 property be defined in the spec (as readonly)? I would love to see that
 property standardized.
 Kris

 ___
 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: __proto__

2007-09-11 Thread Lars T Hansen
__proto__ breaks abstraction boundaries in the language -- it's just
like function.caller, you get to look at and change objects that your
caller may wish to keep secret from you.  Whether it's actually a
security threat depends on the details of the environment: whether
your caller fits those criteria or not, or whether your run-time
environment has objects whose constructors are not exposed to client
code.

--lars

On 9/11/07, Kris Zyp [EMAIL PROTECTED] wrote:
 Is __proto__ somehow a new security threat? __proto__ has been around for
 ages in SM/FF and not only that, but it has been there in the more hazardous
 writable form. I just wanted it be actually included in the spec. Or is
 there some new functionality in ES4 that will somehow interact with
 __proto__ to introduce a security threat?
 Kris
 - Original Message -
 From: Lars T Hansen [EMAIL PROTECTED]
 To: Kris Zyp [EMAIL PROTECTED]
 Cc: Brendan Eich [EMAIL PROTECTED]; liorean [EMAIL PROTECTED];
 es4-discuss@mozilla.org
 Sent: Tuesday, September 11, 2007 2:34 AM
 Subject: Re: __proto__


  On the one hand, __proto__ is another potential security hole, and it
  prevents implementations from sharing prototype objects among multiple
  documents -- the link may be read-only but the object isn't.  Function
  B called from function A with object O may hack O.__proto__ and A can
  do nothing about it; suddenly all O-like objects in the system act
  differently.
 
  On the other hand, Constructor.prototype is generally available for
  any Constructor, so it's hard to see what the real damage is -- it's
  not obviously worse than some other aspects of the language.
 
  On the third hand, some implementations may have specialized objects
  for which no Constructor is available and for whom keeping
  [[Prototype]] unavailable is desirable.  Similarly, some toolkits may
  have private prototype objects that are not available to client code
  because the constructor is hidden in a lexical scope (ES3) or
  package/namespace (ES4).
 
  Introspection is great, but it assumes a lot about how trust works in
  the environment.
 
  --lars
 
 
  On 9/11/07, Kris Zyp [EMAIL PROTECTED] wrote:
   The alternative above would standardize read-only __proto__, which
   would
   make that property no longer implementation-specific. But of  course we
   have no proposal to do that.
  I realize this wasn't really the main subject... but could the __proto__
  property be defined in the spec (as readonly)? I would love to see that
  property standardized.
  Kris
 
  ___
  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