RE: array like objects

2009-12-12 Thread Mike Wilson
David-Sarah Hopwood wrote:
 Mark S. Miller wrote:
  function isArrayLike(obj) {
var len;
return !!(obj 
  typeof obj === 'object' 
  'length' in obj 
  !({}).propertyIsEnumerable.call(obj, 'length') 
  (len = obj.length)  0 === len);
  }

 If you want to avoid side effects:
 
 function isArrayLike(obj) {
   if (!obj || typeof obj !== 'object') return false;
   var desc = Object.getOwnPropertyDescriptor(obj, 'length');
   if (desc) {
 var len = desc.value;
 return !desc.enumerable  (len === undefined || len  
 0 === len);
   }
 }

An advantage with Mark's code is that it doesn't rely
on ES5 API. I think it's good to establish a standard
for array-likeness that can be matched by ES3 code as
well.

Best regards
Mike

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


Re: Catch-all proposal based on proxies

2009-12-12 Thread Mike Samuel
2009/12/11 Mark S. Miller erig...@google.com:
 On Fri, Dec 11, 2009 at 9:31 AM, Brendan Eich bren...@mozilla.com wrote:

 On Dec 11, 2009, at 8:36 AM, Maciej Stachowiak wrote:

 On Dec 10, 2009, at 10:06 PM, Mark S. Miller wrote:

 has 263. I will proceed to worry only about hasOwnProperty until someone
 objects.

 Note that these are hits found in source repositories, not on the Web. So
 I would not put too much stock in the number of hits except as an existence
 proof. Both of these include hits from JavaScript libraries, likely meaning
 there are many deployed copies of the code in question (though unclear if
 that code path gets hit as the JS libraries are used in practice).

 Absolutely. The best case with codesearch would be to get no results --
 that would suggest but not prove that the construct is not used. Getting any
 hits casts doubt on claim that the construct isn't used enough to worry
 about. More than a few handfuls of hits - you should worry.

 Mark, I don't think we can pick meta-level methods to worry about and not
 worry about, if the goal is transparent wrapping or catch-all based DOM
 emulations. OTOH, propertyIsEnumerable is much less used than
 hasOwnProperty, whether directly or via .call. But in principle it is the
 same kind of animal.


 I have now changed the spec so that Object.prototype.hasOwnProperty.call
 and Object.prototype. propertyIsEnumerable.call are base level rather than
 meta level methods. Proxies can now virtualize them fine, at the price of
 loading down the handler protocol with two more methods. As discussed
 earlier, I also added an invoke: trap so that named method invocations can
 be handled in one step without having to curry over the method name. So,
 altogether, three more methods. On the other hand, the double reflection
 needed by the membrane became simpler and faster, since the choke point is
 now an invoke trap.
 Of legacy methods, the only one which is still meta-level
 is Object.prototype.toString.call, as is necessary to preserve its meaning.
 The similar Function.prototype.toString.call remains in limbo awaiting a
 clearer spec. Neither of these should impede faithful emulation of existing
 DOM expectations.

On the interaction of Function.prototype.toString and function
proxies, one use case is code that tries to get at a function's name
as by doing

