Re: traits feedback

2011-10-05 Thread Tom Van Cutsem
Thanks for the feedback, John.

I have to admit that at first I was also taken aback by the apparent
complexity of the syntax for efficient traits strawman. Traits have many
knobs, and require a lot of syntax to turn these knobs.

Regardless of whether you'd want nice declarative syntax for traits for the
sake of usability, for traits.js in particular, there's another important
benefit to having some language support. When using Trait.create to create
tamper-proof objects whose methods have an unspoofable |this|-binding, the
traits.js library creates a method wrapper per method per instance (to bind
|this| to the instance). I still need to verify how much overhead this
actually creates, but there definitely is overhead, and I don't see any way
to avoid it without some support from the language.

Cheers,
Tom

2011/10/5 John J Barton johnjbar...@johnjbarton.com

 In trying to update my JS approach I looked into 'traits'. I'm still on the
 fence about using them at this stage, but MarkM was asking for feedback of
 pretty much any kind so here is a little.

 I believe I understand traits for the most part just from the info on the
 Web site:
 http://traitsjs.org/
 (but read the examples in the Paper, not the one in the Tutorial).
 Traits feel like JS to me: a reusable set of methods packaged in an object.
 The Trait construct add regularity and organization to a wide-spread pattern
 of JS use, but it feels like a tool you pick up when you need it. The key
 operations are create and compose, with resolve and override to handle
 exotic issues.

 On the other hand I had the opposite reaction to
 http://wiki.ecmascript.org/doku.php?id=strawman:syntax_for_efficient_traits
 That proposal is a completely different language with many new keywords and
 operators.

 I came away deciding to stop using |prototype| + new in favor of
 Object.create() and to revisit the traits.org library after a bit.

 jjb


 ___
 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: On I got 99 problems and JavaScript syntax ain't one

2011-10-05 Thread Lasse Reichstein
On Tue, Oct 4, 2011 at 6:19 PM, David Bruant david.bru...@labri.fr wrote:

 **
 I sent a message here explaining the necessity of a syntax construct for a
 reliable bind [1]. There is a need to investingate (one reply was very close
 from a solution) to make sure that such a thing is not possible in pure ES5
 (without making Function.prototype.bind non-configurable), but that would be
 one such thing that no language compiling to JavaScript could emulate (since
 impossible in the language itself).


I don't think security from malicious changes to Function.prototype.bind
is a good argument for adding new operator syntax.

The problem doesn't stop with Function.prototype.bind. ES5 as a compilation
target is built on a quagmire since almost all fundamental language
operations are methods that can be changed. The operators are the exception,
since you can't override their meaning[1], and I can see why you wish to
introduce modification-safe operators for the operations you want to
preserve - but why is Function.prototype.bind more important than, say,
Math.pow? In the wrong hands, I'm sure you can subvert an encryption
algorithm with a malicious Math.pow. We can't have operators for all
functions, and you can't check every function before using it (and it
wouldn't help if you could).

Also, with proxies and getters/setters, even operators aren't guaranteed to
be safe unless they are defined extremely carefully. It used to be that
property access (o.foo) was a safe way to look up a property on an
object. Now it might trigger a proxy or accessor instead. This has actually
diluted the safety of operators. Will new operators that seem safe now be
diluted the same way in the future?

With ES5 getters and (inherited!) setters, you can install a javascript
rootkit that modifies some of the builtins, perhaps put some selected
getters/setters on Object.prototype, and hides every trace of it from other
scripts.
To prevent that kind of maliciousness, you need to go the way of SES and
lock down the entire environment *before* any untrusted code is touched, and
in that case Function.prototype.bind is just as safe as an operator.


(On the other hand, it's actually a fun experience to write Javascript code
that can't be affected by a modified environment - the same way three-legged
races are fun :)

Personally, I'd prefer all the built-in functions to be unconfigurable, so a
language user would actually know what function they are calling ahead of
time.

/L 'Freeze them! Freeze them all!'

[1] But the operators can potentially do type coercion that allows arbitrary
side-effects at unexpected times.
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: On I got 99 problems and JavaScript syntax ain't one

2011-10-05 Thread David Bruant

Le 05/10/2011 10:17, Lasse Reichstein a écrit :
On Tue, Oct 4, 2011 at 6:19 PM, David Bruant david.bru...@labri.fr 
mailto:david.bru...@labri.fr wrote:


I sent a message here explaining the necessity of a syntax
construct for a reliable bind [1]. There is a need to investingate
(one reply was very close from a solution) to make sure that such
a thing is not possible in pure ES5 (without making
Function.prototype.bind non-configurable), but that would be one
such thing that no language compiling to JavaScript could emulate
(since impossible in the language itself).


I don't think security from malicious changes to 
Function.prototype.bind is a good argument for adding new operator 
syntax.


The problem doesn't stop with Function.prototype.bind. ES5 as a 
compilation target is built on a quagmire since almost all fundamental 
language operations are methods that can be changed. The operators are 
the exception, since you can't override their meaning[1], and I can 
see why you wish to introduce modification-safe operators for the 
operations you want to preserve - but why is Function.prototype.bind 
more important than, say, Math.pow?
The difference I saw is that you can keep a reference to Math.pow within 
a scope of yours and you'll be fine. Such a thing doesn't seem possible 
with call, apply and bind, mostly because you need to rely on at least 
one of them in order to do call.call or call.bind, etc. and 
consequently, you always depend on the value on Function.prototype.* in 
a way or another.


As i said before, there is a reliable way to do a call which is f(), but 
you can't choose the value of |this|. That's what originally motivated 
the idea of a syntax-based bind.


I don't think that the other functions require such a thing.

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


Re: On I got 99 problems and JavaScript syntax ain't one

2011-10-05 Thread Mark S. Miller
Since you're assuming you can initialize and grab stuff before your context
is corrupted, what's wrong with Lasse's earlier (and very clever!)

var call = Function.prototype.call.bind(Function.prototype.call);

and by direct analogy:

var apply = Function.prototype.call.bind(Function.prototype.apply);
var bind = Function.prototype.call.bind(Function.prototype.bind);

?

If there's a vulnerability with this technique, I need to know that asap, as
I'm about to start writing code that depends on it for security. So any
vulnerabilities you or anyone can point out now will be greatly appreciated.
Thanks.


On Wed, Oct 5, 2011 at 10:24 AM, David Bruant david.bru...@labri.fr wrote:

 **
 Le 05/10/2011 10:17, Lasse Reichstein a écrit :

 On Tue, Oct 4, 2011 at 6:19 PM, David Bruant david.bru...@labri.frwrote:

 I sent a message here explaining the necessity of a syntax construct for a
 reliable bind [1]. There is a need to investingate (one reply was very close
 from a solution) to make sure that such a thing is not possible in pure ES5
 (without making Function.prototype.bind non-configurable), but that would be
 one such thing that no language compiling to JavaScript could emulate (since
 impossible in the language itself).


  I don't think security from malicious changes to
 Function.prototype.bind is a good argument for adding new operator syntax.

  The problem doesn't stop with Function.prototype.bind. ES5 as a
 compilation target is built on a quagmire since almost all fundamental
 language operations are methods that can be changed. The operators are the
 exception, since you can't override their meaning[1], and I can see why you
 wish to introduce modification-safe operators for the operations you want to
 preserve - but why is Function.prototype.bind more important than, say,
 Math.pow?

 The difference I saw is that you can keep a reference to Math.pow within a
 scope of yours and you'll be fine. Such a thing doesn't seem possible with
 call, apply and bind, mostly because you need to rely on at least one of
 them in order to do call.call or call.bind, etc. and consequently, you
 always depend on the value on Function.prototype.* in a way or another.

 As i said before, there is a reliable way to do a call which is f(), but
 you can't choose the value of |this|. That's what originally motivated the
 idea of a syntax-based bind.

 I don't think that the other functions require such a thing.

 David

 ___
 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: On I got 99 problems and JavaScript syntax ain't one

2011-10-05 Thread David Bruant

Le 05/10/2011 10:33, Mark S. Miller a écrit :
Since you're assuming you can initialize and grab stuff before your 
context is corrupted, what's wrong with Lasse's earlier (and very 
clever!)


var call = Function.prototype.call.bind(Function.prototype.call);

and by direct analogy:

var apply = Function.prototype.call.bind(Function.prototype.apply);
var bind = Function.prototype.call.bind(Function.prototype.bind);

?

Nothing's wrong. I forgot about this, sorry. It is indeed very clever.
I take back what I said about the necessity of a syntax construct for bind.

David



If there's a vulnerability with this technique, I need to know that 
asap, as I'm about to start writing code that depends on it for 
security. So any vulnerabilities you or anyone can point out now will 
be greatly appreciated. Thanks.



On Wed, Oct 5, 2011 at 10:24 AM, David Bruant david.bru...@labri.fr 
mailto:david.bru...@labri.fr wrote:


Le 05/10/2011 10:17, Lasse Reichstein a écrit :

On Tue, Oct 4, 2011 at 6:19 PM, David Bruant
david.bru...@labri.fr mailto:david.bru...@labri.fr wrote:

I sent a message here explaining the necessity of a syntax
construct for a reliable bind [1]. There is a need to
investingate (one reply was very close from a solution) to
make sure that such a thing is not possible in pure ES5
(without making Function.prototype.bind non-configurable),
but that would be one such thing that no language compiling
to JavaScript could emulate (since impossible in the language
itself).


I don't think security from malicious changes to
Function.prototype.bind is a good argument for adding new
operator syntax.

The problem doesn't stop with Function.prototype.bind. ES5 as a
compilation target is built on a quagmire since almost all
fundamental language operations are methods that can be changed.
The operators are the exception, since you can't override their
meaning[1], and I can see why you wish to introduce
modification-safe operators for the operations you want to
preserve - but why is Function.prototype.bind more important
than, say, Math.pow?

The difference I saw is that you can keep a reference to Math.pow
within a scope of yours and you'll be fine. Such a thing doesn't
seem possible with call, apply and bind, mostly because you need
to rely on at least one of them in order to do call.call or
call.bind, etc. and consequently, you always depend on the value
on Function.prototype.* in a way or another.

As i said before, there is a reliable way to do a call which is
f(), but you can't choose the value of |this|. That's what
originally motivated the idea of a syntax-based bind.

I don't think that the other functions require such a thing.

David

___
es-discuss mailing list
es-discuss@mozilla.org mailto: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: On I got 99 problems and JavaScript syntax ain't one

2011-10-05 Thread Andrea Giammarchi
dunno how we ended up here but I would rather use this approach in a private
scope:

var
// used to trap function calls via bind
invoke = Function.call,
// normal use cases
bind = invoke.bind(invoke.bind),
apply = bind(invoke, invoke.apply),
call = bind(invoke, invoke)
;

var hasOwnProperty = bind(invoke, {}.hasOwnProperty);

hasOwnProperty({key:1}, key); // true
call([].slice, [1,2,3], 1); // 2,3
apply([].slice, [1,2,3], [1]);  // 2,3

Regards,
Andrea Giammarchi
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: On I got 99 problems and JavaScript syntax ain't one (was: OnIncremental Updates)

2011-10-05 Thread Claus Reinke

Just walk the object graph starting from the root object and let the
set of all reachable symbols be A.
Load jQuery
Walk the object graph again letting the set of all reachable symbols be
B.
The public API of jQuery is then (B - A).


That's works fine under 2 conditions:
1. You're willing to execute code instead of statically analyze it
2. You're capable of executing that code in isolation.


This should be true for most libraries out there.
It obviously doesn't hold for user code and definitely not for all
code in an IDE since IDE's have to deal with code during editing.


One standard way around this dilemma is to execute such code
abstractly (known as abstract interpretation). What that means is
that the code is run through an alternative engine that does not
execute the code in full detail, but only as far as necessary in order
to infer some interesting properties.

In particular, one wants the abstract interpretation not to have
side-effects (like network or file system operations) and one wants
it to terminate (quickly; so branches and recursion tend to be
approximated).

Unfortunately, interesting properties tend to be undecidable, ie,
they cannot be extracted from arbitrary code while guaranteeing
termination (oversimplifying: you have to run such code in full
to find out what it does..).

There is no magic cure for this, but it is possible to design
languages and programs in such a way that a practically
relevant subset of the properties of interest becomes decidable.
Doing that requires thought and a lot of work (and open minds
to begin with), but the benefits tend to be worth it.

Without support from language and program designers, it does
not matter how many companies throw how much money at tool
development (no magic bullets). Unless you want to find out how
much money they are willing or able to throw before they start
throwing towels.

Support is not so much about syntax as it is about statically
recognizable programming patterns (so that one can distinguish
code with arbitrary effects from code that just adds properties to
a class of objects, or export items to a module; and so that one
can extract useful program properties without having to run the
code in full).

The reason syntax tends to be mentioned is because syntax frozen
in the language spec tends to be less flexible than general code
implementing the same feature in the language. So it looks easier
to analyze, and cannot be re-defined (in current JS).

But adding this kind of special-case syntax makes a language
more complex, by adding lots of constructs that -by design- do
not support the full expressiveness of the language. Other
languages have demonstrated that one can fix programming
patterns sufficiently to permit analysis, without fixing syntax
(added bonus: less syntax, less complexity -easier for coders
and tools to read/analyze- and more general usage patterns
through homogeneous syntax with few special cases).

For this particular problem (improving analysis support), syntax
is the wrong level to work at, but in order to see that, one would
have to make an effort to work with modern type systems - why
they work, and how that interacts with language and program
design. To begin with, one can think of a type system as an
abstract interpretation engine with enhanced information flow,
and of types as program properties.

Also, if coders can express their intentions (do they really mean
an object, or a record, or a map, or an array, ..?), it tends to be
easier to check whether an implementation matches those
intentions (within the limits of decidability, so one is usually
looking at guaranteeing invariants) than to guess what those
intentions were in the first place (is this a function or a method
and should we give it dynamic super or not? are objects from
this constructor expected to retain a certain set of properties
or can they change arbitrarily? is this function going to spider
the web, or will it just add a few methods to an object? can
we rely on function F to be the one in the spec, or could it
have been overwritten?).

It would be great if vocal JS coders with strongly expressed
opinions (often in error, never in doubt) could try a language
like Haskell for a mini project. Don't worry about advanced
features, just convince yourself that a static type system does
not have to get in the way as often as one might expect.

Then, for your second project, start thinking about what you
and the language have to do to make better use of types,
rather than just get your code to compile: where do you have
to change your coding patterns, compared to what you would
do in JS, and how does that help the type system?

After taking these two steps (*), you will be ready to think
about the pros and cons of syntax or types for helping JS tools
with code analysis. And then about how this should affect JS
language design. The basics don't require a big effort, but one
should allow that type/analysis research has not been idle in
the 

Re: On I got 99 problems and JavaScript syntax ain't one

2011-10-05 Thread John J Barton
On Tue, Oct 4, 2011 at 2:33 PM, Bob Nystrom rnyst...@google.com wrote:



 On Tue, Oct 4, 2011 at 2:12 PM, John J Barton johnjbar...@johnjbarton.com
  wrote:



 On Tue, Oct 4, 2011 at 12:59 PM, Bob Nystrom rnyst...@google.com wrote:


 A constructor is different from a regular function. Instead of returning
 the value that the body of the function returns, it returns a special
 newly-created object.


 Sorry, already you lost me ;-)  I guess you mean the operand of new? If
 so, then the different thing is the operator 'new'. It's new that makes
 the operand a constructor.


 It's the yield that makes a function a generator. One is visible at the
 callsite (which means you can *forget* it at the callsite), the other is
 visible at the definition.





 Likewise, a generator is a special function that doesn't return what the
 body returns.


 But it does not look special. There is nothing similar to 'new' involved
 in the invocation of the generator.


 That's good because it means whether or not a function returns an iterable
 object by using yield or through some other means is an implementation
 detail of the function and doesn't bleed into every callsite. Let's say
 generators *did* have a callsite difference. Now imagine:

 function countdown() {
   for (let i = 10; i = 1; i--) yield i;
 }

 let counter = generate countdown(); // -- in callsite
 for (let i of counter) alert(i);
 alert('boom!');

 This magic generate keyword means the function is to be treated like a
 generator. But then later it turns out that -- is really slow and you want
 to change countdown to:

 function countdown() {
   return [10, 9, 8, 7, 6, 5, 4, 3, 2, 1];
 }

 Well, you can't. You'd have to fix each callsite too. Your abstraction has
 leaked. So I think generators do the right thing here. (And, conversely, I
 kind of think constructors do the *wrong* thing.)


We can agree that |new| is a mess even if we don't agree on generators.



 and the state of the generator is hidden from the developer as far as I can
 tell.


 That's correct. That's often the cost of concision. By analogy: you can do
 a lot of stuff using either an explicit stack data structure or recursion.
 Using recursion is often more concise but then the state is hidden from you
 in the callstack. Sometimes that's a good trade-off, sometimes it's not.


Thanks, that analogy helps confirm my opinion of generators. In my
experience, the good trade-off is recursion on data structures and the
not-good-trade-off is recursion for iteration.  So far the only examples
I've seen for generators involve iteration.




 I think generators are an excellent example of a feature that is well
 prototyped (in FF JS 1.7+). I think the developer uptake is minimal, outside
 of the original advocates. I don't hear any clamor for other browsers to
 implement this feature.


 Browsers don't clamor, users do. If it was up to the browsers, they
 wouldn't implement anything. Implementing is hard work!


I've heard no clamor at all. Really this is a niche feature, an aid for the
rare case where conventional iterators are a poor match.

jjb



 In languages that do have yield (Python, C#, and Lua are the ones I know)
 it's used pretty frequently and without complaint.

 Either way, class deserves at least as much investigation.


 Agreed!

 - bob


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


Re: On I got 99 problems and JavaScript syntax ain't one (was: On Incremental Updates)

2011-10-05 Thread John J Barton
On Tue, Oct 4, 2011 at 10:26 AM, Mike Samuel mikesam...@gmail.com wrote:

 2011/10/4 Russell Leggett russell.legg...@gmail.com:
  On Tue, Oct 4, 2011 at 12:51 PM, Mike Samuel mikesam...@gmail.com
 wrote:
 
  No it doesn't.
 
  Just walk the object graph starting from the root object and let the
  set of all reachable symbols be A.
  Load jQuery
  Walk the object graph again letting the set of all reachable symbols be
 B.
 
  The public API of jQuery is then (B - A).
 
  That's works fine under 2 conditions:
 
  1. You're willing to execute code instead of statically analyze it
  2. You're capable of executing that code in isolation.

 This should be true for most libraries out there.
 It obviously doesn't hold for user code and definitely not for all
 code in an IDE since IDE's have to deal with code during editing.


I'm not a jQuery person, but as far as I can tell jQuery introduces only one
global value so the jQuery API is just the properties of that object at the
point in the program where the developer needs to use jQuery.  You don't
have to execute code and the only graph you need to walk is the properties
of one object.

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


Re: traits feedback

2011-10-05 Thread John J Barton
On Wed, Oct 5, 2011 at 12:52 AM, Tom Van Cutsem tomvc...@gmail.com wrote:

 Thanks for the feedback, John.

 I have to admit that at first I was also taken aback by the apparent
 complexity of the syntax for efficient traits strawman. Traits have many
 knobs, and require a lot of syntax to turn these knobs.

 Regardless of whether you'd want nice declarative syntax for traits for the
 sake of usability, for traits.js in particular, there's another important
 benefit to having some language support. When using Trait.create to create
 tamper-proof objects whose methods have an unspoofable |this|-binding, the
 traits.js library creates a method wrapper per method per instance (to bind
 |this| to the instance). I still need to verify how much overhead this
 actually creates, but there definitely is overhead, and I don't see any way
 to avoid it without some support from the language.


Yes I sensed your anguish about this issue. However I believe experimental
measurements might surprise you. Lots of JS code involves event handlers
passed into DOM calls. I bet lots of JS code already duplicates methods and
bind |this|.  Only when you have many instances will this overhead matter,
and in those cases I think you might be better off without OOP anyway.

jjb


 Cheers,
 Tom

 2011/10/5 John J Barton johnjbar...@johnjbarton.com

 In trying to update my JS approach I looked into 'traits'. I'm still on
 the fence about using them at this stage, but MarkM was asking for feedback
 of pretty much any kind so here is a little.

 I believe I understand traits for the most part just from the info on the
 Web site:
 http://traitsjs.org/
 (but read the examples in the Paper, not the one in the Tutorial).
 Traits feel like JS to me: a reusable set of methods packaged in an
 object. The Trait construct add regularity and organization to a wide-spread
 pattern of JS use, but it feels like a tool you pick up when you need it.
 The key operations are create and compose, with resolve and override to
 handle exotic issues.

 On the other hand I had the opposite reaction to

 http://wiki.ecmascript.org/doku.php?id=strawman:syntax_for_efficient_traits
 That proposal is a completely different language with many new keywords
 and operators.

 I came away deciding to stop using |prototype| + new in favor of
 Object.create() and to revisit the traits.org library after a bit.

 jjb


 ___
 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: On I got 99 problems and JavaScript syntax ain't one (was: On Incremental Updates)

2011-10-05 Thread Russell Leggett
On Wed, Oct 5, 2011 at 10:32 AM, John J Barton
johnjbar...@johnjbarton.com wrote:


 On Tue, Oct 4, 2011 at 10:26 AM, Mike Samuel mikesam...@gmail.com wrote:

 2011/10/4 Russell Leggett russell.legg...@gmail.com:
  On Tue, Oct 4, 2011 at 12:51 PM, Mike Samuel mikesam...@gmail.com
  wrote:
 
  No it doesn't.
 
  Just walk the object graph starting from the root object and let the
  set of all reachable symbols be A.
  Load jQuery
  Walk the object graph again letting the set of all reachable symbols be
  B.
 
  The public API of jQuery is then (B - A).
 
  That's works fine under 2 conditions:
 
  1. You're willing to execute code instead of statically analyze it
  2. You're capable of executing that code in isolation.

 This should be true for most libraries out there.
 It obviously doesn't hold for user code and definitely not for all
 code in an IDE since IDE's have to deal with code during editing.

 I'm not a jQuery person, but as far as I can tell jQuery introduces only one
 global value so the jQuery API is just the properties of that object at the
 point in the program where the developer needs to use jQuery.  You don't
 have to execute code and the only graph you need to walk is the properties
 of one object.

If you looked at the code for more than 5 minutes, you'd see that the
jQuery codebase, while interesting to look at, would be ridiculously
hard to statically analyze without understanding jQuery conventions.
The bulk of the methods are added through calls to 'jQuery.extend(...'
and 'jQuery.fn.extend(...'


 jjb

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


Re: On I got 99 problems and JavaScript syntax ain't one (was: On Incremental Updates)

2011-10-05 Thread John J Barton
On Wed, Oct 5, 2011 at 7:49 AM, Russell Leggett
russell.legg...@gmail.comwrote:

 On Wed, Oct 5, 2011 at 10:32 AM, John J Barton
 johnjbar...@johnjbarton.com wrote:
 
 
  On Tue, Oct 4, 2011 at 10:26 AM, Mike Samuel mikesam...@gmail.com
 wrote:
 
  2011/10/4 Russell Leggett russell.legg...@gmail.com:
   On Tue, Oct 4, 2011 at 12:51 PM, Mike Samuel mikesam...@gmail.com
   wrote:
  
   No it doesn't.
  
   Just walk the object graph starting from the root object and let the
   set of all reachable symbols be A.
   Load jQuery
   Walk the object graph again letting the set of all reachable symbols
 be
   B.
  
   The public API of jQuery is then (B - A).
  
   That's works fine under 2 conditions:
  
   1. You're willing to execute code instead of statically analyze it
   2. You're capable of executing that code in isolation.
 
  This should be true for most libraries out there.
  It obviously doesn't hold for user code and definitely not for all
  code in an IDE since IDE's have to deal with code during editing.
 
  I'm not a jQuery person, but as far as I can tell jQuery introduces only
 one
  global value so the jQuery API is just the properties of that object at
 the
  point in the program where the developer needs to use jQuery.  You don't
  have to execute code and the only graph you need to walk is the
 properties
  of one object.

 If you looked at the code for more than 5 minutes, you'd see that the
 jQuery codebase, while interesting to look at, would be ridiculously
 hard to statically analyze without understanding jQuery conventions.
 The bulk of the methods are added through calls to 'jQuery.extend(...'
 and 'jQuery.fn.extend(...'


Sure, that's the way lots of JS code works, which is why I think IDEs based
on static analysis are doomed.

jjb


 
  jjb
 

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


Re: On I got 99 problems and JavaScript syntax ain't one (was: On Incremental Updates)

2011-10-05 Thread Russell Leggett
On Wed, Oct 5, 2011 at 10:52 AM, John J Barton
johnjbar...@johnjbarton.com wrote:


 On Wed, Oct 5, 2011 at 7:49 AM, Russell Leggett russell.legg...@gmail.com
 wrote:

 On Wed, Oct 5, 2011 at 10:32 AM, John J Barton
 johnjbar...@johnjbarton.com wrote:
 
 
  On Tue, Oct 4, 2011 at 10:26 AM, Mike Samuel mikesam...@gmail.com
  wrote:
 
  2011/10/4 Russell Leggett russell.legg...@gmail.com:
   On Tue, Oct 4, 2011 at 12:51 PM, Mike Samuel mikesam...@gmail.com
   wrote:
  
   No it doesn't.
  
   Just walk the object graph starting from the root object and let the
   set of all reachable symbols be A.
   Load jQuery
   Walk the object graph again letting the set of all reachable symbols
   be
   B.
  
   The public API of jQuery is then (B - A).
  
   That's works fine under 2 conditions:
  
   1. You're willing to execute code instead of statically analyze it
   2. You're capable of executing that code in isolation.
 
  This should be true for most libraries out there.
  It obviously doesn't hold for user code and definitely not for all
  code in an IDE since IDE's have to deal with code during editing.
 
  I'm not a jQuery person, but as far as I can tell jQuery introduces only
  one
  global value so the jQuery API is just the properties of that object at
  the
  point in the program where the developer needs to use jQuery.  You don't
  have to execute code and the only graph you need to walk is the
  properties
  of one object.

 If you looked at the code for more than 5 minutes, you'd see that the
 jQuery codebase, while interesting to look at, would be ridiculously
 hard to statically analyze without understanding jQuery conventions.
 The bulk of the methods are added through calls to 'jQuery.extend(...'
 and 'jQuery.fn.extend(...'


 Sure, that's the way lots of JS code works, which is why I think IDEs based
 on static analysis are doomed.

I was responding to:

  You don't have to execute code and the only graph you need to walk is the
  properties of one object.

If you don't execute code, that's what static analysis is. I'm sorry,
I must be missing something. And the way that jQuery (and any JS code
that use a function of some kind to make classes) builds up its api is
to use some helper methods, beyond which, static analysis has a really
rough time. You don't seem to be disagreeing with me.


 jjb


 
  jjb
 


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


Re: traits feedback

2011-10-05 Thread Dean Landolt
On Wed, Oct 5, 2011 at 10:48 AM, John J Barton
johnjbar...@johnjbarton.comwrote:



 On Wed, Oct 5, 2011 at 12:52 AM, Tom Van Cutsem tomvc...@gmail.comwrote:

 Thanks for the feedback, John.

 I have to admit that at first I was also taken aback by the apparent
 complexity of the syntax for efficient traits strawman. Traits have many
 knobs, and require a lot of syntax to turn these knobs.

 Regardless of whether you'd want nice declarative syntax for traits for
 the sake of usability, for traits.js in particular, there's another
 important benefit to having some language support. When using Trait.create
 to create tamper-proof objects whose methods have an unspoofable
 |this|-binding, the traits.js library creates a method wrapper per method
 per instance (to bind |this| to the instance). I still need to verify how
 much overhead this actually creates, but there definitely is overhead, and I
 don't see any way to avoid it without some support from the language.


 Yes I sensed your anguish about this issue. However I believe experimental
 measurements might surprise you. Lots of JS code involves event handlers
 passed into DOM calls. I bet lots of JS code already duplicates methods and
 bind |this|.  Only when you have many instances will this overhead matter,
 and in those cases I think you might be better off without OOP anyway.



It's been measured:
https://mail.mozilla.org/pipermail/es-discuss/2010-September/011821.html
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: traits feedback

2011-10-05 Thread John J Barton
On Wed, Oct 5, 2011 at 8:21 AM, Dean Landolt d...@deanlandolt.com wrote:



 On Wed, Oct 5, 2011 at 10:48 AM, John J Barton 
 johnjbar...@johnjbarton.com wrote:



 On Wed, Oct 5, 2011 at 12:52 AM, Tom Van Cutsem tomvc...@gmail.comwrote:

 Thanks for the feedback, John.

 I have to admit that at first I was also taken aback by the apparent
 complexity of the syntax for efficient traits strawman. Traits have many
 knobs, and require a lot of syntax to turn these knobs.

 Regardless of whether you'd want nice declarative syntax for traits for
 the sake of usability, for traits.js in particular, there's another
 important benefit to having some language support. When using Trait.create
 to create tamper-proof objects whose methods have an unspoofable
 |this|-binding, the traits.js library creates a method wrapper per method
 per instance (to bind |this| to the instance). I still need to verify how
 much overhead this actually creates, but there definitely is overhead, and I
 don't see any way to avoid it without some support from the language.


 Yes I sensed your anguish about this issue. However I believe experimental
 measurements might surprise you. Lots of JS code involves event handlers
 passed into DOM calls. I bet lots of JS code already duplicates methods and
 bind |this|.  Only when you have many instances will this overhead matter,
 and in those cases I think you might be better off without OOP anyway.



 It's been measured:
 https://mail.mozilla.org/pipermail/es-discuss/2010-September/011821.html

 Well that reference says it was tried once in an undocumented way by one
team focused on other things. Falls short of 'measured' for me.

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


String concatenation

2011-10-05 Thread Axel Rauschmayer
Is this worthy of ES.next support? Or does it belong into a library?

The two concatenation approaches I know of are:
1. via +=
2. push() into an array, join() it after the last push()

(1) can’t possibly be efficient, but if (2) is OK on all(!) platforms, then a 
library would be OK. However, given how frequently this is used, I would like 
this to become part of the standard library.

-- 
Dr. Axel Rauschmayer

a...@rauschma.de
twitter.com/rauschma

home: rauschma.de
blog: 2ality.com



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


Re: On I got 99 problems and JavaScript syntax ain't one (was: On Incremental Updates)

2011-10-05 Thread Andrea Giammarchi
Here again I am not sure how we ended up with this conversation but you can
find a function able to extract properties and methods out of a generic
object:

https://gist.github.com/1264775

It works with jQuery too, as well as arrays, etc etc

Regards,
  Andrea Giammarchi
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: On I got 99 problems and JavaScript syntax ain't one (was: On Incremental Updates)

2011-10-05 Thread John J Barton
On Wed, Oct 5, 2011 at 8:05 AM, Russell Leggett
russell.legg...@gmail.comwrote:

 On Wed, Oct 5, 2011 at 10:52 AM, John J Barton
 johnjbar...@johnjbarton.com wrote:
 
 
  On Wed, Oct 5, 2011 at 7:49 AM, Russell Leggett 
 russell.legg...@gmail.com
  wrote:
 
  On Wed, Oct 5, 2011 at 10:32 AM, John J Barton
  johnjbar...@johnjbarton.com wrote:
  
  
   On Tue, Oct 4, 2011 at 10:26 AM, Mike Samuel mikesam...@gmail.com
   wrote:
  
   2011/10/4 Russell Leggett russell.legg...@gmail.com:
On Tue, Oct 4, 2011 at 12:51 PM, Mike Samuel mikesam...@gmail.com
 
wrote:
   
No it doesn't.
   
Just walk the object graph starting from the root object and let
 the
set of all reachable symbols be A.
Load jQuery
Walk the object graph again letting the set of all reachable
 symbols
be
B.
   
The public API of jQuery is then (B - A).
   
That's works fine under 2 conditions:
   
1. You're willing to execute code instead of statically analyze it
2. You're capable of executing that code in isolation.
  
   This should be true for most libraries out there.
   It obviously doesn't hold for user code and definitely not for all
   code in an IDE since IDE's have to deal with code during editing.
  
   I'm not a jQuery person, but as far as I can tell jQuery introduces
 only
   one
   global value so the jQuery API is just the properties of that object
 at
   the
   point in the program where the developer needs to use jQuery.  You
 don't
   have to execute code and the only graph you need to walk is the
   properties
   of one object.
 
  If you looked at the code for more than 5 minutes, you'd see that the
  jQuery codebase, while interesting to look at, would be ridiculously
  hard to statically analyze without understanding jQuery conventions.
  The bulk of the methods are added through calls to 'jQuery.extend(...'
  and 'jQuery.fn.extend(...'
 
 
  Sure, that's the way lots of JS code works, which is why I think IDEs
 based
  on static analysis are doomed.

 I was responding to:

   You don't have to execute code and the only graph you need to walk is
 the
   properties of one object.

 If you don't execute code, that's what static analysis is. I'm sorry,
 I must be missing something. And the way that jQuery (and any JS code
 that use a function of some kind to make classes) builds up its api is
 to use some helper methods, beyond which, static analysis has a really
 rough time. You don't seem to be disagreeing with me.


Oh I got burnt by static analysis before, I should know better. I keep
thinking that static analysis means analysis of a single compilation unit
outside of the runtime as most IDEs for statically typed languages use.

I meant: if your tool is embedded in the run time then it knows the exact
jQuery API because it can scan the exact jQuery object. No code on this
jQuery object needs to run (though that issue is not a show stopper in
practice, witness breakpoint debugging).

I don't know what to call runtime analysis that does not run extraneous
code.

jjb




 
  jjb
 
 
  
   jjb
  
 
 

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


Re: On I got 99 problems and JavaScript syntax ain't one (was: On Incremental Updates)

2011-10-05 Thread Russell Leggett
On Wed, Oct 5, 2011 at 11:48 AM, Andrea Giammarchi
andrea.giammar...@gmail.com wrote:
 Here again I am not sure how we ended up with this conversation but you can
 find a function able to extract properties and methods out of a generic
 object:
 https://gist.github.com/1264775
 It works with jQuery too, as well as arrays, etc etc
 Regards,
   Andrea Giammarchi

Its a nice snippet, but it does require executing the code. It clearly
operates on an object in running code, not an AST. Sorry, I guess I
just don't understand where this thread is going.. :)

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


Re: On I got 99 problems and JavaScript syntax ain't one (was: On Incremental Updates)

2011-10-05 Thread John J Barton
On Wed, Oct 5, 2011 at 8:57 AM, Russell Leggett
russell.legg...@gmail.comwrote:

 On Wed, Oct 5, 2011 at 11:48 AM, Andrea Giammarchi
 andrea.giammar...@gmail.com wrote:
  Here again I am not sure how we ended up with this conversation but you
 can
  find a function able to extract properties and methods out of a generic
  object:
  https://gist.github.com/1264775
  It works with jQuery too, as well as arrays, etc etc
  Regards,
Andrea Giammarchi

 Its a nice snippet, but it does require executing the code. It clearly
 operates on an object in running code, not an AST. Sorry, I guess I
 just don't understand where this thread is going.. :)


We are trying to convince you that limiting your analysis to ASTs will limit
the scope of your tools ;-).