function nameOf(f) {
  if ('name' in f) { return f.name; }  // Works on some interpreters
  var m = ('' + f).match(/^function\s+([^(\s]+)/);
  return m ? m[1] : void 0;
}

I'm not sure how much of the existing code like this invokes toString
directly or indirectly instead of using Function.prototype.toString.

Function proxy handlers could implement has('name') then there might
not be a need for Function.prototype.toString to support this use
case.


 --
    Cheers,
    --MarkM

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


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


Re: array like objects

2009-12-12 Thread Garrett Smith
On Fri, Dec 11, 2009 at 12:08 PM, Mike Wilson mike...@hotmail.com wrote:
 Mark S. Miller wrote:

 If we're looking for a convention that is
 * does not admit any legacy ES3R non-array non-host objects (to prevent
 false positives)

No native ES objects?

 * does easily allow ES5 programmers to define new array-like non-array
 objects
 * takes bounded-by-constant time (i.e., no iteration)

*What* takes bounded-by-constant time? The object's existence would
not take any time.

 * is a reasonably compatible compromise with the existing notions of
 array-like in legacy libraries as represented by previous examples in this
 thread

Can you please clarify what the problem area is a little more?

 then I suggest:
 function isArrayLike(obj) {
   var len;
   return !!(obj 
             typeof obj === 'object' 
             'length' in obj 
             !({}).propertyIsEnumerable.call(obj, 'length') 
             (len = obj.length)  0 === len);
 }


 Is looks like array like is defined as an an object where length
is non-enumerable and numeric. What about [[Get]], [[HasProperty]] for
numeric property names?

And why must the - length - property be an *own* property? Why could
length not be a getter in the prototype chain?

Indeed many Mozilla DOM collections work this way:

javascript: var cn = document.links; alert([cn.length,
({}).hasOwnProperty.call( cn, length)]);

Mozilla elerts 80, false

Garrett
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


[[HasOwnProperty]]

2009-12-12 Thread Garrett Smith
[[HasOwnProperty]] is mentioned in one place in the spec: s 15.4.4.11
Array.prototype.sort (comparefn).

There is no mention of [[HasOwnProperty]] anywhere else.

I also see a [[GetOwnProperty]] definition in Table 8 and a definition
for own property (s. 4.3.30).

Is there a difference between [[HasOwnProperty]] and own property?
If not, then one or the other should be used. If so, then
[[HasOwnProperty]] should be defined somewhere in the spec.

Garrett
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


RE: array like objects

2009-12-12 Thread Mike Wilson
Mark S. Miller wrote:



On Sat, Dec 12, 2009 at 10:36 AM, Mike Samuel mikesam...@gmail.com wrote:


On the String defect, we could repair that with
({}).toString.call(obj) !== '[object String]'
Cons:
  An extra function call in the likely case
  Strings are arguable array-like
Pros:
  Strings are inconsistently indexable : (new String('foo'))[0] is
undefined on IE 6 

 
Yes, this test would work. Before incorporating it, we should discuss
whether String wrapper objects should indeed be considered array-like. My
inclination is that they should not. Opinions? 

I don't think strings should trigger array-like, and this seems to be the
position held by most JS libraries (see f ex dojo.isArrayLike). The normal
use of these methods is to identify things like Arguments and NodeLists, ie
sequences of distinct objects/values, not character sequences (text).
Anyhow, whatever is decided here I think primitive strings and String
wrappers should be handled the same way in this respect.
 
Best regards
Mike
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: [[HasOwnProperty]]

2009-12-12 Thread Mark S. Miller
[+es5-discuss] Thanks for reporting. But please include es5-discuss on all
messages pointing out mistakes in the ES5 spec. It will help us
accumulate errata.


On Sat, Dec 12, 2009 at 11:29 AM, Garrett Smith dhtmlkitc...@gmail.comwrote:

 [[HasOwnProperty]] is mentioned in one place in the spec: s 15.4.4.11
 Array.prototype.sort (comparefn).

 There is no mention of [[HasOwnProperty]] anywhere else.

 I also see a [[GetOwnProperty]] definition in Table 8 and a definition
 for own property (s. 4.3.30).

 Is there a difference between [[HasOwnProperty]] and own property?
 If not, then one or the other should be used. If so, then
 [[HasOwnProperty]] should be defined somewhere in the spec.

 Garrett
 ___
 es-discuss mailing list
 es-discuss@mozilla.org
 https://mail.mozilla.org/listinfo/es-discuss




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


Re: array like objects

2009-12-12 Thread Brendan Eich

On Dec 12, 2009, at 11:36 AM, Mike Wilson wrote:


Mark S. Miller wrote:

On Sat, Dec 12, 2009 at 10:36 AM, Mike Samuel mikesam...@gmail.com  
wrote:

On the String defect, we could repair that with
({}).toString.call(obj) !== '[object String]'
Cons:
  An extra function call in the likely case
  Strings are arguable array-like
Pros:
  Strings are inconsistently indexable : (new String('foo'))[0] is
undefined on IE 6

Yes, this test would work. Before incorporating it, we should  
discuss whether String wrapper objects should indeed be considered  
array-like. My inclination is that they should not. Opinions?
I don't think strings should trigger array-like, and this seems to  
be the position held by most JS libraries (see f ex  
dojo.isArrayLike). The normal use of these methods is to identify  
things like Arguments and NodeLists, ie sequences of distinct  
objects/values, not character sequences (text).


A String object is indexable (to get unit-length strings -- not  
characters) with length as fencepost above the maximum index.


A string or String object wrapping it has immutable .length and [i]  
for i  length properties, OTOH -- it is not frozen, but this raises  
the question: is a frozen Array instance no longer array-like?


Prototype's isArray wants 'splice' in obj  'join' in obj, but that  
rules out many objects considered array-like, without monkey-patching.


We need a definition of array-like that matches common practice, if  
there is a common practice. Then we can see (without prejudgment)  
whether Strings satisfy it.


From Mike Samuel's posts and my own quick reading, I don't see too  
much common practice. A more detailed survey of popular Ajax libraries  
would be great -- I'm out of time right now, but I'll try later today  
unless someone else does it first.



Anyhow, whatever is decided here I think primitive strings and  
String wrappers should be handled the same way in this respect.


Right.

/be

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


Re: array like objects

2009-12-12 Thread Brendan Eich

On Dec 12, 2009, at 10:36 AM, Mike Samuel wrote:


2009/12/12 Mike Wilson mike...@hotmail.com:

David-Sarah Hopwood wrote:

Mark S. Miller wrote:

function isArrayLike(obj) {
  var len;
  return !!(obj 
typeof obj === 'object' 
'length' in obj 
!({}).propertyIsEnumerable.call(obj, 'length') 
(len = obj.length)  0 === len);
}


Nits:

Array length is specified as being in [0, 0x8000_],


Where? From the spec that implementors have had years to follow  
(citing ES3 rather than ES5), Array length is defined by:


15.4.5.2 length

The length property of this Array object is always numerically  
greater than the name of every property whose name is an array index.


which refers to the definition of array index here:

15.4 Array Objects

Array objects give special treatment to a certain class of property  
names. A property name P (in the form of a string value) is an array  
index if and only if ToString(ToUint32(P)) is equal to P and  
ToUint32(P) is not equal to 2^32−1. Every Array object has a length  
property whose value is always a nonnegative integer less than 2^32.


So length is in [0, 0x] and array indexes are in [0,  
0xfffe].


String length has no such constraint.

/be

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


Re: array like objects

2009-12-12 Thread Garrett Smith
On Sat, Dec 12, 2009 at 12:01 PM, Mark S. Miller erig...@google.com wrote:
 On Sat, Dec 12, 2009 at 11:21 AM, Garrett Smith dhtmlkitc...@gmail.com
 wrote:

 On Fri, Dec 11, 2009 at 12:08 PM, Mike Wilson mike...@hotmail.com wrote:
  Mark S. Miller wrote:
 
  If we're looking for a convention that is
  * does not admit any legacy ES3R non-array non-host objects (to prevent
  false positives)

 No native ES objects?


 Native array and (currently) String wrapper objects do pass this test. No
 other ES3R natives objects can. Which native objects are you concerned
 about?


Any user defined native object e.g. a jquery object or something like:

{
  x : 10,
  length : 1.5
}



  * does easily allow ES5 programmers to define new array-like non-array
  objects
  * takes bounded-by-constant time (i.e., no iteration)

 *What* takes bounded-by-constant time? The object's existence would
 not take any time.

 The execution time of this predicate. Actually, that's not necessarily true.

[snip]

Got it.  That means that the isArrayLike test itself is constant time.
That makes sense.


  * is a reasonably compatible compromise with the existing notions of
  array-like in legacy libraries as represented by previous examples in
  this
  thread

 Can you please clarify what the problem area is a little more?

  then I suggest:
  function isArrayLike(obj) {
    var len;
    return !!(obj 
              typeof obj === 'object' 
              'length' in obj 
              !({}).propertyIsEnumerable.call(obj, 'length') 
              (len = obj.length)  0 === len);
  }
 


[snip]

  Is looks like array like is defined as an an object where length
 is non-enumerable and numeric. What about [[Get]], [[HasProperty]] for
 numeric property names?

 And why must the - length - property be an *own* property? Why could
 length not be a getter in the prototype chain?

 Indeed many Mozilla DOM collections work this way:

 javascript: var cn = document.links; alert([cn.length,
 ({}).hasOwnProperty.call( cn, length)]);

 Mozilla elerts 80, false


 Not a problem. The proposed predicate does not test whether 'length' is own,
 only whether it is enumerable. A squarefree session on FF 3.5.5:

[snip]

Ah no, that is not correct, your isArrayLike *does* test to see
whether length is own.

Object.prototype.propertyIsEnumerable does not consider properties in
the prototype chain. In effect, propertyIsEnumerable is a test to see
if an object has *own* property that is also enumerable.

We discussed this back in ES4 proposal days, and I think I remember
that it was decided to keep the existing behavior (as unintuitive as
it may be) to not break existing code (some already broken things YUI
and some other libs were doing).

Also notice that the name propertyIsEnumerable deviates from standard
boolean predicate method naming convention. Flash AS apparently has an
isPropertyEnumerable (more standard boolean predicate name).

Garrett
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: array like objects

2009-12-12 Thread Mark S. Miller
On Sat, Dec 12, 2009 at 12:29 PM, Garrett Smith dhtmlkitc...@gmail.comwrote:

 Object.prototype.propertyIsEnumerable does not consider properties in
 the prototype chain. In effect, propertyIsEnumerable is a test to see
 if an object has *own* property that is also enumerable.


And just when I was thinking I was finally beginning to understand this
language :(. I wonder what other gotchas I'm still missing?

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


Re: Catch-all proposal based on proxies

2009-12-12 Thread Maciej Stachowiak


On Dec 12, 2009, at 11:08 AM, Mark S. Miller wrote:

On Sat, Dec 12, 2009 at 10:53 AM, Mike Samuel mikesam...@gmail.com  
wrote:

On the interaction of Function.prototype.toString and function
proxies, one use case is code that tries to get at a function's name
as by doing

function nameOf(f) {
 if ('name' in f) { return f.name; }  // Works on some interpreters
 var m = ('' + f).match(/^function\s+([^(\s]+)/);
 return m ? m[1] : void 0;
}

I'm not sure how much of the existing code like this invokes toString
directly or indirectly instead of using Function.prototype.toString.

Function proxy handlers could implement has('name') then there might
not be a need for Function.prototype.toString to support this use
case.


Under the current proposal, a trapping function proxy f can  
virtualize all the following without problem:


'name' in f
f.name
'' + f
f.toString()

The only open issue is

Function.prototype.toString.call(f)

I would have ventured a guess that this isn't used in real code. But  
having learned my lesson ;), I looked. What do we all think of http://www.google.com/codesearch?hl=enlr=q=Function.prototype.toString.call+lang:javascriptsbtn=Search 
?


Interesting. A few of these uses appear to be in JavaScript libraries  
so they could be widespread. I see a few different uses:


- To get the function name
- To detect if something is a function at all (by seeing if the  
attempt to call it throws)

- To check for function equality (likely a bogus check!)
- To get argument names
- Something else mysterious that I couldn't figure out (looking for  
calls to the Function constructor inside the function body?)


Note though that in the case of DOM emulation specifically, probably  
most of these are not relevant. Looking at toString() on DOM methods  
is usually done for one of the following reasons:


1) To get the function name.
2) To check for [native code] to verify that a native method hasn't  
been replaced by JavaScript code (seems like a fairly bogus check).