jjb



 - Russ

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


Re: On I got 99 problems and JavaScript syntax ain't one (was: On Incremental Updates)

2011-10-05 Thread Andrea Giammarchi
with such dynamic language I would never trust much AST

This is for realtime, inline, methods and properties suggestion and it's
kinda fast as macro/inspector

I don't know where the thread is going either :-)

On Wed, Oct 5, 2011 at 5:57 PM, Russell Leggett
russell.legg...@gmail.comwrote:

 On Wed, Oct 5, 2011 at 11:48 AM, Andrea Giammarchi
 andrea.giammar...@gmail.com wrote:
  Here again I am not sure how we ended up with this conversation but you
 can
  find a function able to extract properties and methods out of a generic
  object:
  https://gist.github.com/1264775
  It works with jQuery too, as well as arrays, etc etc
  Regards,
Andrea Giammarchi

 Its a nice snippet, but it does require executing the code. It clearly
 operates on an object in running code, not an AST. Sorry, I guess I
 just don't understand where this thread is going.. :)

 - Russ

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


Re: String concatenation

2011-10-05 Thread Dean Landolt
On Wed, Oct 5, 2011 at 11:45 AM, Axel Rauschmayer a...@rauschma.de wrote:

 Is this worthy of ES.next support? Or does it belong into a library?

 The two concatenation approaches I know of are:
 1. via +=
 2. push() into an array, join() it after the last push()

 (1) can’t possibly be efficient,


Huh? Engines have optimized the hell out of 1 by essentially doing 2 under
the hood. Even rhino's about a land a patch to do just that.


 but if (2) is OK on all(!) platforms, then a library would be OK. However,
 given how frequently this is used, I would like this to become part of the
 standard library.


What exactly do you want supported?
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: String concatenation

2011-10-05 Thread Dmitry Soshnikov

On 05.10.2011 19:45, Axel Rauschmayer wrote:

Is this worthy of ES.next support? Or does it belong into a library?

The two concatenation approaches I know of are:
1. via +=
2. push() into an array, join() it after the last push()

(1) can’t possibly be efficient, but if (2) is OK on all(!) platforms, then a 
library would be OK. However, given how frequently this is used, I would like 
this to become part of the standard library.


15.5.4.6 String.prototype.concat

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


Re: String concatenation

2011-10-05 Thread Axel Rauschmayer
 The two concatenation approaches I know of are:
 1. via +=
 2. push() into an array, join() it after the last push()
 
 (1) can’t possibly be efficient,
 
 Huh? Engines have optimized the hell out of 1 by essentially doing 2 under 
 the hood. Even rhino's about a land a patch to do just that.
  
 but if (2) is OK on all(!) platforms, then a library would be OK. However, 
 given how frequently this is used, I would like this to become part of the 
 standard library.
 
 What exactly do you want supported?

Something like Java’s StringBuilder. If, however, (2) collects the concatenated 
substrings and only joins them on demand in current engines, then there is 
indeed no need for such a thing.


-- 
Dr. Axel Rauschmayer

a...@rauschma.de
twitter.com/rauschma

home: rauschma.de
blog: 2ality.com



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


Re: On I got 99 problems and JavaScript syntax ain't one (was: On Incremental Updates)

2011-10-05 Thread Russell Leggett
On Wed, Oct 5, 2011 at 11:49 AM, John J Barton
johnjbar...@johnjbarton.com wrote:


 On Wed, Oct 5, 2011 at 8:05 AM, Russell Leggett russell.legg...@gmail.com
 wrote:

 On Wed, Oct 5, 2011 at 10:52 AM, John J Barton
 johnjbar...@johnjbarton.com wrote:
 
 
  On Wed, Oct 5, 2011 at 7:49 AM, Russell Leggett
  russell.legg...@gmail.com
  wrote:
 
  On Wed, Oct 5, 2011 at 10:32 AM, John J Barton
  johnjbar...@johnjbarton.com wrote:
  
  
   On Tue, Oct 4, 2011 at 10:26 AM, Mike Samuel mikesam...@gmail.com
   wrote:
  
   2011/10/4 Russell Leggett russell.legg...@gmail.com:
On Tue, Oct 4, 2011 at 12:51 PM, Mike Samuel
mikesam...@gmail.com
wrote:
   
No it doesn't.
   
Just walk the object graph starting from the root object and let
the
set of all reachable symbols be A.
Load jQuery
Walk the object graph again letting the set of all reachable
symbols
be
B.
   
The public API of jQuery is then (B - A).
   
That's works fine under 2 conditions:
   
1. You're willing to execute code instead of statically analyze it
2. You're capable of executing that code in isolation.
  
   This should be true for most libraries out there.
   It obviously doesn't hold for user code and definitely not for all
   code in an IDE since IDE's have to deal with code during editing.
  
   I'm not a jQuery person, but as far as I can tell jQuery introduces
   only
   one
   global value so the jQuery API is just the properties of that object
   at
   the
   point in the program where the developer needs to use jQuery.  You
   don't
   have to execute code and the only graph you need to walk is the
   properties
   of one object.
 
  If you looked at the code for more than 5 minutes, you'd see that the
  jQuery codebase, while interesting to look at, would be ridiculously
  hard to statically analyze without understanding jQuery conventions.
  The bulk of the methods are added through calls to 'jQuery.extend(...'
  and 'jQuery.fn.extend(...'
 
 
  Sure, that's the way lots of JS code works, which is why I think IDEs
  based
  on static analysis are doomed.

 I was responding to:

   You don't have to execute code and the only graph you need to walk is
   the
   properties of one object.

 If you don't execute code, that's what static analysis is. I'm sorry,
 I must be missing something. And the way that jQuery (and any JS code
 that use a function of some kind to make classes) builds up its api is
 to use some helper methods, beyond which, static analysis has a really
 rough time. You don't seem to be disagreeing with me.

 Oh I got burnt by static analysis before, I should know better. I keep
 thinking that static analysis means analysis of a single compilation unit
 outside of the runtime as most IDEs for statically typed languages use.

 I meant: if your tool is embedded in the run time then it knows the exact
 jQuery API because it can scan the exact jQuery object. No code on this
 jQuery object needs to run (though that issue is not a show stopper in
 practice, witness breakpoint debugging).

 I don't know what to call runtime analysis that does not run extraneous
 code.

I see, yes. Yeah, I mean if I run the JavaScript console in chrome I
get nice autocompletion because its using the running environment to
know what properties an object has. I believe this is what a lot of
smalltalk IDEs used to do.

There are still a lot of limitations, though. I mean, what is the
purpose of the analysis in the long run. Modern Java IDEs can do a lot
of things with static analysis that are very helpful like refactoring
and autocompletion. Look, I'm not trying to turn this into a static
vs. dynamic debate, my point is that there are a lot of limitations -
and useful tooling that is impossible with dynamic code. I think we
got here because someone was trying to make the point that the ability
to add statically analyzable constraints would be useful to tooling.
In JavaScript, the way to do that may have to be through syntactic
additions such as extends or |. I'm certainly not opposed to analysis
that goes beyond ASTs. I say, any way you can get it!

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


Re: On I got 99 problems and JavaScript syntax ain't one (was: On Incremental Updates)

2011-10-05 Thread Russell Leggett
On Wed, Oct 5, 2011 at 12:04 PM, Andrea Giammarchi
andrea.giammar...@gmail.com wrote:
 with such dynamic language I would never trust much AST
 This is for realtime, inline, methods and properties suggestion and it's
 kinda fast as macro/inspector
 I don't know where the thread is going either :-)