Regards,
Maciej


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


Re: Weak references and destructors

2009-12-12 Thread Mark S. Miller
On Fri, Dec 11, 2009 at 12:45 AM, Erik Corry erik.co...@gmail.com wrote:

 2009/12/11 Mark S. Miller erig...@google.com:
  [...] However, I
  agree that these proposals should be decoupled if possible. Accordingly,
 I
  have kludged [...]

 I really dislike this definition.  This would imply that anyone could
 overwrite setTimeout and get a completely different behaviour.  If
 overwriting is impossible then it introduces setTimeout into the
 standard by the backdoor.

 I'd prefer an underspecified [[QueueForProcessing]] operation with no
 connection to the global object and a note to say that in a browser it
 would be expected to use the same mechanism as a setTimeout with a
 timeout of zero.

 I agree. Done. To be consistent with the spec style on the rest of that
page -- perhaps a bad idea -- I called your [[QueueForProcessing]] operation
POSTPONE. This is a minor issue and I'm not attached to the choice. In any
case, the most relevant new text is at 
http://wiki.ecmascript.org/doku.php?id=strawman:weak_references#safe_post_mortem_notification.
Thanks for the suggestion.




 There are lots of misunderstandings around GC, where people expect
 this sort of callback to happen at some predictable time.  If there's
 no memory pressure then there's no reason to expect the GC to ever be
 run even if the program runs for ever.  It would be nice to have some
 indication in the text of the standard that discouraged people from
 expecting a callback at some predictable time.  For example if people
 want to close file descriptors or collect other resources that are not
 memory using this mechanism it would be nice to discourage them
 (because it won't work on a machine with lots of memory and not so
 many max open fds).