It would also break as soon as you hit your first function call until
that function got executed. :)

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


Re: String concatenation

2011-10-05 Thread John Tamplin
On Wed, Oct 5, 2011 at 12:10 PM, Axel Rauschmayer a...@rauschma.de wrote:

  The two concatenation approaches I know of are:
 1. via +=
 2. push() into an array, join() it after the last push()

 (1) can’t possibly be efficient,


 Huh? Engines have optimized the hell out of 1 by essentially doing 2 under
 the hood. Even rhino's about a land a patch to do just that.


 but if (2) is OK on all(!) platforms, then a library would be OK. However,
 given how frequently this is used, I would like this to become part of the
 standard library.


 What exactly do you want supported?


 Something like Java’s StringBuilder. If, however, (2) collects the
 concatenated substrings and only joins them on demand in current engines,
 then there is indeed no need for such a thing.


GWT's implementation of StringBuilder actually uses both methods #1 and #2
under the hood, because each is faster on different browsers (due to
deferred binding, you only get the implementation for the browser you are
using and parts of it can be inlined at call sites so you don't pay the
penalty for multiple implementations).

-- 
John A. Tamplin
Software Engineer (GWT), Google
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: On I got 99 problems and JavaScript syntax ain't one

2011-10-05 Thread Dean Landolt
On Wed, Oct 5, 2011 at 10:18 AM, John J Barton
johnjbar...@johnjbarton.comwrote:



 On Tue, Oct 4, 2011 at 2:33 PM, Bob Nystrom rnyst...@google.com wrote:



 On Tue, Oct 4, 2011 at 2:12 PM, John J Barton 
 johnjbar...@johnjbarton.com wrote:



 On Tue, Oct 4, 2011 at 12:59 PM, Bob Nystrom rnyst...@google.comwrote:


 A constructor is different from a regular function. Instead of returning
 the value that the body of the function returns, it returns a special
 newly-created object.


 Sorry, already you lost me ;-)  I guess you mean the operand of new? If
 so, then the different thing is the operator 'new'. It's new that makes
 the operand a constructor.


 It's the yield that makes a function a generator. One is visible at the
 callsite (which means you can *forget* it at the callsite), the other is
 visible at the definition.





 Likewise, a generator is a special function that doesn't return what the
 body returns.


 But it does not look special. There is nothing similar to 'new' involved
 in the invocation of the generator.


 That's good because it means whether or not a function returns an iterable
 object by using yield or through some other means is an implementation
 detail of the function and doesn't bleed into every callsite. Let's say
 generators *did* have a callsite difference. Now imagine:

 function countdown() {
   for (let i = 10; i = 1; i--) yield i;
 }

 let counter = generate countdown(); // -- in callsite
 for (let i of counter) alert(i);
 alert('boom!');

 This magic generate keyword means the function is to be treated like a
 generator. But then later it turns out that -- is really slow and you want
 to change countdown to:

 function countdown() {
   return [10, 9, 8, 7, 6, 5, 4, 3, 2, 1];
 }

 Well, you can't. You'd have to fix each callsite too. Your abstraction has
 leaked. So I think generators do the right thing here. (And, conversely, I
 kind of think constructors do the *wrong* thing.)


 We can agree that |new| is a mess even if we don't agree on generators.



 and the state of the generator is hidden from the developer as far as I
 can tell.


 That's correct. That's often the cost of concision. By analogy: you can do
 a lot of stuff using either an explicit stack data structure or recursion.
 Using recursion is often more concise but then the state is hidden from you
 in the callstack. Sometimes that's a good trade-off, sometimes it's not.


 Thanks, that analogy helps confirm my opinion of generators. In my
 experience, the good trade-off is recursion on data structures and the
 not-good-trade-off is recursion for iteration.  So far the only examples
 I've seen for generators involve iteration.




 I think generators are an excellent example of a feature that is well
 prototyped (in FF JS 1.7+). I think the developer uptake is minimal, outside
 of the original advocates. I don't hear any clamor for other browsers to
 implement this feature.


 Browsers don't clamor, users do. If it was up to the browsers, they
 wouldn't implement anything. Implementing is hard work!


 I've heard no clamor at all. Really this is a niche feature, an aid for the
 rare case where conventional iterators are a poor match.



Generators are more than iteration optimizations -- they enable shallow
frame continuations, and open the doors to some really nice async
programming patterns (just the beginnings of which are demonstrated by Dave
Herman's task.js [1]).

Again, they're not fully implemented in any engine, so library support is
practically non-existent. How are users supposed to clamor for a feature
that can't demonstrate itself as advantageous? I've heard plenty of calls
for language-level async support -- generators enable this without the
well-documented hazards of the alternatives.

[1] https://github.com/dherman/taskjs
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: On I got 99 problems and JavaScript syntax ain't one (was: OnIncremental Updates)

2011-10-05 Thread Russell Leggett
On Wed, Oct 5, 2011 at 10:03 AM, Claus Reinke claus.rei...@talk21.com wrote:
 Just walk the object graph starting from the root object and let the
 set of all reachable symbols be A.
 Load jQuery
 Walk the object graph again letting the set of all reachable symbols be
 B.
 The public API of jQuery is then (B - A).

 That's works fine under 2 conditions:
 1. You're willing to execute code instead of statically analyze it
 2. You're capable of executing that code in isolation.

 This should be true for most libraries out there.
 It obviously doesn't hold for user code and definitely not for all
 code in an IDE since IDE's have to deal with code during editing.

 One standard way around this dilemma is to execute such code
 abstractly (known as abstract interpretation). What that means is
 that the code is run through an alternative engine that does not
 execute the code in full detail, but only as far as necessary in order
 to infer some interesting properties.

 In particular, one wants the abstract interpretation not to have
 side-effects (like network or file system operations) and one wants
 it to terminate (quickly; so branches and recursion tend to be
 approximated).

 Unfortunately, interesting properties tend to be undecidable, ie,
 they cannot be extracted from arbitrary code while guaranteeing
 termination (oversimplifying: you have to run such code in full
 to find out what it does..).

 There is no magic cure for this, but it is possible to design
 languages and programs in such a way that a practically
 relevant subset of the properties of interest becomes decidable.
 Doing that requires thought and a lot of work (and open minds
 to begin with), but the benefits tend to be worth it.

 Without support from language and program designers, it does
 not matter how many companies throw how much money at tool
 development (no magic bullets). Unless you want to find out how
 much money they are willing or able to throw before they start
 throwing towels.

 Support is not so much about syntax as it is about statically
 recognizable programming patterns (so that one can distinguish
 code with arbitrary effects from code that just adds properties to
 a class of objects, or export items to a module; and so that one
 can extract useful program properties without having to run the
 code in full).

 The reason syntax tends to be mentioned is because syntax frozen
 in the language spec tends to be less flexible than general code
 implementing the same feature in the language. So it looks easier
 to analyze, and cannot be re-defined (in current JS).

 But adding this kind of special-case syntax makes a language
 more complex, by adding lots of constructs that -by design- do
 not support the full expressiveness of the language. Other
 languages have demonstrated that one can fix programming
 patterns sufficiently to permit analysis, without fixing syntax
 (added bonus: less syntax, less complexity -easier for coders
 and tools to read/analyze- and more general usage patterns
 through homogeneous syntax with few special cases).

 For this particular problem (improving analysis support), syntax
 is the wrong level to work at, but in order to see that, one would
 have to make an effort to work with modern type systems - why
 they work, and how that interacts with language and program
 design. To begin with, one can think of a type system as an
 abstract interpretation engine with enhanced information flow,
 and of types as program properties.

 Also, if coders can express their intentions (do they really mean
 an object, or a record, or a map, or an array, ..?), it tends to be
 easier to check whether an implementation matches those
 intentions (within the limits of decidability, so one is usually
 looking at guaranteeing invariants) than to guess what those
 intentions were in the first place (is this a function or a method
 and should we give it dynamic super or not? are objects from
 this constructor expected to retain a certain set of properties
 or can they change arbitrarily? is this function going to spider
 the web, or will it just add a few methods to an object? can
 we rely on function F to be the one in the spec, or could it
 have been overwritten?).

I agree with this 100%. Languages as dynamic as JavaScript and Ruby
are interesting, because as much as the freedoms can allow for more
concise code and a level of expression that can often be difficult to
achieve in more statically typed languages, it can also lead to a
place with almost no constraints or guarantees. Sometimes these
guarantees can be remarkably useful for the coder, the compiler, and
the tooling.

 It would be great if vocal JS coders with strongly expressed
 opinions (often in error, never in doubt) could try a language
 like Haskell for a mini project. Don't worry about advanced
 features, just convince yourself that a static type system does
 not have to get in the way as often as one might expect.

I don't think I qualify as a vocal 

Re: On I got 99 problems and JavaScript syntax ain't one (was: On Incremental Updates)

2011-10-05 Thread Andrea Giammarchi
Sorry Russ, I am not sure I got it

On Wed, Oct 5, 2011 at 6:14 PM, Russell Leggett
russell.legg...@gmail.comwrote:

 On Wed, Oct 5, 2011 at 12:04 PM, Andrea Giammarchi
 andrea.giammar...@gmail.com wrote:
  with such dynamic language I would never trust much AST
  This is for realtime, inline, methods and properties suggestion and it's
  kinda fast as macro/inspector
  I don't know where the thread is going either :-)

 It would also break as soon as you hit your first function call until
 that function got executed. :)

 - Russ

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


Minor issues with proxies

2011-10-05 Thread Andreas Rossberg
Hi Mark, Tom!

I understand that you are currently working on finalizing a number of
aspects of the proxies proposal, so I thought I'd send my current
notes on issues I discovered. (Sorry if I'm a bit late with that, but
I just returned from travelling.)

Here is a list of minor issues. I'll send a separate mail describing
what I think is a more fundamental problem with the current spec.

- Proxy.create: What if the handler passed is not an object? Should we
throw right away?

- Proxy.create: What if the prototype passed is neither an object nor
null? FF silently sets it to null in all other cases, but that seems
inconsistent with Object.create, which throws.

- Proxy.createFunction: More of a question, but do we really want to
support a separate construct trap for function proxies? I would argue
that it was a mistake to ever make a distinction between a regular and
a construct call. Even if we cannot clean that up, we should perhaps
avoid having it proliferate further, in the proxy interface.

- Derived get/set traps: They use .call on accessor functions taken
from a user-defined descriptor. Such a function might itself be a
proxy, in which case .call is not necessarily defined. Should invoke
it through Function.prototype.call.call instead. (There may be other
places in the current ES spec that assume that all functions have a
call method. I think they should all be changed.)

- Also, we should specify that the JS code assumes that all used
intrinisc properties are the original methods.

- Object.{seal,freeze,preventExtensions}: When sealing a function
proxy, how do we initialize the standard properties length,
constructor, prototype, caller, and arguments? What if the proxy does
not define them already, or returns unsuitable values?

- Function.prototype.toString: should this work for function proxies?

- Function.prototype.bind: requires additional language explaining how
the length property is set if the curried function is a proxy.

- JSON: don't we need some changes here, too? For example, step 6a of
the JO operation (15.12.3) talks about the names of all the own
properties of an object. Clearly, for a proxy we need to invoke the
appropriate trap here.

- Outside the (current?) standard, but pragmatically, how should we
treat .__proto__ on a proxy? FF and V8 both treat it as an ordinary
property for proxies, but that implies that Object.getPrototypeOf(p)
!= p.__proto__ in general.

- ToStringArray, step 6.a: s/array/O/

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


Proxy-induced impurity of internal methods

2011-10-05 Thread Andreas Rossberg
Proxies invalidate one fundamental assumption of the current ES spec,
namely that (most) internal methods are effectively pure. That has a
couple of consequences which the current proxy proposal and semantics
seem to ignore, but which we need to address.


OBSERVABILITY  EFFICIENCY

In ES5, internal methods essentially are an implementation detail of
the spec. AFAICS, there is no way their interaction is actually
observable in user code. This gives JS implementations significant
leeway in implementing objects (and they make use of it).

This changes drastically with proxies. In particular, since most
internal methods may now invoke traps directly or indirectly, we can
suddenly observe many internal steps of property lookup and similar
operations through potential side effects of these traps. (Previously,
only the invocation of getters or setters was observable).

Take the following simple example:


var desc = {configurable: true, get: function() {return 8}, set:
function() {return true}}
var handler = {getPropertyDescriptor: function() {seq += G; return desc}}
var p = Proxy.create(handler)
var o = Object.create(p)

var seq = 
o.x
var seq1 = seq
seq = 
o.x = 0
var seq2 = seq


According to the proxy spec, we should see seq1==G and seq2==GG.
In my local version of V8, I currently see seq1==G and seq2==G.
In Firefox 7, I see seq1==GG and seq2==GG.

Obviously, both implementations are unfaithful to the spec, albeit in
reverse ways. At least for V8, implementing the correct behaviour may
require significant changes.

Also, I wonder whether the current semantics forcing seq2==GG really
is what we want, given that it is unnecessarily inefficient (note that
it also involves converting the property descriptor twice, which in
turn can spawn numerous calls into user code). Optimizing this would
require purity analysis on trap functions, which seems difficult in
general.


HIDDEN ASSUMPTIONS

In a number of places, the ES5 spec makes hidden assumptions about the
purity of internal method calls, and derives certain invariants from
that, which break with proxies.

For example, in the spec of [[Put]] (8.12.5), step 5.a asserts that
desc.[[Set]] cannot be undefined. That is true in ES5, but no longer
with proxies. Unsurprisingly, both Firefox and V8 do funny things for
the following example:


var handler = {
  getPropertyDescriptor: function() {
Object.defineProperty(o, x, {get: function() { return 5 }})
return {set: function() {}}
  }
}
var p = Proxy.create(handler)
var o = Object.create(p)
o.x = 4


Firefox 7: InternalError on line 1: too much recursion
V8: TypeError: Trap #error of proxy handler #Object returned
non-configurable descriptor for property x

More generally, there is no guarantee anymore that the result of
[[CanPut]] in step 1 of [[Put]] is in any way consistent with what we
see in later steps. In this light (and due to the efficiency reasons I
mentioned earlier), we might want to consider rethinking the
CanPut/Put split.

This is just one case. There may be other problematic places in other
operations. Most of them are probably more subtle, i.e. the spec still
prescribes some behaviour, but that does not necessarily make any
sense for certain cases (and would be hard to implement to the
letter). We probably need to check the whole spec very carefully.


FIXING PROXIES

A particularly worrisome side effect is fixing a proxy. The proxy
semantics contains a lot of places saying If O is a trapping proxy,
do steps I-J. However, there generally is no guarantee that O remains
a trapping proxy through all of I-J!

Again, an example:


var handler = {
  get set() { Object.freeze(p); return undefined },
  fix: function() { return {} }
}
var p = Proxy.create(handler)
p.x


Firefox 7: TypeError on line 1: getPropertyDescriptor is not a function
V8: TypeError: Object #Object has no method 'getPropertyDescriptor'

The current proxy semantics has an (informal) restriction forbidding
reentrant fixing of the same object, but that is only a very special
case of the broader problem. Firefox 7 rejects fixing a proxy while
one of (most) its traps is executing (this seems to be a recent
change, and the above case probably is an oversight). But it is not
clear to me what the exact semantics is there, and whether it is
enough as a restriction. V8 currently even crashes on a few contorted
examples.



In summary, I'm slightly worried. The above all seems fixable, but is
that all? Ideally, I'd like to see a more thorough analysis of how the
addition of proxies affects properties of the language and its spec.
But given the state of the ES spec, that is probably too much to wish
for... :)

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


Re: On I got 99 problems and JavaScript syntax ain't one (was: On Incremental Updates)

2011-10-05 Thread John J Barton
On Wed, Oct 5, 2011 at 9:11 AM, Russell Leggett
russell.legg...@gmail.comwrote:

 On Wed, Oct 5, 2011 at 11:49 AM, John J Barton
 johnjbar...@johnjbarton.com wrote:
 
 
  On Wed, Oct 5, 2011 at 8:05 AM, Russell Leggett 
 russell.legg...@gmail.com
  wrote:
 
  On Wed, Oct 5, 2011 at 10:52 AM, John J Barton
  johnjbar...@johnjbarton.com wrote:
  
  
   On Wed, Oct 5, 2011 at 7:49 AM, Russell Leggett
   russell.legg...@gmail.com
   wrote:
  
   On Wed, Oct 5, 2011 at 10:32 AM, John J Barton
   johnjbar...@johnjbarton.com wrote:
   
   
On Tue, Oct 4, 2011 at 10:26 AM, Mike Samuel mikesam...@gmail.com
 
wrote:
   
2011/10/4 Russell Leggett russell.legg...@gmail.com:
 On Tue, Oct 4, 2011 at 12:51 PM, Mike Samuel
 mikesam...@gmail.com
 wrote:

 No it doesn't.

 Just walk the object graph starting from the root object and
 let
 the
 set of all reachable symbols be A.
 Load jQuery
 Walk the object graph again letting the set of all reachable
 symbols
 be
 B.

 The public API of jQuery is then (B - A).

 That's works fine under 2 conditions:

 1. You're willing to execute code instead of statically analyze
 it
 2. You're capable of executing that code in isolation.
   
This should be true for most libraries out there.
It obviously doesn't hold for user code and definitely not for all
code in an IDE since IDE's have to deal with code during editing.
   
I'm not a jQuery person, but as far as I can tell jQuery introduces
only
one
global value so the jQuery API is just the properties of that
 object
at
the
point in the program where the developer needs to use jQuery.  You
don't
have to execute code and the only graph you need to walk is the
properties
of one object.
  
   If you looked at the code for more than 5 minutes, you'd see that the
   jQuery codebase, while interesting to look at, would be ridiculously
   hard to statically analyze without understanding jQuery conventions.
   The bulk of the methods are added through calls to
 'jQuery.extend(...'
   and 'jQuery.fn.extend(...'
  
  
   Sure, that's the way lots of JS code works, which is why I think IDEs
   based
   on static analysis are doomed.
 
  I was responding to:
 
You don't have to execute code and the only graph you need to walk
 is
the
properties of one object.
 
  If you don't execute code, that's what static analysis is. I'm sorry,
  I must be missing something. And the way that jQuery (and any JS code
  that use a function of some kind to make classes) builds up its api is
  to use some helper methods, beyond which, static analysis has a really
  rough time. You don't seem to be disagreeing with me.
 
  Oh I got burnt by static analysis before, I should know better. I keep
  thinking that static analysis means analysis of a single compilation
 unit
  outside of the runtime as most IDEs for statically typed languages use.
 
  I meant: if your tool is embedded in the run time then it knows the exact
  jQuery API because it can scan the exact jQuery object. No code on this
  jQuery object needs to run (though that issue is not a show stopper in
  practice, witness breakpoint debugging).
 
  I don't know what to call runtime analysis that does not run extraneous
  code.

 I see, yes. Yeah, I mean if I run the JavaScript console in chrome I
 get nice autocompletion because its using the running environment to
 know what properties an object has. I believe this is what a lot of
 smalltalk IDEs used to do.

 There are still a lot of limitations, though. I mean, what is the
 purpose of the analysis in the long run. Modern Java IDEs can do a lot
 of things with static analysis that are very helpful like refactoring
 and autocompletion. Look, I'm not trying to turn this into a static
 vs. dynamic debate, my point is that there are a lot of limitations -
 and useful tooling that is impossible with dynamic code. I think we
 got here because someone was trying to make the point that the ability
 to add statically analyzable constraints would be useful to tooling.


And it is on this exact point that we disagree


 In JavaScript, the way to do that may have to be through syntactic
 additions such as extends or |. I'm certainly not opposed to analysis
 that goes beyond ASTs. I say, any way you can get it!


... because once we go beyond ASTs much of the value of changing the
language for tools goes away.

Of course if you make developers do more work for tools, tools can be
better. But we should first ensure that tools do their best, then decide
what to force on devs.

jjb




 - Russ

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


Re: On I got 99 problems and JavaScript syntax ain't one

2011-10-05 Thread Bob Nystrom
On Wed, Oct 5, 2011 at 7:18 AM, John J Barton
johnjbar...@johnjbarton.comwrote:



 On Tue, Oct 4, 2011 at 2:33 PM, Bob Nystrom rnyst...@google.com wrote:

 That's correct. That's often the cost of concision. By analogy: you can do
 a lot of stuff using either an explicit stack data structure or recursion.
 Using recursion is often more concise but then the state is hidden from you
 in the callstack. Sometimes that's a good trade-off, sometimes it's not.


 Thanks, that analogy helps confirm my opinion of generators. In my
 experience, the good trade-off is recursion on data structures and the
 not-good-trade-off is recursion for iteration.


Yes, I wasn't making any claim about using recursion *for iteration*. Maybe
I need to be more concrete here:

If you need to walk a tree, you can do so using recursion or you can use an
explicit stack data structure. The former is usually more terse (because it
implicitly relies on the callstack itself storing the stack) but the other
can be more clear.

*By analogy*, if you need to produce a sequence of values, you can do so
using generators, or you can use an explicit iterator object. Again, the
former is usually more terse (because the language automatically creates the
iterator object for you given a function containing yield) but the latter
can be more clear (because the state is laid bare).

Note that those two paragraphs are separate. I'm not talking about using
recursion for iteration. Is this clearer now?

So far the only examples I've seen for generators involve iteration.


Yup, that's what generators do. And recursion involves stacks.

I've heard no clamor at all.


That may be true, but it may say as much about your surrounding auditory
environment as it does the feature in question. You may be right, but simply
saying Bigfoot isn't in my living room doesn't disprove the existence of
Bigfoot.