Does the current text clarify this to your satisfaction?

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


Re: [[HasOwnProperty]]

2009-12-12 Thread David-Sarah Hopwood
Garrett Smith wrote:
 [[HasOwnProperty]] is mentioned in one place in the spec: s 15.4.4.11
 Array.prototype.sort (comparefn).
 
 There is no mention of [[HasOwnProperty]] anywhere else.
 
 I also see a [[GetOwnProperty]] definition in Table 8 and a definition
 for own property (s. 4.3.30).
 
 Is there a difference between [[HasOwnProperty]] and own property?
 If not, then one or the other should be used. If so, then
 [[HasOwnProperty]] should be defined somewhere in the spec.

Array.prototype.sort should have been defined in terms of
[[GetOwnProperty]]. That is, the text in 15.4.4.11 should be

# • The result of calling the [[GetOwnProperty]] internal method of
#   proto with argument ToString(j) is not *undefined*.


(Incidentally, I don't see any errata for the published standard at
http://wiki.ecmascript.org/doku.php?id=es3.1:es3.1_proposal_working_draft.)

-- 
David-Sarah Hopwood  ⚥  http://davidsarah.livejournal.com



signature.asc
Description: OpenPGP digital signature
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: array like objects

2009-12-12 Thread Mark S. Miller
On Sat, Dec 12, 2009 at 12:29 PM, Garrett Smith dhtmlkitc...@gmail.com
wrote:
 Object.prototype.propertyIsEnumerable does not consider properties in
 the prototype chain. In effect, propertyIsEnumerable is a test to see
 if an object has *own* property that is also enumerable.

At the end of 
http://wiki.ecmascript.org/doku.php?id=conventions:isarraylike I have added
the issue:

Unfortunately, the propertyIsEnumerable test above, despite the name,
actually tests whether a property is both enumerable and own. This means the
above predicate will reject objects that inherit a non-enumerable length
property. I can think of no reliable and portable ES3R test which tests only
property enumerability, except by running a for-in loop and testing the
output. Doing so would kill the bounded-by-constant time virtue.


Are we really this stuck? Can anyone think of a reliable, portable, and fast
ES3R test that tests whether a property is enumerable, whether it is
inherited or not?

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


Re: Weak references and destructors

2009-12-12 Thread P T Withington
On 2009-12-11, at 12:43, Brendan Eich wrote:

 It would be more than nice. It is important that the spec not mandate any 
 particular schedule. We have seen endless over-coupling to GC implementation 
 details where programmers who can hook into finalization or another GC phase 
 do so for all the wrong reasons: to close fds, free database cursors, send a 
 message, update UI, etc. Crazy stuff.

+n

In my experience, it is always a bad idea for the GC to invoke user-code.

Please don't throw out the weak-key tables with the finalization bathwater.

 But if there is no guarantee of when the notification might happen, then 
 programmers should not expect any scheduling akin to setTimeout with a 
 timeout of zero.

I initially mis-read this as saying setTimeout with a timeout of 0 might never 
be scheduled.  But that's not what you said.

--

I was amused by this aside from the strawman:

 Since I can never remember the black/white polarity of traditional gc 
 descriptions, I will use retained for black, fringe for gray, and untraced 
 for white.
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: array like objects

2009-12-12 Thread Mark S. Miller
On Sat, Dec 12, 2009 at 3:38 PM, Garrett Smith dhtmlkitc...@gmail.comwrote:

 On Sat, Dec 12, 2009 at 2:59 PM, Mark S. Miller erig...@google.com
 wrote:
  Are we really this stuck? Can anyone think of a reliable, portable, and
 fast
  ES3R test that tests whether a property is enumerable, whether it is
  inherited or not?
 

 Not stuck. Why do you care if |length| is enumerable?

 If a standard |for| loop is used, it doesn't matter.  Why anyone would
 want to use |for in| for something that is arrayLike?



|for in| is not my concern. I wish a predicate that has little chance of
false positives against legacy ES3 user constructed objects. If

var obelisk = {
  width: 9,
  length: 16,
  height: 25
};

appears in some existing code, I don't want a predicate that decides the
obelisk is array-like, as it was clearly not the intent. The reason I care
about enumerability is that legacy ES3R code has no way to create an
ordinary native object with a non-enumerable length property, thereby
preventing false positives in against legacy ES3R objects.

OTOH, your examples of false DOM negatives below are sufficiently
discouraging that perhaps this whole exercise is fruitless. Perhaps there is
no coherent notion of array-like to be rescued from current practice.




 Can an arrayLike object have other properties? If you're talking about
 a DOM collection, you can be that it will have other properties and
 probably a mix of enumerable and non-enumerable proprietary
 properties.

 A DOM collection (NodeList, for example) might very well have a length
 property that shows up in the body of a for in loop. There is no
 standard that specifies one way or another if a NodeList's length
 property should be enumerable. I can't see why anyone would care,
 either.

 javascript: for(var p in document.childNodes) if(!isFinite(p)) alert(p);

 Firefox 3.5, Safari 4, Chrome 2:
length
item

 Opera 10:
length
item
namedItem
tags

 IE7
tags

 That example alone shows a few good reasons why using a for in loop
 would be a bad choice. In superficial testing in a few browsers, the
 length property showed up in the body of a for in loop. Other
 properties will show up, depending on the implementation and property
 name. Other collections will likely have even more properties.

 if a DOM collection is considered arrayLike, then using for in loops
 over arrayLike can be considered to be a reckless, error-prone
 concept.

 OTOH, If indexed properties are got off the object, as with your
 standard for loop, the enumerability of - length - is irrelevant. So
 again: Why do you care if |length| is enumerable?

 Garrett
 ___
 es-discuss mailing list
 es-discuss@mozilla.org
 https://mail.mozilla.org/listinfo/es-discuss




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


Re: Catch-all proposal based on proxies

2009-12-12 Thread Mike Samuel
2009/12/12 Mark S. Miller erig...@google.com:
 On Sat, Dec 12, 2009 at 10:53 AM, Mike Samuel mikesam...@gmail.com wrote:

 On the interaction of Function.prototype.toString and function
 proxies, one use case is code that tries to get at a function's name
 as by doing

 function nameOf(f) {
  if ('name' in f) { return f.name; }  // Works on some interpreters
  var m = ('' + f).match(/^function\s+([^(\s]+)/);
  return m ? m[1] : void 0;
 }

 I'm not sure how much of the existing code like this invokes toString
 directly or indirectly instead of using Function.prototype.toString.

 Function proxy handlers could implement has('name') then there might
 not be a need for Function.prototype.toString to support this use
 case.


 Under the current proposal, a trapping function proxy f can virtualize all
 the following without problem:
     'name' in f
     f.name
     '' + f
     f.toString()
 The only open issue is
     Function.prototype.toString.call(f)
 I would have ventured a guess that this isn't used in real code. But having
 learned my lesson ;), I looked. What do we all think
 of http://www.google.com/codesearch?hl=enlr=q=Function.prototype.toString.call+lang:javascriptsbtn=Search?

So in your search results, prototype is extracting formal parameter names.
  argumentNames: function() {
var names = Function.prototype.toString.call(this)
 .match(/^[\s\(]*function[^(]*\(([^\)]*)\)/)[1]
 .replace(/\s+/g, '').split(',');
return names.length == 1  !names[0] ? [] : names;
  },

 --
    Cheers,
    --MarkM

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


Re: array like objects

2009-12-12 Thread Mike Samuel
2009/12/12 Brendan Eich bren...@mozilla.com:
 On Dec 12, 2009, at 10:36 AM, Mike Samuel wrote:

 2009/12/12 Mike Wilson mike...@hotmail.com:

 David-Sarah Hopwood wrote:

 Mark S. Miller wrote:

 function isArrayLike(obj) {
  var len;
  return !!(obj 
            typeof obj === 'object' 
            'length' in obj 
            !({}).propertyIsEnumerable.call(obj, 'length') 
            (len = obj.length)  0 === len);
 }

 Nits:

 Array length is specified as being in [0, 0x8000_],

 Where? From the spec that implementors have had years to follow (citing ES3
 rather than ES5), Array length is defined by:

 15.4.5.2 length

 The length property of this Array object is always numerically greater than
 the name of every property whose name is an array index.

 which refers to the definition of array index here:

 15.4 Array Objects

 Array objects give special treatment to a certain class of property names.
 A property name P (in the form of a string value) is an array index if and
 only if ToString(ToUint32(P)) is equal to P and ToUint32(P) is not equal to
 2^32−1. Every Array object has a length property whose value is always a
 nonnegative integer less than 2^32.

 So length is in [0, 0x] and array indexes are in [0, 0xfffe].

Ah.  Thanks.

 String length has no such constraint.

 /be


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


Re: array like objects

2009-12-12 Thread Mike Samuel
2009/12/12 Garrett Smith dhtmlkitc...@gmail.com:
 On Fri, Dec 11, 2009 at 12:08 PM, Mike Wilson mike...@hotmail.com wrote:
 Mark S. Miller wrote:

 If we're looking for a convention that is
 * does not admit any legacy ES3R non-array non-host objects (to prevent
 false positives)

 No native ES objects?

 * does easily allow ES5 programmers to define new array-like non-array
 objects
 * takes bounded-by-constant time (i.e., no iteration)

 *What* takes bounded-by-constant time? The object's existence would
 not take any time.

 * is a reasonably compatible compromise with the existing notions of
 array-like in legacy libraries as represented by previous examples in this
 thread

 Can you please clarify what the problem area is a little more?

 then I suggest:
 function isArrayLike(obj) {
   var len;
   return !!(obj 
             typeof obj === 'object' 
             'length' in obj 
             !({}).propertyIsEnumerable.call(obj, 'length') 
             (len = obj.length)  0 === len);
 }


  Is looks like array like is defined as an an object where length
 is non-enumerable and numeric. What about [[Get]], [[HasProperty]] for
 numeric property names?

I prefer integral and non-negative to numeric.
As Brendan pointed out, the definition of uint32 already matches up
with length as specified for arrays.
He also points out that there in no limit on string length, but if
ulp(length)  1 then you run into a lot of problems, so there is a
practical limit on length of 2**53.

I think any of the following definitions of length would be fine
  * uint32: (x === (x  0)  isFinite(x))
  * non-negative integer: (x === +x  !(x % 1))
  * non-negative integer i such that ulp(i) = 1: (x === +x  !(x %
1)  (x - -1) !== x)

 And why must the - length - property be an *own* property? Why could
 length not be a getter in the prototype chain?

 Indeed many Mozilla DOM collections work this way:

 javascript: var cn = document.links; alert([cn.length,
 ({}).hasOwnProperty.call( cn, length)]);

 Mozilla elerts 80, false

 Garrett
 ___
 es-discuss mailing list
 es-discuss@mozilla.org
 https://mail.mozilla.org/listinfo/es-discuss

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


Re: array like objects

2009-12-12 Thread Garrett Smith
On Sat, Dec 12, 2009 at 4:04 PM, Mark S. Miller erig...@google.com wrote:
 On Sat, Dec 12, 2009 at 3:38 PM, Garrett Smith dhtmlkitc...@gmail.com
 wrote:

 On Sat, Dec 12, 2009 at 2:59 PM, Mark S. Miller erig...@google.com
 wrote:
  Are we really this stuck? Can anyone think of a reliable, portable, and
  fast
  ES3R test that tests whether a property is enumerable, whether it is
  inherited or not?
 

 Not stuck. Why do you care if |length| is enumerable?

 If a standard |for| loop is used, it doesn't matter.  Why anyone would
 want to use |for in| for something that is arrayLike?


 |for in| is not my concern. I wish a predicate that has little chance of
 false positives against legacy ES3 user constructed objects.

Why the need to distinguish between a user-defined object that is
intended for iteration vs one that is not? The program should already
know. If the needs of a program are to iterate over an object's
indexed properties, possibly filtering, mapping, etc, then allowing
the algorithm to throw errors at Step 0 seems like a recipe for IE (a
disaster).

[snip]

I am still a bit fuzzy on what your arrayLike means or is intended
for. Allen pointed out on previous thread[1] that Array generic
methods provide an implicit contract. What that contract is depends on
the method and arguments.

Array.prototype.slice, when supplied with one argument, has the
following implicit contract for the thisArg:
 1) [[Get]]
 2) [[HasProperty]] checks