There *are* languages in wide use that have this feature. None of those
languages (Lua, C#, Python) has a reputation for catering to the esoteric
programming language fanbase.

 Really this is a niche feature, an aid for the rare case where conventional
 iterators are a poor match.


They said the same thing about closures. I agree that generators aren't the
most important language feature in the world, but I think if you had them
you'd find that you used them.

Here's an example:

let tree = [['a', 'b', 'c'], [['d', 'e'], 'f'], ['g']];

let inOrder = walk(tree);
for (node of walk(tree)) alert(node); // a, b, c, d, ...

walk(tree) {
  if (typeof tree == 'string') {
yield tree; // leaf
  } else {
yield* walk(tree); // branch
  }
}


What would the above look like without generators?

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


Re: Proxy-induced impurity of internal methods

2011-10-05 Thread Waldemar Horwat

Please keep bringing these up; they're important.

This is something that we'll need to get nailed down for the spec.  Yes, I'm 
worried too, as this problem is not well-understood.  It has the feel of a 
research problem.

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


Re: Sep 27 meeting notes

2011-10-05 Thread Brendan Eich
On Oct 4, 2011, at 6:17 AM, Russell Leggett wrote:

 That's why I was trying to make it less error prone and verbose.

Understood, but we should not scenario solve with ad-hoc, compound additions. 
We seek orthogonal primitives that compose well, and the harder scenarios 
ideally desugar.


 If you are assuming .{ binds to the result of evaluating the unparenthesized
 | expression to its left, then there's a precedence problem.
 
 I was assuming | was evaluated first because that's how I read
 Allen's pattern working as well. I'm wondering how Allen's even works
 now.

The | operator must not take an arbitrary expression on its right, because 
that allows for mutation of [[Prototype]] on an escaped old-born object.

But | could take literal forms and concatenations of literal forms via 
.prototype.{...}.constructor, e.g.

Or | binds tighter than . (but I think this would be a mistake).


 My thought was that if func | obj = func, then .{ would go on
 the resulting function.

No, func | {...} makes an object whose [[Prototype]] is func.

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


Re: Sep 27 meeting notes

2011-10-05 Thread Brendan Eich
On Oct 4, 2011, at 8:35 AM, Allen Wirfs-Brock wrote:

 On Oct 4, 2011, at 12:44 AM, Brendan Eich wrote:
 
 On Oct 4, 2011, at 5:43 AM, Russell Leggett wrote:
 
 I don't want to be pushy, so this is the last time that I'll mention
 it, but if we can create something using the | operator that can
 basically do what has been discussed for the simplest class literal,
 
 I think you're barking up several wrong trees. But yes, Allen proposed | 
 and .{ to help make class-like syntax lighter-weight (if more punctuated), 
 without having real class syntax. Unfortunately any such poor-person's 
 class unsyntax will remain error prone (easy to leave out or misorder a 
 sub-expression) and slightly verbose (compared to just-so class syntax).
 
 
 Brendan,  It sounds like you may have missed this alternative from  the 
 Minor extension to Set Literal Prototype... thread that eliminates the 
 mis-ordered or left-out constructor clause problem.

Care to summarize? I was traveling and skimming some of the long messages in 
that thread.

Also, I fear we are pattern-mongering prematurely. We want something like | 
for sure (exact spelling needs work IMHO). We could have just Object.extend 
instead of .{...} and some on the committee objected to the mutating nature of 
a variant on dot -- they wanted .= at least -- but since there is no 
requirement that the RHS be a literal, Object.extend is enough.

IINM .{...} is trying to make a shorthand, not just for its own sake but to 
make a class-like pattern and reduce the perceived need for classes as sugar. I 
think that's not well-motivated at this point.

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


Re: Proxy-induced impurity of internal methods

2011-10-05 Thread Andreas Rossberg
On 5 October 2011 18:57, Andreas Rossberg rossb...@google.com wrote:
 FIXING PROXIES

 A particularly worrisome side effect is fixing a proxy. The proxy
 semantics contains a lot of places saying If O is a trapping proxy,
 do steps I-J. However, there generally is no guarantee that O remains
 a trapping proxy through all of I-J!

 Again, an example:

 
 var handler = {
  get set() { Object.freeze(p); return undefined },
  fix: function() { return {} }
 }
 var p = Proxy.create(handler)
 p.x
 

 Firefox 7: TypeError on line 1: getPropertyDescriptor is not a function
 V8: TypeError: Object #Object has no method 'getPropertyDescriptor'

Whoops, sorry, I just saw that I screwed up that example. That
behaviour is perfectly fine, of course. Don't have my notes here, I'll
deliver the proper example tomorrow.

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


Re: holes in spread elements/arguments

2011-10-05 Thread Sean Eagan
On Mon, Oct 3, 2011 at 4:37 PM, Allen Wirfs-Brock al...@wirfs-brock.com wrote:
 apply supports holes...

 f.apply(Array(5));

 Look at the specification of apply in section 15.3.4.3 of the ES5/5.1 spec.
  It does a [[Get]] on each element of the argArray to get the value that
 passed in the argument list.  [[Get]] converts holes to undefined.

The only way this is observable in ES5 is if argArray has getters for
any of the indexes between 0 and argArray.length.  I'm not aware of
any cases of objects defining getters for indexed properties, much
less those objects being passed to Function.prototype.apply.  So the
only consequence of this is that the hole preservation algorithms in
the draft spec only call [[Get]] when [[HasProperty]] returns true.
So we could either tweak the hole preservation algorithm for rest
parameters to call [[Get]] regardless, or the better option IMHO,
match the other algorithms by no longer calling [[Get]] for holes in
argArray, at least when Function.prototype.apply is called from
extended code.


 syntactic calls will support holes...

 f(...Array(5))

 by syntactic calls I meant f(a,b,c).  the legacy language does not allow for
 f(a,,c)

This can be said of any any syntax being added in ES.next.  Also, I'm
only suggesting to add that syntax if it continues to be available in
array literals.

 What *doesn't* support holes is the `arguments` object which is on its way
 out.

 In addition, the specification of the semantics of function invocation made
 no allowance for the possibility of holes in an argument list.

 The specification of `arguments` dictates this, not function
 invocation as a whole.

 Sorry that is incorrect, see 15.3.4.3

You are correct, sorry.  However, this is merely an unobservable
specification detail, so what relevance does it have to what is best
for the future of the language ?

 What about holes makes them applicable to arrays in general but not
 argument arrays ?  Everything else in ES.next points to reification of
 arguments as plain old arrays, why be different here ?

 Because we aren't talking about reification of arguments.  We are talking
 about the semantics of an argument list in a function call expression and
 the semantics of the spread operator.

The spread operator in argument lists reifies the argument list as an
array in my view.  But mostly I just care that the semantics are the
same as when the spread oeprator occurs in an array literal, i.e. that
holes are preserved for the receiver.  If a caller does not want holes
to be observed by a potential callee rest argument, they can use a
dense argument list, however I'm not sure why they would care about
this.  If a caller *does* want to allow a potential callee rest
parameter to utilize holes for optimization purposes, why prevent them
from doing so?

 I would actually be ok with or without both Elision syntax and hole
 preservation in ES.next, I just want consistency.

 One concern that I've already mentioned is that recognizing holes in spread
 would create an inconsistency with the existing semantics of apply and that
 changing apply would be a breaking change that might impact existing code.

 apply does not have existing semantics for rest parameters since they
 don't yet exist, I'm not suggesting to change the semantics for
 `arguments` while it's still around

 Apply is on the caller side.  It doesn't have any parameter semantics at
 all.  It is only responsible for passing on a valid argument list.
 Because apply and normal function application can't depend knowledge to the
 callee, it is reasonable to expect that:
    foo.apply(undefined,x)
 means exactly the same thing as
    foo(...x)


Yes, I intend for them to mean the same thing, which is that holes in
x which fall within a range covered by a rest parameter in foo are
preserved.  If foo uses `arguments` they continue to show up as
undefined values there.

 function f(arg) {
  [a='a', b='b'] = arg;

 The above line is not legal syntax according to the current specification
 draft.  The destructuring binding pattern and a destructuring assignment
 pattern have both different syntax and semantics.
 In a destructuring binding, a scalar BindingElement is defined as:
    SingleNameBinding : BindingIdentifier Initializer-opt
 while in a destructuring assignment, a scalar AssignmentElement is defined
 as
    AssignmentElement : LeftHandSideExpression
 Note that an AssignmentElement does not have an Initializer.  The reason I
 defined it this way is that unlike a BindingIdentifier, a
 LeftHandSideExpression can be an arbitrary complex expression. I didn't want
 to allow expressions such as:
    [new foo.bar[baz(x=5)].bam=0] = obj;
 where the trailing initializer looks like it is just part of the element
 expression.  I'm willing to discuss the merits of that decision, but the
 fact remains that the semantics of destructuring binding and destructuring
 assignment are quite different so I consider suspect any argument that
 starts by 

Re: On I got 99 problems and JavaScript syntax ain't one (was: On Incremental Updates)

2011-10-05 Thread Russell Leggett
On Wed, Oct 5, 2011 at 1:18 PM, John J Barton
johnjbar...@johnjbarton.com wrote:


 On Wed, Oct 5, 2011 at 9:11 AM, Russell Leggett russell.legg...@gmail.com
 wrote:

 On Wed, Oct 5, 2011 at 11:49 AM, John J Barton
 johnjbar...@johnjbarton.com wrote:
 
 
  On Wed, Oct 5, 2011 at 8:05 AM, Russell Leggett
  russell.legg...@gmail.com
  wrote:
 
  On Wed, Oct 5, 2011 at 10:52 AM, John J Barton
  johnjbar...@johnjbarton.com wrote:
  
  
   On Wed, Oct 5, 2011 at 7:49 AM, Russell Leggett
   russell.legg...@gmail.com
   wrote:
  
   On Wed, Oct 5, 2011 at 10:32 AM, John J Barton
   johnjbar...@johnjbarton.com wrote:
   
   
On Tue, Oct 4, 2011 at 10:26 AM, Mike Samuel
mikesam...@gmail.com
wrote:
   
2011/10/4 Russell Leggett russell.legg...@gmail.com:
 On Tue, Oct 4, 2011 at 12:51 PM, Mike Samuel
 mikesam...@gmail.com
 wrote:

 No it doesn't.

 Just walk the object graph starting from the root object and
 let
 the
 set of all reachable symbols be A.
 Load jQuery
 Walk the object graph again letting the set of all reachable
 symbols
 be
 B.

 The public API of jQuery is then (B - A).

 That's works fine under 2 conditions:

 1. You're willing to execute code instead of statically analyze
 it
 2. You're capable of executing that code in isolation.
   
This should be true for most libraries out there.
It obviously doesn't hold for user code and definitely not for
all
code in an IDE since IDE's have to deal with code during editing.
   
I'm not a jQuery person, but as far as I can tell jQuery
introduces
only
one
global value so the jQuery API is just the properties of that
object
at
the
point in the program where the developer needs to use jQuery.  You
don't
have to execute code and the only graph you need to walk is the
properties
of one object.
  
   If you looked at the code for more than 5 minutes, you'd see that
   the
   jQuery codebase, while interesting to look at, would be ridiculously
   hard to statically analyze without understanding jQuery conventions.
   The bulk of the methods are added through calls to
   'jQuery.extend(...'
   and 'jQuery.fn.extend(...'
  
  
   Sure, that's the way lots of JS code works, which is why I think IDEs
   based
   on static analysis are doomed.
 
  I was responding to:
 
You don't have to execute code and the only graph you need to walk
is
the
properties of one object.
 
  If you don't execute code, that's what static analysis is. I'm sorry,
  I must be missing something. And the way that jQuery (and any JS code
  that use a function of some kind to make classes) builds up its api is
  to use some helper methods, beyond which, static analysis has a really
  rough time. You don't seem to be disagreeing with me.
 
  Oh I got burnt by static analysis before, I should know better. I keep
  thinking that static analysis means analysis of a single compilation
  unit
  outside of the runtime as most IDEs for statically typed languages use.
 
  I meant: if your tool is embedded in the run time then it knows the
  exact
  jQuery API because it can scan the exact jQuery object. No code on this
  jQuery object needs to run (though that issue is not a show stopper in
  practice, witness breakpoint debugging).
 
  I don't know what to call runtime analysis that does not run extraneous
  code.

 I see, yes. Yeah, I mean if I run the JavaScript console in chrome I
 get nice autocompletion because its using the running environment to
 know what properties an object has. I believe this is what a lot of
 smalltalk IDEs used to do.

 There are still a lot of limitations, though. I mean, what is the
 purpose of the analysis in the long run. Modern Java IDEs can do a lot
 of things with static analysis that are very helpful like refactoring
 and autocompletion. Look, I'm not trying to turn this into a static
 vs. dynamic debate, my point is that there are a lot of limitations -
 and useful tooling that is impossible with dynamic code. I think we
 got here because someone was trying to make the point that the ability
 to add statically analyzable constraints would be useful to tooling.

 And it is on this exact point that we disagree

 In JavaScript, the way to do that may have to be through syntactic
 additions such as extends or |. I'm certainly not opposed to analysis
 that goes beyond ASTs. I say, any way you can get it!

 ... because once we go beyond ASTs much of the value of changing the
 language for tools goes away.

 Of course if you make developers do more work for tools, tools can be
 better. But we should first ensure that tools do their best, then decide
 what to force on devs.

Sometimes going beyond ASTs is extremely challenging - but OK, let's
just say we reach a point where we have tools good enough that they
can read in code that has been run through a build tool so that they
can 

Re: holes in spread elements/arguments

2011-10-05 Thread Sean Eagan
Removing these inconsistencies would also allow argument and parameter
lists to be explained in terms of desugaring into array structuring
and destructuring patterns respectively:
function(a, , c = 0, ...d){  //...}
would desugar to:
function(){  var [a, , c = 0, ...d] = _arguments_; // even better
would be let!  //...}
and:
f(a, , c, ...d)
would desugar to:
Function.prototype.apply.call(f, undefined, [a, , c, ...d]);

On Wed, Oct 5, 2011 at 2:19 PM, Sean Eagan seaneag...@gmail.com wrote:
 On Mon, Oct 3, 2011 at 4:37 PM, Allen Wirfs-Brock al...@wirfs-brock.com 
 wrote:
 apply supports holes...

 f.apply(Array(5));

 Look at the specification of apply in section 15.3.4.3 of the ES5/5.1 spec.
  It does a [[Get]] on each element of the argArray to get the value that
 passed in the argument list.  [[Get]] converts holes to undefined.

 The only way this is observable in ES5 is if argArray has getters for
 any of the indexes between 0 and argArray.length.  I'm not aware of
 any cases of objects defining getters for indexed properties, much
 less those objects being passed to Function.prototype.apply.  So the
 only consequence of this is that the hole preservation algorithms in
 the draft spec only call [[Get]] when [[HasProperty]] returns true.
 So we could either tweak the hole preservation algorithm for rest
 parameters to call [[Get]] regardless, or the better option IMHO,
 match the other algorithms by no longer calling [[Get]] for holes in
 argArray, at least when Function.prototype.apply is called from
 extended code.


 syntactic calls will support holes...

 f(...Array(5))

 by syntactic calls I meant f(a,b,c).  the legacy language does not allow for
 f(a,,c)

 This can be said of any any syntax being added in ES.next.  Also, I'm
 only suggesting to add that syntax if it continues to be available in
 array literals.

 What *doesn't* support holes is the `arguments` object which is on its way
 out.

 In addition, the specification of the semantics of function invocation made
 no allowance for the possibility of holes in an argument list.

 The specification of `arguments` dictates this, not function
 invocation as a whole.

 Sorry that is incorrect, see 15.3.4.3

 You are correct, sorry.  However, this is merely an unobservable
 specification detail, so what relevance does it have to what is best
 for the future of the language ?

 What about holes makes them applicable to arrays in general but not
 argument arrays ?  Everything else in ES.next points to reification of
 arguments as plain old arrays, why be different here ?

 Because we aren't talking about reification of arguments.  We are talking
 about the semantics of an argument list in a function call expression and
 the semantics of the spread operator.

 The spread operator in argument lists reifies the argument list as an
 array in my view.  But mostly I just care that the semantics are the
 same as when the spread oeprator occurs in an array literal, i.e. that
 holes are preserved for the receiver.  If a caller does not want holes
 to be observed by a potential callee rest argument, they can use a
 dense argument list, however I'm not sure why they would care about
 this.  If a caller *does* want to allow a potential callee rest
 parameter to utilize holes for optimization purposes, why prevent them
 from doing so?

 I would actually be ok with or without both Elision syntax and hole
 preservation in ES.next, I just want consistency.

 One concern that I've already mentioned is that recognizing holes in spread
 would create an inconsistency with the existing semantics of apply and that
 changing apply would be a breaking change that might impact existing code.

 apply does not have existing semantics for rest parameters since they
 don't yet exist, I'm not suggesting to change the semantics for
 `arguments` while it's still around

 Apply is on the caller side.  It doesn't have any parameter semantics at
 all.  It is only responsible for passing on a valid argument list.
 Because apply and normal function application can't depend knowledge to the
 callee, it is reasonable to expect that:
    foo.apply(undefined,x)
 means exactly the same thing as
    foo(...x)


 Yes, I intend for them to mean the same thing, which is that holes in
 x which fall within a range covered by a rest parameter in foo are
 preserved.  If foo uses `arguments` they continue to show up as
 undefined values there.

 function f(arg) {
  [a='a', b='b'] = arg;

 The above line is not legal syntax according to the current specification
 draft.  The destructuring binding pattern and a destructuring assignment
 pattern have both different syntax and semantics.
 In a destructuring binding, a scalar BindingElement is defined as:
    SingleNameBinding : BindingIdentifier Initializer-opt
 while in a destructuring assignment, a scalar AssignmentElement is defined
 as
    AssignmentElement : LeftHandSideExpression
 Note that an AssignmentElement does not have an Initializer.  The 

Re: On I got 99 problems and JavaScript syntax ain't one (was: On Incremental Updates)

2011-10-05 Thread John J Barton
On Wed, Oct 5, 2011 at 2:25 PM, Russell Leggett
russell.legg...@gmail.comwrote:

 On Wed, Oct 5, 2011 at 1:18 PM, John J Barton
 johnjbar...@johnjbarton.com wrote:
 
 
  On Wed, Oct 5, 2011 at 9:11 AM, Russell Leggett 
 russell.legg...@gmail.com
  wrote:
 
  On Wed, Oct 5, 2011 at 11:49 AM, John J Barton
  johnjbar...@johnjbarton.com wrote:
  
  
   On Wed, Oct 5, 2011 at 8:05 AM, Russell Leggett
   russell.legg...@gmail.com
   wrote:
  
   On Wed, Oct 5, 2011 at 10:52 AM, John J Barton
   johnjbar...@johnjbarton.com wrote:
   
   
On Wed, Oct 5, 2011 at 7:49 AM, Russell Leggett
russell.legg...@gmail.com
wrote:
   
On Wed, Oct 5, 2011 at 10:32 AM, John J Barton
johnjbar...@johnjbarton.com wrote:


 On Tue, Oct 4, 2011 at 10:26 AM, Mike Samuel
 mikesam...@gmail.com
 wrote:

 2011/10/4 Russell Leggett russell.legg...@gmail.com:
  On Tue, Oct 4, 2011 at 12:51 PM, Mike Samuel
  mikesam...@gmail.com
  wrote:
 
  No it doesn't.
 
  Just walk the object graph starting from the root object and
  let
  the
  set of all reachable symbols be A.
  Load jQuery
  Walk the object graph again letting the set of all reachable
  symbols
  be
  B.
 
  The public API of jQuery is then (B - A).
 
  That's works fine under 2 conditions:
 
  1. You're willing to execute code instead of statically
 analyze
  it
  2. You're capable of executing that code in isolation.

 This should be true for most libraries out there.
 It obviously doesn't hold for user code and definitely not for
 all
 code in an IDE since IDE's have to deal with code during
 editing.

 I'm not a jQuery person, but as far as I can tell jQuery
 introduces
 only
 one
 global value so the jQuery API is just the properties of that
 object
 at
 the
 point in the program where the developer needs to use jQuery.
 You
 don't
 have to execute code and the only graph you need to walk is the
 properties
 of one object.
   
If you looked at the code for more than 5 minutes, you'd see that
the
jQuery codebase, while interesting to look at, would be
 ridiculously
hard to statically analyze without understanding jQuery
 conventions.
The bulk of the methods are added through calls to
'jQuery.extend(...'
and 'jQuery.fn.extend(...'
   
   
Sure, that's the way lots of JS code works, which is why I think
 IDEs
based
on static analysis are doomed.
  
   I was responding to:
  
 You don't have to execute code and the only graph you need to
 walk
 is
 the
 properties of one object.
  
   If you don't execute code, that's what static analysis is. I'm sorry,
   I must be missing something. And the way that jQuery (and any JS code
   that use a function of some kind to make classes) builds up its api
 is
   to use some helper methods, beyond which, static analysis has a
 really
   rough time. You don't seem to be disagreeing with me.
  
   Oh I got burnt by static analysis before, I should know better. I
 keep
   thinking that static analysis means analysis of a single compilation
   unit
   outside of the runtime as most IDEs for statically typed languages
 use.
  
   I meant: if your tool is embedded in the run time then it knows the
   exact
   jQuery API because it can scan the exact jQuery object. No code on
 this
   jQuery object needs to run (though that issue is not a show stopper in
   practice, witness breakpoint debugging).
  
   I don't know what to call runtime analysis that does not run
 extraneous
   code.
 
  I see, yes. Yeah, I mean if I run the JavaScript console in chrome I
  get nice autocompletion because its using the running environment to
  know what properties an object has. I believe this is what a lot of
  smalltalk IDEs used to do.
 
  There are still a lot of limitations, though. I mean, what is the
  purpose of the analysis in the long run. Modern Java IDEs can do a lot
  of things with static analysis that are very helpful like refactoring
  and autocompletion. Look, I'm not trying to turn this into a static
  vs. dynamic debate, my point is that there are a lot of limitations -
  and useful tooling that is impossible with dynamic code. I think we
  got here because someone was trying to make the point that the ability
  to add statically analyzable constraints would be useful to tooling.
 
  And it is on this exact point that we disagree
 
  In JavaScript, the way to do that may have to be through syntactic
  additions such as extends or |. I'm certainly not opposed to analysis
  that goes beyond ASTs. I say, any way you can get it!
 
  ... because once we go beyond ASTs much of the value of changing the
  language for tools goes away.
 
  Of course if you make developers do more work for tools, tools can be
  better. But we should first ensure that tools do their best, then decide
  

Re: traits feedback

2011-10-05 Thread John J Barton
On Tue, Oct 4, 2011 at 8:56 PM, John J Barton
johnjbar...@johnjbarton.comwrote:

 In trying to update my JS approach I looked into 'traits'. I'm still on the
 fence about using them at this stage, but MarkM was asking for feedback of
 pretty much any kind so here is a little.

 I believe I understand traits for the most part just from the info on the
 Web site:
 http://traitsjs.org/
 (but read the examples in the Paper, not the one in the Tutorial).
 Traits feel like JS to me: a reusable set of methods packaged in an object.
 The Trait construct add regularity and organization to a wide-spread pattern
 of JS use, but it feels like a tool you pick up when you need it. The key
 operations are create and compose, with resolve and override to handle
 exotic issues.

 On the other hand I had the opposite reaction to
 http://wiki.ecmascript.org/doku.php?id=strawman:syntax_for_efficient_traits
 That proposal is a completely different language with many new keywords and
 operators.

 I came away deciding to stop using |prototype| + new in favor of
 Object.create() and to revisit the traits.org library after a bit.


Ok that was a quick experiment. I completely misunderstood Object.create().
I imagined that Object.create(a,b) returned an object with the properties of
b and a __proto__ of a. Unfortunately the second argument is some kind of
meta object. So to get {p:42} you have to write { p: { value: 42, writable:
true, enumerable: true, configurable: true } }. Oy vey.

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


Re: On I got 99 problems and JavaScript syntax ain't one (was: OnIncremental Updates)

2011-10-05 Thread Brendan Eich
On Oct 4, 2011, at 7:19 AM, Juan Ignacio Dopazo wrote:

 Yes, tools should be better, but they need to start becoming better by 
 themselves as previous discussions here have noted.
 
 However, there are problems in the language that need to be addressed by both 
 syntax and APIs. We need:
 
 - A sane way of dealing with equality, identity and basically a lot of what's 
 in http://wtfjs.com/

Some of that is due to implicit conversions, not any equality-ish operator.


 - Ways of isolating code from the global scope

Covered by modules and module loaders.


 - Tools for avoiding XSS

That's a cross-cutting problem, not just core language. So, yes, tools but no 
silver bullets. ES5 has some tools, ES6 has more.


 There was talk about an is or eq operator to fix equality, but it seems 
 it got demoted or interest was lost.

Wrong: wiki.ecmascript.org/doku.php?id=harmony:egal

/be

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


Re: traits feedback

2011-10-05 Thread Jake Verbaten
Object.create does indeed require  propertydescriptors as the second
argument. This is the easiest way to send meta-data like read-only.

However it's verbose and the defaults are restrictive. I've written a small
library (github.com/Raynos/pd) to make it less verbose, you might find it
useful.

On Oct 5, 2011 11:59 PM, John J Barton johnjbar...@johnjbarton.com
wrote:



On Tue, Oct 4, 2011 at 8:56 PM, John J Barton johnjbar...@johnjbarton.com
wrote:   In trying to ...

Ok that was a quick experiment. I completely misunderstood Object.create().
I imagined that Object.create(a,b) returned an object with the properties of
b and a __proto__ of a. Unfortunately the second argument is some kind of
meta object. So to get {p:42} you have to write { p: { value: 42, writable:
true, enumerable: true, configurable: true } }. Oy vey.

jjb

___
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: On I got 99 problems and JavaScript syntax ain't one

2011-10-05 Thread Quildreen Motta

On 05/10/11 22:05, Brendan Eich wrote:

On Oct 4, 2011, at 7:19 AM, Juan Ignacio Dopazo wrote:

Yes, tools should be better, but they need to start becoming better 
by themselves as previous discussions here have noted.


However, there are problems in the language that need to be addressed 
by both syntax and APIs. We need:


- A sane way of dealing with equality, identity and basically a lot 
of what's in http://wtfjs.com/


Some of that is due to implicit conversions, not any equality-ish 
operator.
I really never understood people's complaints about equality comparisons 
in JavaScript. There are only two operators, with clear and well defined 
semantics/use-cases:


`==' (Abstract equality) is used for comparing the value of two objects, 
without taking data-structure into account.


`===' (Strict equality) is used for comparing the value of two objects, 
taking data-structure into account.


Could someone enlighten me on what is not intuitive or sane about 
that? I mean, my starting point for comparing equality operator sanity 
is Common Lisp's with its 10+ equality predicates — some being 
implementation-dependant, so YMMV.

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


Re: On I got 99 problems and JavaScript syntax ain't one

2011-10-05 Thread Brendan Eich
On Oct 5, 2011, at 7:01 PM, Quildreen Motta wrote:

 On 05/10/11 22:05, Brendan Eich wrote:
 On Oct 4, 2011, at 7:19 AM, Juan Ignacio Dopazo wrote:
 
 Yes, tools should be better, but they need to start becoming better by 
 themselves as previous discussions here have noted.
 
 However, there are problems in the language that need to be addressed by 
 both syntax and APIs. We need:
 
 - A sane way of dealing with equality, identity and basically a lot of 
 what's in http://wtfjs.com/
 
 Some of that is due to implicit conversions, not any equality-ish operator.
 I really never understood people's complaints about equality comparisons in 
 JavaScript. There are only two operators, with clear and well defined 
 semantics/use-cases:
 
 `==' (Abstract equality) is used for comparing the value of two objects, 
 without taking data-structure into account.

This operator is insane due to implicit conversions it does when operand types 
are not the same. In such cases it is not an equivalence relation.


 `===' (Strict equality) is used for comparing the value of two objects, 
 taking data-structure into account.

This operator is fine, unless you want to test (NaN is NaN) or (-0 isnt 0). 
There, you need is/isnt.


 Could someone enlighten me on what is not intuitive or sane about that? I 
 mean, my starting point for comparing equality operator sanity is Common 
 Lisp's with its 10+ equality predicates — some being 
 implementation-dependant, so YMMV.

Yes, during ES1 days Guy Steele said we were not worse than Common Lisp. Still 
doesn't excuse ==/!= in the case of operands of different types.

/be

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


Re: On I got 99 problems and JavaScript syntax ain't one

2011-10-05 Thread Quildreen Motta

On 05/10/11 23:06, Brendan Eich wrote:

On Oct 5, 2011, at 7:01 PM, Quildreen Motta wrote:


On 05/10/11 22:05, Brendan Eich wrote:

On Oct 4, 2011, at 7:19 AM, Juan Ignacio Dopazo wrote:


Yes, tools should be better, but they need to start becoming better by 
themselves as previous discussions here have noted.

However, there are problems in the language that need to be addressed by both 
syntax and APIs. We need:

- A sane way of dealing with equality, identity and basically a lot of what's 
in http://wtfjs.com/

Some of that is due to implicit conversions, not any equality-ish operator.

I really never understood people's complaints about equality comparisons in 
JavaScript. There are only two operators, with clear and well defined 
semantics/use-cases:

`==' (Abstract equality) is used for comparing the value of two objects, 
without taking data-structure into account.

This operator is insane due to implicit conversions it does when operand types 
are not the same. In such cases it is not an equivalence relation.
I would argue this is not entirely true. It would depend on what you 
consider equivalence. As I said, the way I see the abstract equality 
algorithm is that it compares values — by which I mean primitive 
values, — such that it can't really take into account the data structure 
of the operands.


So, `1' equals `1' which equals `[1]' which equals 
`{toString:function() 1}' which might equal just about any other 
object which `toString' returns 1. In this case, the semantics are 
pretty sane (though some might argue about `[1]' and other objects). We 
could say it would be analogous to having a book in several different 
medias — ebook, paper, audio, etc. Just because the medias are 
different, it doesn't mean the contents of the book are.


I have to agree, however, that some of the conversions are not as 
intuitive — at first glance — as the ones in the relational operators, 
which always convert the operands to the a numeric primitive value. 
Perhaps some of the fault of abstract equality's usage might be on the 
lack of chaining comparisons, though:


---
// This is not what you'd usually assume it to be, based on mathematical 
notation

2 == 2 == [2] // = false

// ...because operations are done this way
(2 == 2) == [2]
→ (2 == ToNumber(2)) == [2]
→ (2 == 2) == [2]
→ true == [2]
→ true == ToPrimitive([2]) // [2].valueOf().toString()
→ ToNumber(true) == 2
→ 1 == ToNumber(2)
→ 1 == 2
→ false
---

That said, I don't consider the semantics of abstract equality *that* 
complex to consider it a problem — there are some recursive conversions, 
yes. ToPrimitive might get confusing depending on how toString and 
valueOf are defined in the object. That might be a problem or an 
interesting feature depending on the particular use-case, considering 
how dynamic JS is.


That's not to say it's perfect in every single conversion, but it gets 
at least 90% of all the practical use cases right. Other people probably 
have a different opinion on this kind of equivalence coming from a 
strong or static/strong typed background.



`===' (Strict equality) is used for comparing the value of two objects, taking 
data-structure into account.

This operator is fine, unless you want to test (NaN is NaN) or (-0 isnt 0). 
There, you need is/isnt.

Is `egal' already in ES.next?
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: traits feedback

2011-10-05 Thread Juan Ignacio Dopazo
On Wed, Oct 5, 2011 at 10:36 PM, Jake Verbaten rayn...@gmail.com wrote:

 Object.create does indeed require  propertydescriptors as the second
 argument. This is the easiest way to send meta-data like read-only.

 However it's verbose and the defaults are restrictive. I've written a small
 library (github.com/Raynos/pd) to make it less verbose, you might find it
 useful.


 That's what 
 Object.getOwnPropertyDescriptorshttp://wiki.ecmascript.org/doku.php?id=strawman:extended_object_api
  would
be for. I don't know why it hasn't gotten into Harmony yet.


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


Re: traits feedback

2011-10-05 Thread Quildreen Motta

On 06/10/11 00:02, Juan Ignacio Dopazo wrote:
On Wed, Oct 5, 2011 at 10:36 PM, Jake Verbaten rayn...@gmail.com 
mailto:rayn...@gmail.com wrote:


Object.create does indeed require  propertydescriptors as the
second argument. This is the easiest way to send meta-data like
read-only.

However it's verbose and the defaults are restrictive. I've
written a small library (github.com/Raynos/pd
http://github.com/Raynos/pd) to make it less verbose, you might
find it useful.


That's what Object.getOwnPropertyDescriptors 
http://wiki.ecmascript.org/doku.php?id=strawman:extended_object_api would 
be for. I don't know why it hasn't gotten into Harmony yet.
Hm, how exactly would `#getOwnPropertyDescriptors' fix the verbosity of 
property descriptors when creating new slots in an object? Or were you 
referring to another issue? If so, I missed it, would you care to 
explain a little better?
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: traits feedback

2011-10-05 Thread John J Barton
On Wed, Oct 5, 2011 at 8:02 PM, Juan Ignacio Dopazo
dopazo.j...@gmail.comwrote:

 On Wed, Oct 5, 2011 at 10:36 PM, Jake Verbaten rayn...@gmail.com wrote:

 Object.create does indeed require  propertydescriptors as the second
 argument. This is the easiest way to send meta-data like read-only.

 However it's verbose and the defaults are restrictive. I've written a
 small library (github.com/Raynos/pd) to make it less verbose, you might
 find it useful.


 That's what 
 Object.getOwnPropertyDescriptorshttp://wiki.ecmascript.org/doku.php?id=strawman:extended_object_api
  would
 be for. I don't know why it hasn't gotten into Harmony yet.


Sorry I the property descriptors thing is just for library writers I guess,
it's too complicated for app devs.

I think what's missing is Object.extend:

http://www.prototypejs.org/api/object/extend
http://api.jquery.com/jQuery.extend/
http://dojotoolkit.org/reference-guide/dojo/extend.html
http://docs.sencha.com/ext-js/4-0/source/Object2.html#Ext-Object-method-merge
http://code.google.com/p/fbug/source/browse/branches/firebug1.9/content/firebug/lib/object.js

just some examples in a few minutes. With extend, then we can write

var bar = Object.extend(Object.create(aMethodList), aPropList);

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


Re: On I got 99 problems and JavaScript syntax ain't one

2011-10-05 Thread Juan Ignacio Dopazo
On Thu, Oct 6, 2011 at 12:01 AM, Quildreen Motta quildr...@gmail.comwrote:

 On 05/10/11 23:06, Brendan Eich wrote:

 On Oct 5, 2011, at 7:01 PM, Quildreen Motta wrote:

  On 05/10/11 22:05, Brendan Eich wrote:

 On Oct 4, 2011, at 7:19 AM, Juan Ignacio Dopazo wrote:

 - A sane way of dealing with equality, identity and basically a lot of
 what's in http://wtfjs.com/

 Some of that is due to implicit conversions, not any equality-ish
 operator.

 I really never understood people's complaints about equality comparisons
 in JavaScript. There are only two operators, with clear and well defined
 semantics/use-cases:

 `==' (Abstract equality) is used for comparing the value of two objects,
 without taking data-structure into account.

 This operator is insane due to implicit conversions it does when operand
 types are not the same. In such cases it is not an equivalence relation.


Yes, == and === work fine. The problem is not in how they work, but in the
learning curve for new users of the language. I think most expect == to work
as ===. That, combined with object wrappers for values (new Number(5), new
Boolean(false), etc), seems to be an endless source of confusion for
beginners.

Of course pretty much every operator does type coercion, so tampering with
== and === could be as much detrimental as constructive.


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


Re: On I got 99 problems and JavaScript syntax ain't one

2011-10-05 Thread Brendan Eich
On Oct 5, 2011, at 8:01 PM, Quildreen Motta wrote:

 On 05/10/11 23:06, Brendan Eich wrote:
 `==' (Abstract equality) is used for comparing the value of two objects, 
 without taking data-structure into account.
 This operator is insane due to implicit conversions it does when operand 
 types are not the same. In such cases it is not an equivalence relation.
 I would argue this is not entirely true. It would depend on what you consider 
 equivalence.

Equivalence relation is a well-defined technical phrase, and I was employing 
it intentionally. Please read

http://en.wikipedia.org/wiki/Equivalence_relation

and note the three required properties: an e.r. must be reflexive, symmetric, 
and transitive.

 == 0  0 == 0 but  != 0 in JS. If == were transitive, then  would 
have to == 0.

(NaN != NaN violates reflexive but it's a special case for numerical 
analysts, I'm told -- other languages do likewise.)


 This operator is fine, unless you want to test (NaN is NaN) or (-0 isnt 0). 
 There, you need is/isnt.
 Is `egal' already in ES.next?

Already answered -- wiki.ecmascript.org/doku.php?id=harmony:egal. That link 
remains in harmony:proposals.

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


Re: traits feedback

2011-10-05 Thread Brendan Eich
On Oct 5, 2011, at 8:21 PM, John J Barton wrote:

 I think what's missing is Object.extend:
 
 http://www.prototypejs.org/api/object/extend
 http://api.jquery.com/jQuery.extend/
 http://dojotoolkit.org/reference-guide/dojo/extend.html
 http://docs.sencha.com/ext-js/4-0/source/Object2.html#Ext-Object-method-merge
 http://code.google.com/p/fbug/source/browse/branches/firebug1.9/content/firebug/lib/object.js
 
 just some examples in a few minutes. With extend, then we can write
 
 var bar = Object.extend(Object.create(aMethodList), aPropList);

I agree we should specify Object.extend in ES6. It's the API form of the .{ 
monocle-mustache operator but generalized to non-literal RHS.

However, IIRC PrototypeJS uses for-in and does not filter out enumerable 
inherited properties. It also uses assignment. Neither is good for ES6. We want 
only own properties, including private-name-object-keyed ones. This is good 
motivation for a built-in.

Given Object.extend, does .{ pay for itself outside of the class pattern 
use-case? Does a play on dot connote the mutation of the LHS? I think maybe 
not and no. If we have only Object.extend, we still roll up a popular and 
common de-facto standard. If we must have an operator, it should take 
non-literal RHS and contain = in the assignment operator style. So, .= 
(monocle-nostrils? monocle-thin-man-mustache? ugh).

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


Re: traits feedback

2011-10-05 Thread John J Barton
On Wed, Oct 5, 2011 at 8:44 PM, Brendan Eich bren...@mozilla.com wrote:

 On Oct 5, 2011, at 8:21 PM, John J Barton wrote:

 I think what's missing is Object.extend:

 http://www.prototypejs.org/api/object/extend
 http://api.jquery.com/jQuery.extend/
 http://dojotoolkit.org/reference-guide/dojo/extend.html

 http://docs.sencha.com/ext-js/4-0/source/Object2.html#Ext-Object-method-merge

 http://code.google.com/p/fbug/source/browse/branches/firebug1.9/content/firebug/lib/object.js

 just some examples in a few minutes. With extend, then we can write

 var bar = Object.extend(Object.create(aMethodList), aPropList);


 I agree we should specify Object.extend in ES6. It's the API form of the .{
 monocle-mustache operator but generalized to non-literal RHS.

 However, IIRC PrototypeJS uses for-in and does not filter out enumerable
 inherited properties. It also uses assignment. Neither is good for ES6. We
 want only own properties, including private-name-object-keyed ones. This
 is good motivation for a built-in.


PrototypeJS (and Firebug) pre-date Object.keys() and .hasOwnProperty(), so
their implementation was just what could be done, not what was desired.

Trait.create() parallels Object.create() and I gather that Trait.compose()
resembles proposed Object.extend(). I wonder if the traits.js
'parallel-universe' could be applied to Trait.resolve(). In my experience
resolve() isn't needed, but academic work on traits suggests otherwise, so
it might be a good thing to investigate.

jjb



 Given Object.extend, does .{ pay for itself outside of the class pattern
 use-case? Does a play on dot connote the mutation of the LHS? I think maybe
 not and no. If we have only Object.extend, we still roll up a popular and
 common de-facto standard. If we must have an operator, it should take
 non-literal RHS and contain = in the assignment operator style. So, .=
 (monocle-nostrils? monocle-thin-man-mustache? ugh).

 /be

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


Re: On I got 99 problems and JavaScript syntax ain't one

2011-10-05 Thread Brendan Eich
On Oct 4, 2011, at 10:52 AM, Mikeal Rogers wrote:

 But, some of them simply double the semantics and syntax in the language 
 without a path to deprecate previous syntax. I'm a big fan of let, but if you 
 don't deprecate var we're going to have to contend with new programmers 
 keeping two sets of scoping rules in their head.

You mean by deprecate what, exactly?

Web JS is full of var. Making any attempt to migrate a big hunk of it to ES6 
require replacing all 'var' with 'let' is a huge tax, since scoping works 
differently.

Ok, how about saying if you use 'let' in a function or at top level, you can no 
longer use 'var'? That's less of a tax on average, but for a long program or 
single function, it's as bad.

On the web, deprecation is separate from obsolescence. You don't remove the bad 
old thing until the good new thing is out and about and actually in use. You 
might have to wait for the bad old thing to wither almost to nothing, all by 
itself.

Or sometimes a breaking change that actually improves semantics, rarely breaks 
valid content, and has better security can be shipped sooner. Examples include 
window name targeting and mixed http:/https: content not loading the http: 
content (IE9 does this, good on them).

'var' is not such a case.


 Brendan said something very interesting in his talk at JSConf.eu, he said 
 that because of the way TC39 works any new proposal that doesn't have (and I 
 hope I'm paraphrasing this right) sexy syntax to start with doesn't have 
 much of a chance.

I never said that. In particular, I did not say sexy, and I didn't say 
start -- here's proof. | and .{ are proposed for ES6. They aren't quite 
right, many on the committee and in the community believe. That doesn't mean 
they'll fail to be included under some syntax -- the semantics are good 
(although .{ is just Object.extend, so the API would be good by itself).

What I said was that it's hard to agree on syntax unless the proposer nails it, 
really (no double entendre there!). Often by using syntax from a nearby 
language. Even then, .e.g. generators (we distinguish them at the head via 
function*) and block-lambdas, some who don't know or do not like the nearby 
language balk.

My main point was that syntax is hard. But syntax is UI and JS's UI has real 
usability bugs. I'm glad you find it easy to teach. That's not the only 
consideration though, because after people learn a language, as they keep using 
it they do progress to become fluent, even expert, at it, and its usability 
problems come to the fore.

/be

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


Re: Proxy-induced impurity of internal methods

2011-10-05 Thread Allen Wirfs-Brock
Good points that we will have to specify careful.  Also one the reasons we do 
prototype implementations.

Such issues seems inherent in the adoption of an intercession API and 
semantics.  Having to deal with such issues isn't really new.  In ES5 we had to 
deal with this possibility WRT [[Get]] and [[Set]] triggering accessors it 
forced us in some cases to use [[DefineOwnProperty]] instead of [[Put]].  The 
impact on the internal methods were relatively small in ES5.  It was larger for 
some of the syntactic production evaluation semantics. The biggest impact was 
on built-ins. I agree that Proxies will have even broader impact and I can even 
imagine that working through them might lead to some refactoring of the 
internal properties in order to reduce such effects.  such refactorings might 
then force some changes in to the Proxy Traps.

more below

On Oct 5, 2011, at 9:57 AM, Andreas Rossberg wrote:

 
 In summary, I'm slightly worried. The above all seems fixable, but is
 that all? Ideally, I'd like to see a more thorough analysis of how the
 addition of proxies affects properties of the language and its spec.
 But given the state of the ES spec, that is probably too much to wish
 for... :)

I'm not sure what you mean my the last sentence. I have not yet done any work 
to incorporate proxies into the ES6 draft.  What we currently have is proposal 
that does not address this depth of specification.  I can assure you that, we 
will when they start to move into the ES6 draft.

If you have specific issues like these a good way to capture them is to file 
bugs against  the proposals component  of the harmony products at 
bugs.ecmascript.org.  Proposes resolutions would be good too.  I definitely 
look at reported proposal bugs when I work on incorporating new features into 
the draft specification.  On the other hand I don't guarantee that I will spot 
or remember all issues raised on this list.  So file bugs.

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


Re: On I got 99 problems and JavaScript syntax ain't one

2011-10-05 Thread Brendan Eich
A huge +1 and hugs and kisses for your entire post. And I didn't say anything 
like Mikeal's paraphrase, and the ES6 harmony:proposals bear this out (| is 
unsexy in my current font!).

It's especially important not to discount shorthands and sugar for cliché, even 
though they could be replaced by equivalent long-hand. English does not only 
have is not. It has isn't as well, and we're better off for that kind of 
contraction. Yes, this makes it harder to teach -- I know, I have a 7 and a 6 
year old learning the rules right now, along with the raft of irregular verbs 
in English that such children need to know -- but learners manage.

/be

On Oct 4, 2011, at 12:59 PM, Bob Nystrom wrote:

 
 
 On Tue, Oct 4, 2011 at 10:52 AM, Mikeal Rogers mikeal.rog...@gmail.com 
 wrote:
 
 My main concern with *some* of the proposals is that I feel they add features 
 and clever syntax for experts at the expense of keeping the language easy to 
 understand for new programmers.
 
 It's hard to satisfy both sets of users here. It's important to try and do 
 our best, but many things are trade-offs. I don't think we can declare thou 
 shalt not change the language in a way that makes it harder for new users. 
 If we can make things much better for working Javascripters at a small 
 expense to newcomers, that may be a worthwhile trade-off or it may not. We 
 should be open to making wise decisions like that, while remaining 
 sympathetic to everyone who is writing JS.
 
 I'm a big fan of let, but if you don't deprecate var we're going to have to 
 contend with new programmers keeping two sets of scoping rules in their head.
 
 I would love to kill var. With fire.
 
 Generators so a function is sometimes a constructor, sometimes a 
 function, and sometimes it's a generator?!?! Explain that in one paragraph 
 that new programmers can understand, I dare you.
 
 Because I can never refuse a dare...
 
 A constructor is different from a regular function. Instead of returning the 
 value that the body of the function returns, it returns a special 
 newly-created object. Likewise, a generator is a special function that 
 doesn't return what the body returns. Instead, it returns an object that lets 
 you interrupt and resume that function. This object exposes a next() method. 
 When you call that, the function runs until it hits a yield. When it does, 
 the function is paused at that point, and the result of the yield is returned 
 from next(). The next time you call next() it picks up from there and 
 continues.
 
 Brendan said something very interesting in his talk at JSConf.eu, he said 
 that because of the way TC39 works any new proposal that doesn't have (and I 
 hope I'm paraphrasing this right) sexy syntax to start with doesn't have 
 much of a chance.
 
 Brendan knows better than I, but often I feel that we have the opposite 
 problem. If all you're proposing is syntax, it's easy for anyone to shoot it 
 down by saying You can already do that now. There's a fundmental difference 
 between utility (can we do it all, ever, regardless of how many fingers we 
 lose in the process) and usability (is it discoverable, easy, clear, 
 pleasurable and not error-prone).
 
 Because we're programmers we have a tendency to ignore usability concerns 
 because they take more work to demonstrate. We like nice clear boolean 
 switches: I couldn't do this and now I can! It's less satisfying for many 
 of us to say Now people encounter 17% fewer errors when doing this!
 
 Personally, I don't think that's the right way to look at things. Arguing 
 from that angle pretty quickly turns into a Turing tarpit. I believe the 
 entire reason we create languages is for usability. I think syntax does 
 matter, because syntax is the user interface of the semantics. I rarely have 
 complaints about JavaScript's semantics (except for var) but I find its 
 notation awkward in some places. Improving those would make me more 
 productive and make JS more fun for me to use.
 
 - bob
 ___
 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: On I got 99 problems and JavaScript syntax ain't one

2011-10-05 Thread Brendan Eich
On Oct 4, 2011, at 7:36 PM, Dean Landolt wrote:

 I think generators are an excellent example of a feature that is well 
 prototyped (in FF JS 1.7+). I think the developer uptake is minimal, outside 
 of the original advocates.
 
 Of course uptake is minimal -- it's only in one engine, and even then it 
 doesn't yet match the spec.

Please get the historical order right. The spec changed only recently, the 
implementation matched the previous spec (of five years' standing).

Anyway, the changes are minor in the scheme of things, or in the terms of this 
debate. Unless the issue is the function head not looking different? Fixed that 
in ES6 for ya! ;-) function* also makes the empty basis case work for yield*.

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


Re: traits feedback

2011-10-05 Thread Brendan Eich
On Oct 5, 2011, at 9:02 PM, John J Barton wrote:

 PrototypeJS (and Firebug) pre-date Object.keys() and .hasOwnProperty(),

hasOwnProperty was in ES3 in 1999. PrototypeJS is IIRC 2005-era. Firebug is 
post-y2k.


 so their implementation was just what could be done, not what was desired.

Seems unhistorical :-|.


 Trait.create() parallels Object.create() and I gather that Trait.compose() 
 resembles proposed Object.extend(). I wonder if the traits.js 
 'parallel-universe' could be applied to Trait.resolve(). In my experience 
 resolve() isn't needed, but academic work on traits suggests otherwise, so it 
 might be a good thing to investigate.

Tom Van Cutsem should weigh in.

/be

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