An object that can do those two, but also has a - length - property
has enough functionality so that a call to - ([]).slice.call( anObject
) - would be expected to return an array that has anObject's numeric
properties, except for the specification allowing anything goes with
Host object and we see JScript Object Expected errors in IE.

Allen has not yet commented on that.

Stronger wording for Host object in ES specification would provide
stronger incentive for implementations (IE) to use host objects that
have consistent functionality. IOW, if the Array.prototype.slice says:

| 2. Call the [[Get]] method of this object with argument length.

[[Get]] works via property accessor operators, as in:-

k = anObject.length  0;

- then that step of the algorithm should succeed.

Once an Array is obtained, then the program can use the other
Array.prototype methods on that object.  Alternatively, if the
object's functionality is known by the programmer and the
functionality fulfills an implicit contract for a generic method, then
the program should be able to use that method, host object or not. At
least, I would like it to be that way.

| var anObject = document.body.childNodes;
| function fn( obj ) { return /foo/.test(obj.className); };
| Array.prototype.filter.call( anObject, fn );

Or (Spidermonkey only):

| function fn( obj ) { return /foo/.test(obj.className); }
| Array.filter( document.body.childNodes, fn );

ES5 allows the algorithm to terminate at step 0, so that approach is
not viable.

A for loop could be used, however the downside to that now the program
uses a user-defined makeArray function.

makeArray( anObject ).
  filter( function(obj) { return /foo/.test(obj.className); });

Which requires double iteration over the collection, plus the overhead
of an extra call, plus the extra makeArray function, downloaded and
interpreted and loaded in memory. This sort of thing is often mired in
the bowels of today's popular libraries.

In contrast, the generic algorithm in question could be specified to
execute each step, regardless of whether or not the argument is a host
object.

Whether or not the execution of that step results in error depends on
the particular object's implementation. This way, if an object
supports [[Get]], an Array method that calls [[Get]] could be expected
to succeed. However if the object has a readonly - length - property,
or - length - is a getter with no setter, then it would be expected to
throw an error.

Is this idea reasonable or feasable, from a spec standpoint or
implementation standpoint?

This is a very very old issue these errors are still coming in IE8,
but do not appear in other major browsers (AFAIK). Is stronger wording
for host objects a good idea?

Garrett

[1]https://mail.mozilla.org/pipermail/es-discuss/2009-May/009310.html
[2]https://mail.mozilla.org/pipermail/es-discuss/2009-December/010241.html
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss