Re: (Map|Set|WeakMap)#set() returns `this` ?

2012-12-06 Thread Jussi Kalliokoski
On Wed, Dec 5, 2012 at 10:43 PM, Rick Waldron waldron.r...@gmail.comwrote:




 On Wed, Dec 5, 2012 at 3:26 PM, Domenic Denicola 
 dome...@domenicdenicola.com wrote:

 Readability or library preference aside, I still think it's bizarre that

 map.set(key, val)

 is analogous to

 (dict[key] = val, dict)

 and not to

 dict[key] = val

 When I'm using a fluent library like jQuery or a configuration DSL like
 those in the npm packages surveyed, I can see the attraction of chaining.
 But when I am using a basic primitive of the language, I expect uniformity
 across primitives.


 This argument won't hold when the language doesn't make any such
 uniformity promises, eg.

 array.push(val); // new length
 array[ array.length - 1 ] = val; // val


That's just a bad analogy, because that's not what push does, since it has
a variadic argument (admittedly, I don't think returning the length is
useful anyway, but if it returned the value, should it return the first,
last, or all of them?). And if it comes down to precedents in the language,
even Array#forEach() returns undefined, contrary to popular libraries out
there. Let's keep some consistency here.

I agree with you, fear-driven design is bad. But don't you agree that if
there's chaining, it's better done at language level rather than having all
APIs be polluted by `this` returns? After all, the APIs can't guarantee a
`this` return, since they might have something actually meaningful to
return, otherwise we might as well just replace `undefined` with `this` as
the default return value.

We could introduce mutable primitives so that meaningful return values
could be stored in arguments, kinda like in C, but instead of error values,
we'd be returning `this`, heheheh. :)

I'm curious, do you have any code examples of maps/sets that could be made
clearer by chaining?

Cheers,
Jussi




 Rick



 ___
 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: Module Comments

2012-12-06 Thread David Herman
On Dec 5, 2012, at 11:52 PM, Brendan Eich bren...@mozilla.org wrote:

 ExportDeclaration: export { ExportSpecifier (, ExportSpecifier)* 
 } ;
 ExportDeclaration: export Identifier (, Identifier)* ;
 ExportDeclaration: export * from StringLiteral ;
 
 Reasonable point, I'll think about that.
 
 We do not so limit var, let, or const -- why should we limit export? Ok, it's 
 a bit different (but then import is not, right?).
 
 Style enforcement should not be wired into the grammar. If I want to write
 
  export {odd, even}, {nat: naturals};
 
 why not?

Fairly agnostic about this, given that you can express most combinations within 
the { ... } form. But I'll think about it.

 Removing the curlies for this simple case would seem like a win.
 
 Another fair point. I think it might've just been a refactoring oversight.
 
 Cool, definitely want the plain identifier form, it's part of the binding 
 (and destructuring) pattern language.

Well, the thing is it isn't consistent with the destructuring meaning: dropping 
the curlies here means extracting a single export (aka property), which is not 
what it means in destructuring assignment/binding anywhere else.

But that said, the convenience may well still trump the inconsistency.

Dave

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


Re: Module Comments

2012-12-06 Thread Jussi Kalliokoski
On Thu, Dec 6, 2012 at 8:25 AM, David Herman dher...@mozilla.com wrote:

 On Dec 5, 2012, at 7:16 PM, Kevin Smith khs4...@gmail.com wrote:

  1) export ExportSpecifierSet (, ExportSpecifierSet)* ;
 
  This rule seems too permissive.  It allows strange combinations like:
 
  export x, { y: a.b.c, z }, { j, k }, * from bloop;
 
  I think it would be better to flatten it out a little bit:
 
  ExportDeclaration: export { ExportSpecifier (,
 ExportSpecifier)* } ;
  ExportDeclaration: export Identifier (, Identifier)* ;
  ExportDeclaration: export * from StringLiteral ;

 Reasonable point, I'll think about that.

 
  2) Do we need `export *;`?
 
  I don't see the point of exporting every declaration in the current
 module scope.  If the programmer wants to export a bunch of stuff, the
 other forms make that sufficiently easy.  Exporting everything encourages
 bad (de-modular) design.

 Again, reasonable point.

  3) I'm just OK with as.  Note that it inverts the position of the
 string and the binding:
 
  import { x } from goo;
  import ga as ga;
 
  Which makes it harder to read when you have a bunch of imports mixed
 together.  It's harder for the eyes to scan back and forth.

 Yeah, that's the known downside to this syntax. We've been around this
 block so many times, and it's just one of those things that will end up
 with bikeshed colored not in paint but in blood. I'm open to alternative
 suggestions but not to endless discussion (it goes nowhere).

 The alternative of

 import ga = ga

 has the problem of looking like it's saying that ga is a string.

 The alternatives of

 import ga = module(ga)

 or

 import ga = (module ga)

 have the problem of making it look like the RHS is an expression.

 Feel free to suggest alternatives, but forgive me if I'm not willing to
 respond to every opinion on this one. :}


Replace the current `from` form with `of` and use `from` for the single
export:

import go from ga; // prev: import ga as go
import {a: b, b: a} of ta; // prev: import {a: b, b:a} from ta

It would even make the common case shorter. :P

Or keep the current `from` form and:

import go off ga; // prev: import ga as go

Or maybe `in`, but it sounds really weird in English as import has an
implicit in.

Cheers,
Jussi


  4) Why was this form eliminated?
 
  import x from goo;  // Note lack of curlies!
 
  In an object-oriented application, we're often going to be importing a
 single thing (the class) from external modules.  So we may see long lists
 like this:
 
  import { ClassA } from ClassA.js;
  import { ClassB } from ClassB.js;
  
  import { ClassZ } from ClassZ.js;
 
  Removing the curlies for this simple case would seem like a win.

 Another fair point. I think it might've just been a refactoring oversight.

  5) Dynamic exports via `export = ?` could make interop with existing
 module systems easier.  But how does that work?

 Basic semantics:

 - The module has one single anonymous export.
 - Clients can only get access to the export with the as form; there's no
 way to access it via a named export.
 - The value of the export is undefined until the RHS is evaluated.

  6) Adding .js as the default resolution strategy:
 
  I don't think this is tenable.  First, there's the practical issue of
 what happens when someone actually wants to load a resource without a .js
 extension?

 They change the resolution hook.

  Second, there's the philosophical problem of essentially setting up an
 alternate URL scheme.  That's fine for libraries like AMD loaders or YUI.
  But EcmaScript is a cornerstone of the internet.  External resource
 resolution can't conflict with HTML/CSS/etc.

 I'll wait till it's fleshed out more didn't last long, eh? ;-) Anyway, I
 don't really understand this argument but do you think there's much value
 to a philosophical debate on es-discuss?

 Dave

 ___
 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: Module Comments

2012-12-06 Thread Claus Reinke
Well, the thing is it isn't consistent with the destructuring meaning: dropping the curlies here 
means extracting a single export (aka property), which is not what it means in destructuring 
assignment/binding anywhere else.


But that said, the convenience may well still trump the inconsistency.


I think I'd prefer consistency here, as it also allows to get rid of

   import foo as foo;

and replace it with

   import foo from foo;

which keeps the order of

   import {x,y} from foo

and it is all just module-level destructuring (fewer new concepts).

Claus


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


Categorisation of ECMAScript(+event loops) Threats

2012-12-06 Thread David Bruant

Hi,

This post is not intentioned to be a perfect and final guide, but rather 
a conversation starter.
It's mostly triggered by what Andrea described as a potential attack 
(assigning Object.prototype.get).


# Description of the JS runtime

To a first approximation (ignoring things like alert/prompt and weird 
window resize event behaviors), a JavaScript runtime contains a heap, a 
call stack and a message queue. Messages accumulate in the queue and are 
treated one after the other. The time during which one message is 
treated is called a turn. Messages are queued when a user clicks and a 
listener listens or when a timeout fires, etc.
A message contains a function which, upon being called may call other 
functions (hence the call stack). Functions manipulate memory, including 
things in the heap. The heap contains a bunch of objects being 
accessible either from the global object or the scope of the function 
being called.


# Some properties

## Environment Mutability

Until ES5, pretty much everything in the heap could be modified at any 
turn by anyone; new properties could be added/removed from the global 
object, or the Object.prototype object for instance.
Sharing access to an object pretty much meant giving away the 
possibility to anyone with access to this object to mess up with it.
ES5 introduces a couple of constructs like Object.preventExtensions and 
Object.defineProperty(,,{configurable: false, writable: true|false}) to 
enable a programmer to share some object but have some properties 
enforced. It is probably the first time there are constructs that act on 
objects to create permanent effects on them.


## During a turn

Stating the obvious, but the function running in a turn has the power to 
do anything to whatever it has access to. Among the possible changes, 
it's possible to Object.freeze any object the function has access to.
When some JS code is running during a turn, it can't be preempted by 
some other code. The code has to end.


## First turn

There is a first turn.

## (Partial) conclusion

If malicious code runs, it can do whatever is possible during its turns. 
The role of a defenser will be to reduce whatever is possible to 
nothing harmful.
First reaction, if the malicious code runs first, too bad, it can edit 
anything in the JavaScript environment it has access to, including 
modifying Object.prototype. The careful attacker will freeze 
Object.prototype after having modified it.
The opposite is true too. If the defender runs first, it can defend its 
environment. If the defender doesn't want Object.prototype to be 
modified, it can freeze it. If it wants to add polyfills then freeze 
everything, that's also a decent idea.
If during the first turn no one modifies anything in an harmful or 
defensive way, the decision to attack or defend is let to the code 
running in the next turn and so on.



# Categorisation of threats

## Threats that are unprotectable against

Programming languages or APIs sometimes leave holes by design that even 
the most skilled programmers couldn't write defensive programs against. 
If I recall, ES5 strict mode has gotten rid of all of them with the 
notable exception of mutable Date.prototype that provides a covert channel.
SES is an example of script that does everything it can to protect the 
JS environment (including fixing or working around almost-comformant 
environments bugs!)



## Threats that can be protected against

From everything I have said, one clear thing is that protecting the 
JavaScript is an opt-in. If you do not opt-in to a secure environment, 
you're left to be a prey by default.

The list of potential attacks is probably endless.
Adding an Object.prototype.get function and waiting for people to use 
Object.defineProperty is such an attack. Putting an accessor on 
Array.prototype[0] is also a possibility.



# What does it mean for the language evolution?

The first category needs to be taken care of and is. Next features are 
carefully thought out to avoid unprotectable threats.
The second category is a bit more debatable. There is tension due to the 
fact that the vast majority of JS developers aren't aware that 
JavaScript security requires an opt-in like SES and as a consequence are 
victim of whatever buggy or malicious code they happen to add to their 
webpages.


Given that security requires an opt-in anyway, is it worthwhile to 
modify the language (like Object.defineProperty) to protect for some 
cases but not others?

I would tend to say no.

Regarding Andrea's specific case, I'd like to mention that proxy 
handlers are also based on [[Get]]. The inheritance is actually used in 
some cases for trap reuse (it was even more the case in the previous 
design, but still is the case). Should inheritance be prevented here too 
and ruin a valid use case? Just because an attacker might add an 
Object.prototype.someTrap and the defender might have forgotten to 
protect against it?

I don't think it's worth the cost in 

Re: (Map|Set|WeakMap)#set() returns `this` ?

2012-12-06 Thread Andreas Rossberg
On 6 December 2012 05:05, Rick Waldron waldron.r...@gmail.com wrote:
 Again, I reject the notion that someone might screw up is a valid argument
 for this, or any, discussion. It's one thing to be aware of the potential
 for misuse, but entirely another to succumb to fear driven design.

Fear driven design is pejorative. The argument really is about the
ability to do local reasoning as much as possible, which is a *very*
valid concern, especially when reading somebody else's code using
somebody else's library.

I agree with other voices in this thread that in general, returning
'this' rather is an anti pattern. You can get away with it if you
limit it to very few well-known library functions, but I doubt that
blessing such style in the std lib does help that cause.

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


Re: Module Comments

2012-12-06 Thread Sam Tobin-Hochstadt
On Thu, Dec 6, 2012 at 1:25 AM, David Herman dher...@mozilla.com wrote:
 On Dec 5, 2012, at 7:16 PM, Kevin Smith khs4...@gmail.com wrote:

 2) Do we need `export *;`?

 I don't see the point of exporting every declaration in the current module 
 scope.  If the programmer wants to export a bunch of stuff, the other forms 
 make that sufficiently easy.  Exporting everything encourages bad 
 (de-modular) design.

 Again, reasonable point.

I *strongly* disagree.  There are two important use cases for `export
*` -- exporting everything you've defined, for little convenience
modules or other quick tasks, and for wrapper modules where you want
to export everything you import from somewhere else. Not having it
means that you have to write everything explicitly, but more than that
means that you end up with annoying busy work when you forget, and
have to go figure out where the missing import or export is.  I don't
see any benefit to leaving it out (unlike `import *`, which was
genuinely complex), and I don't think we need to tell programmers what
good design is.

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


Re: Module Comments

2012-12-06 Thread Kevin Smith
Summaries with comments:

1) export ExportSpecifierSet (, ExportSpecifierSet)* ;


Brendan pointed out that other binding forms allow lists (including the
import form), so why not this one?  I actually didn't realize that lists
are allowed with import:

ImportDeclaration ::= import ImportClause (, ImportClause)* ;

Fair enough.

2) Do we need `export *;`?


Sam pointed out two use cases:

1) Conveniently exporting everything from little convenience modules.

I'm not really convinced by this.  It's just so easy to export things by
adding the export keyword.

2) Re-exporting a collection of imports from other sources.

This is better, at least in the case where you want to import a
well-defined set of bindings and then re-export those same bindings later.
 Without `export *;`, you'd have to keep those binding lists in sync.
 Sounds reasonable to me.

3) I'm just OK with as.  Note that it inverts the position of the string
 and the binding:


Claus and Matthew suggested using the no-curlies form instead:

import ga from ga;

Dave responded by pointing out that we don't want from to have overloaded
semantics.  I actually think this form has potential, because it further
aligns import with the other binding forms:

var a = x;
var { b } = y;

// Symmetry!

import a from x;
import { b } from y;

5) Dynamic exports via `export = ?` could make interop with existing module
 systems easier.  But how does that work?


Dave gave an outline.  I'm liking this.  What are the downsides, if any?


 6) Adding .js as the default resolution strategy:


Dave responded that a custom resolution hook would be required for
resources that don't end in .js.  While that certainly works for current
loader libraries, can we really mandate a js extension for all module
URLs, forever?  Because this default will effectively mandate that.
 Imagine if such a mandate came from CSS.  URLs are a backbone concept of
the internet and we shouldn't go fiddling with it.

Dave also responded:

 I'll wait till it's fleshed out more didn't last long, eh? ;-) Anyway,
I don't really
 understand this argument but do you think there's much value to a
philosophical
 debate on es-discuss?

Well, I practice Olympian levels of patience with my four small children
day in and day out, so you'll have to forgive me if I've got none left over
for you, good sir. ; )

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


Re: Module Comments

2012-12-06 Thread Erik Arvidsson
On Thu, Dec 6, 2012 at 9:42 AM, Kevin Smith khs4...@gmail.com wrote:

 Dave responded by pointing out that we don't want from to have
 overloaded semantics.  I actually think this form has potential, because it
 further aligns import with the other binding forms:

 var a = x;
 var { b } = y;

 // Symmetry!

 import a from x;
 import { b } from y;


+1

This also matches what Yehuda and Domenic proposed a few weeks ago.

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


Re: On dropping @names

2012-12-06 Thread Andreas Rossberg
On 5 December 2012 19:19, Claus Reinke claus.rei...@talk21.com wrote:
 their operational generativity perhaps being a mismatch with their
 seemingly static meaning in certain syntactic forms,

 This appears to be ungrounded. See below.

Personally, I also consider that a non-issue, but it was concern that
was raised.

 Implicit scoping in a language with nested scopes has never been a
 good idea (even the implicit var/let scopes in JS are not its strongest
 point). Prolog got away with it because it had a flat program structure
 in the beginning, and even that fell down when integrating Prolog-like
 languages into functional one, or when adding local sets of answers.

 Indeed. (Although I don't think we have implicit let-scopes in JS.)

 There are few enough cases (scope to nearest enclosing block unless there is
 an intervening conditional or loop construct,

If you mean something like

  if (bla) let x;

then that is not actually legal.

 to nearest for loop body if it
 appears in the loop header, to the right in a comprehension) that the
 difference might not matter.
 I would have preferred if let had not been modeled after var so much, but
 that is another topic.

It is as clean as it can get given JS. And you may be surprised to
hear that there are some voices who actually would have preferred a
_more_ var-like behaviour.

 So I'm not sure how your concerns are being addressed by
 merely replacing a declarative scoping construct by an explicitly
 imperative gensym construct?

 We have the gensym construct anyway, @-names were intended to be merely
 syntactic sugar on top of that.

 Yes, so my question was how removing the sugar while keeping
 the semantics is going to address the concerns voiced in the meeting
 notes.

The concern was that the sugar has issues, not symbol semantics as such.


 Scope extrusion semantics actually is equivalent to an allocation
 semantics. The only difference is that the store is part of your term
 syntax instead of being a separate runtime environment, but it does
 not actually make it more declarative in any deeper technical sense.
 Name generation is still an impure effect, albeit a benign one.

 For me, as a fan of reduction semantics, having all of the semantics
 explainable in the term syntax is an advantage!-) While it is simple to map
 between the two approaches, the nu-binders are more declarative in terms
 of simpler program equivalences: for gensym,
 one needs to abstract over generated symbols and record sharing
 of symbols, effectively reintroducing what nu-binders model directly.

The program equivalences are the same, up to annoying additional
congruences you need to deal with for nu-binders, which complicate
matters. Once you actually try to formalise semantic reasoning (think
e.g. logical relations), it turns out that a representation with a
separate store is significantly _easier_ to handle. Been there, done
that.

 gensym is more imperative in terms of the simplest implementation:
 create a globally unused symbol.

Which also happens to be the simplest way of implementing
alpha-conversion. Seriously, the closer you look, the more it all
boils down to the same thing.

 As Brendon mentions, nu-scoped variables aren't all that different
 from lambda-scoped variables. It's just that most implementations
 do not support computations under a lambda binder, so lambda
 variables do not appear to be dynamic constructs to most people,
 while nu binders rely on computations under the binders, so a
 static-only view is too limited.

 I think you are confusing something. All the classical name calculi
 like pi-calculus or nu-calculus don't reduce/extrude name binders
 under abstraction either.

 Not under lambda-binders, but under nu-binders - they have to.

 If was explaining that the static/dynamic differences that seem to make
 some meeting attendees uncomfortable are not specific to nu-scoped
 variables, but to implementation strategies. For lambda-binders, one can get
 far without reducing below them, but if one lifts that restriction,
 lambda-bound variables appear as runtime constructs, too, just as for
 nu-binders and nu-bound variables (gensym-ed names).

Not sure what you're getting at precisely, but I don't think anybody
would seriously claim that nu-binders are useful as an actual
implementation strategy.

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


Re: Module Comments

2012-12-06 Thread Axel Rauschmayer
+1

Compared to Node.js, I love ES6 exports, but Node.js module imports are easier 
to understand.

Claus’ suggestion would make `import` similar to `let` and people could 
basically think of modules as objects.


On Dec 6, 2012, at 10:41 , Claus Reinke claus.rei...@talk21.com wrote:

 Well, the thing is it isn't consistent with the destructuring meaning: 
 dropping the curlies here means extracting a single export (aka property), 
 which is not what it means in destructuring assignment/binding anywhere else.
 
 But that said, the convenience may well still trump the inconsistency.
 
 I think I'd prefer consistency here, as it also allows to get rid of
 
   import foo as foo;
 
 and replace it with
 
   import foo from foo;
 
 which keeps the order of
 
   import {x,y} from foo
 
 and it is all just module-level destructuring (fewer new concepts).

-- 
Dr. Axel Rauschmayer
a...@rauschma.de

home: rauschma.de
twitter: twitter.com/rauschma
blog: 2ality.com

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


Re: (Map|Set|WeakMap)#set() returns `this` ?

2012-12-06 Thread Mark S. Miller
On Wed, Dec 5, 2012 at 8:05 PM, Rick Waldron waldron.r...@gmail.com wrote:



 On Wed, Dec 5, 2012 at 10:33 PM, Bill Frantz fra...@pwpconsult.com wrote:

 On 12/5/12 at 1:50 AM, jussi.kallioko...@gmail.com (Jussi Kalliokoski)
 wrote:

 I personally think returning `this` in absence of any meaningful value
 (and
 chaining in general) is a bad pattern.


 /lurk

 I have to agree with Jussi here. Whenever I consider chaining using the
 returned values from the various things called, my programming paranoia hair
 stands on end. Let me try to explain:

 Whenever I program, I try to trust as little code as possible. With
 chaining, there are two possibilities for getting the wrong answer in the
 returned value:

   * I or someone else wrote it, but screwed up,
   * Someone hostile wrote it and is trying to trip me up.

 If there is a language construct that allows chaining -- like the Pascal
 with construct -- then I am only trusting the language*, not other
 fragments of programs. If I depend on things I call returning the correct
 this, then I am depending on them and my dependency set is a lot larger. A
 larger dependency set makes me nervous.

 Cheers - Bill

 * For the really paranoid, minimizing the parts of the language depended
 on is important. Not all JS implementations behave the same way in the
 corner cases.


 Again, I reject the notion that someone might screw up is a valid argument
 for this, or any, discussion. It's one thing to be aware of the potential
 for misuse, but entirely another to succumb to fear driven design.

Is fear driven design just a derogatory phrase for defensive programming?



 Rick


 ___
 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: Module Comments

2012-12-06 Thread Domenic Denicola
For the record, here's the idea Yehuda and I worked out:

https://gist.github.com/1ab3f0daa7b37859ce43

I would *really* appreciate if people read it (it's easy reading, I promise!) 
and incorporated some of our concerns and ideas into their thinking on module 
syntax.

In general, it tries to eliminate the ExportSpecifierSet and ImportSpecifierSet 
microsyntaxes in favor of standard object literal/destructuring forms, 
respectively. It also made export and import syntax symmetric.

It apparently failed to get much traction among committee members, mainly 
because of objections to our reformation of the export-side syntax. 
(Second-hand info.) E.g. the current export function foo() { } was preferred to 
the proposed export { foo() { } }, and---less aesthetically---our special 
behavior for ObjectLiteral expressions over other expressions was a bit weird.

I still think the import-side reformation is important and stand by everything 
in the proposal in that regard. As mentioned in other messages in this thread, 
the current form is confusingly dual-natured. And I maintain that the 
incomplete semi-destructuring microsyntax of ImportSpecifierSet adds a lot of 
cognitive burden.

If we can start by fixing the import side, I have some other ideas on how to 
make the export side better that hopefully will be more appealing to the 
committee. But I don't want to try proposing those yet until we can get the 
buy-in on fixing import.


From: es-discuss-boun...@mozilla.org [es-discuss-boun...@mozilla.org] on behalf 
of Erik Arvidsson [erik.arvids...@gmail.com]
Sent: Thursday, December 06, 2012 09:54
To: Kevin Smith
Cc: es-discuss
Subject: Re: Module Comments


On Thu, Dec 6, 2012 at 9:42 AM, Kevin Smith 
khs4...@gmail.commailto:khs4...@gmail.com wrote:
Dave responded by pointing out that we don't want from to have overloaded 
semantics.  I actually think this form has potential, because it further aligns 
import with the other binding forms:

var a = x;
var { b } = y;

// Symmetry!

import a from x;
import { b } from y;

+1

This also matches what Yehuda and Domenic proposed a few weeks ago.

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


Re: Module Comments

2012-12-06 Thread Andreas Rossberg
On 6 December 2012 15:42, Kevin Smith khs4...@gmail.com wrote:
 5) Dynamic exports via `export = ?` could make interop with existing
 module systems easier.  But how does that work?

 Dave gave an outline.  I'm liking this.  What are the downsides, if any?

The downside is that it introduces a severe anomaly into the module
semantics (a module which actually has no instance). I could live with
this feature if we were to find a way to explain it in terms of simple
syntactic sugar on both the import and export side, but screwing and
complicating the semantics for minor syntactic convenience is not
something I am particularly fond of.

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


Re: Module Comments

2012-12-06 Thread Yehuda Katz
One plausible variant to our proposal that might be easier to swallow (as
it doesn't have the special-cased ObjectLiteral problem) is:

   - Replace `export ExportSpecifierSet` with `export ObjectLiteral` for
   static exports
   - Allow `export = foo` (or something like it) for single exports
   - Unify the import syntax to support the full destructuring syntax and
   to work on both static and single exports

This retains the advantages of reducing micro-syntax and reforming import
without forcing an awkward special-casing of `export ObjectLiteral`


On Thu, Dec 6, 2012 at 7:44 AM, Domenic Denicola 
dome...@domenicdenicola.com wrote:

  For the record, here's the idea Yehuda and I worked out:

 https://gist.github.com/1ab3f0daa7b37859ce43

 I would *really* appreciate if people read it (it's easy reading, I
 promise!) and incorporated some of our concerns and ideas into their
 thinking on module syntax.

 In general, it tries to eliminate the ExportSpecifierSet and
 ImportSpecifierSet microsyntaxes in favor of standard object
 literal/destructuring forms, respectively. It also made export and import
 syntax symmetric.

 It apparently failed to get much traction among committee members, mainly
 because of objections to our reformation of the export-side syntax.
 (Second-hand info.) E.g. the current export function foo() { } was
 preferred to the proposed export { foo() { } }, and---less
 aesthetically---our special behavior for ObjectLiteral expressions over
 other expressions was a bit weird.

 I still think the import-side reformation is important and stand by
 everything in the proposal in that regard. As mentioned in other messages
 in this thread, the current form is confusingly dual-natured. And I
 maintain that the incomplete semi-destructuring microsyntax of
 ImportSpecifierSet adds a lot of cognitive burden.

 If we can start by fixing the import side, I have some other ideas on how
 to make the export side better that hopefully will be more appealing to the
 committee. But I don't want to try proposing those yet until we can get the
 buy-in on fixing import.

  --
 *From:* es-discuss-boun...@mozilla.org [es-discuss-boun...@mozilla.org]
 on behalf of Erik Arvidsson [erik.arvids...@gmail.com]
 *Sent:* Thursday, December 06, 2012 09:54
 *To:* Kevin Smith
 *Cc:* es-discuss
 *Subject:* Re: Module Comments


  On Thu, Dec 6, 2012 at 9:42 AM, Kevin Smith khs4...@gmail.com wrote:

 Dave responded by pointing out that we don't want from to have
 overloaded semantics.  I actually think this form has potential, because it
 further aligns import with the other binding forms:

  var a = x;
 var { b } = y;

  // Symmetry!

  import a from x;
 import { b } from y;


  +1

  This also matches what Yehuda and Domenic proposed a few weeks ago.

  --
 erik

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




-- 
Yehuda Katz
(ph) 718.877.1325
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: On dropping @names

2012-12-06 Thread Claus Reinke

I would have preferred if let had not been modeled after var so much, but
that is another topic.


It is as clean as it can get given JS. 


I was hoping for something roughly like

   let lhs = rhs; statements
   // non-recursive, scope is statements

   let { declarations }; statements 
   // recursive, scope is declarations and statements


No hoisting needed to support recursion, no temporal deadzones,
no problem with referring to old x when defining x non-recursively.
And less mixing of declarations and statements.

And you may be surprised to hear that there are some voices who 
actually would have preferred a _more_ var-like behaviour.


Well, in the beginning let was meant to replace var, so it had to
be more or less like it for an easy transition. Later, even that transition
was considered too hard, so var an let coexist, giving more freedom
for let design. At least, that is my impression.


The program equivalences are the same, up to annoying additional
congruences you need to deal with for nu-binders, which complicate
matters. Once you actually try to formalise semantic reasoning (think
e.g. logical relations), it turns out that a representation with a
separate store is significantly _easier_ to handle. Been there, done
that.


Hmm, I used to find reasoning at term level quite useful (a very long
time ago, I was working on a functional logic language, which had 
something like nu-binders for logic variables). Perhaps it depends on

whether one reasons about concrete programs (program development)
or classes of programs (language-level proofs).


gensym is more imperative in terms of the simplest implementation:
create a globally unused symbol.


Which also happens to be the simplest way of implementing
alpha-conversion. Seriously, the closer you look, the more it all
boils down to the same thing.


Yep. Which is why I thought to speak up when I saw those concerns
in the meeting notes;-)


Not under lambda-binders, but under nu-binders - they have to.

If was explaining that the static/dynamic differences that seem to make
some meeting attendees uncomfortable are not specific to nu-scoped
variables, but to implementation strategies. For lambda-binders, one can get
far without reducing below them, but if one lifts that restriction,
lambda-bound variables appear as runtime constructs, too, just as for
nu-binders and nu-bound variables (gensym-ed names).


Not sure what you're getting at precisely, but I don't think anybody
would seriously claim that nu-binders are useful as an actual
implementation strategy.


More as a user-level representation of whatever implementation
strategy is used behind the scenes, just as lambda-binders are a
user-level representation of efficient implementations. 


But to clarify the point:

Consider something like: 


   (\x. (\y. [y, y]) x)

Most implementations won't reduce under the \x., nor will they
bother to produce any detailed result, other than 'function'. So
those x and y are purely static constructs.

However, an implementation that does reduce under the \x.
will need to deal with x as a dynamic construct, passing it to
\y. to deliver the result (\x. [x,x]).

Now, the same happens with nu-binders, or private names:
after bringing them in scope, computation continues under
the nu-binder, so there is a dynamic representation (the
generated symbol) of the variable.

My point is that there isn't anything worrying about variables
appearing at dynamic constructs, nor is it specific to private
names - normal variables appearing to be static is just a
consequence of limited implementations. What is static is
the binding/scope structure, not the variables.

Since we mostly agree, I'll leave this here. Perhaps it helps
the meeting participants with their concerns.

Claus

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


Re: Module Comments

2012-12-06 Thread Andreas Rossberg
On 6 December 2012 16:44, Domenic Denicola dome...@domenicdenicola.com wrote:
 For the record, here's the idea Yehuda and I worked out:

 https://gist.github.com/1ab3f0daa7b37859ce43

 I would *really* appreciate if people read it (it's easy reading, I
 promise!) and incorporated some of our concerns and ideas into their
 thinking on module syntax.

I strongly agree with having the

import x from ...
import {x, y} from ...

symmetry and consistent binding on the left. However, the more radical
parts of your proposal (allowing arbitrary export expressions, and
arbitrary import patterns) do not work.

The problem is that imports are not normal variable assignments. They
do not copy values, like normal destructuring, they are aliasing
bindings! If you were to allow arbitrary expressions and patterns,
then this would imply aliasing of arbitrary object properties. Not
only is this a completely new feature, it also is rather questionable
-- the aliased location might disappear, because objects are mutable.

Consider:

  module A {
let o = {
  x: [1, 2],
  f() { o.x = 666 }
}
export o
  }

  import {x: [a, b], f} from A
  a = 3  // is this supposed to modify the array?
  f()
  print(a)  // x is no longer an array, a doesn't even exist

In other words, what you are proposing has no longer anything to do
with static scoping.

You could arguably make this saner by interpreting nested patterns in
an import as copying, not aliasing, but I think mixing meanings like
that would be rather confusing and surprising.

You could also consider imports always meaning copying, but then you
exporting a variable will no longer be useful.

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


Re: Module Comments

2012-12-06 Thread Kevin Smith
 The downside is that it introduces a severe anomaly into the module
 semantics (a module which actually has no instance). I could live with
 this feature if we were to find a way to explain it in terms of simple
 syntactic sugar on both the import and export side, but screwing and
 complicating the semantics for minor syntactic convenience is not
 something I am particularly fond of.


What if this:

export = boo;

Actually creates a static export with some exotic name, say __DEFAULT__
(for the sake of argument) and initializes it to the value boo.

And this form:

import boo from boo.js;

Creates a binding to __DEFAULT__ in boo.js, if it exists, or to the
module instance of boo.js otherwise.

Would that work as a desugaring?

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


Re: On dropping @names

2012-12-06 Thread Andreas Rossberg
On 6 December 2012 17:25, Claus Reinke claus.rei...@talk21.com wrote:
 I was hoping for something roughly like

let lhs = rhs; statements
// non-recursive, scope is statements

let { declarations }; statements// recursive, scope is
 declarations and statements

Problem is that you need mutual recursion between different binding
forms, not just 'let' itself.

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


Re: Module Comments

2012-12-06 Thread Andreas Rossberg
On 6 December 2012 17:33, Kevin Smith khs4...@gmail.com wrote:
 The downside is that it introduces a severe anomaly into the module
 semantics (a module which actually has no instance). I could live with
 this feature if we were to find a way to explain it in terms of simple
 syntactic sugar on both the import and export side, but screwing and
 complicating the semantics for minor syntactic convenience is not
 something I am particularly fond of.

 What if this:

 export = boo;

 Actually creates a static export with some exotic name, say __DEFAULT__ (for
 the sake of argument) and initializes it to the value boo.

 And this form:

 import boo from boo.js;

 Creates a binding to __DEFAULT__ in boo.js, if it exists, or to the module
 instance of boo.js otherwise.

 Would that work as a desugaring?

I suggested something along these lines at some point in the past, but
there were some concerns with it that, unfortunately, I do not
remember. Maybe it can be resolved.

Note, however, that you still assume some hack in the semantics with
the if it exists part. To avoid that, you need to divorce the import
syntax from the naming-an-external-module syntax -- which I'd actually
prefer anyway, and which was the case in the previous version of the
proposal.

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


Re: Module Comments

2012-12-06 Thread Matthew Robb
What about trying it the other way, flip everything.

import foo as bar;
import foo as { baz }


On Thu, Dec 6, 2012 at 8:42 AM, Andreas Rossberg rossb...@google.comwrote:

 On 6 December 2012 17:33, Kevin Smith khs4...@gmail.com wrote:
  The downside is that it introduces a severe anomaly into the module
  semantics (a module which actually has no instance). I could live with
  this feature if we were to find a way to explain it in terms of simple
  syntactic sugar on both the import and export side, but screwing and
  complicating the semantics for minor syntactic convenience is not
  something I am particularly fond of.
 
  What if this:
 
  export = boo;
 
  Actually creates a static export with some exotic name, say __DEFAULT__
 (for
  the sake of argument) and initializes it to the value boo.
 
  And this form:
 
  import boo from boo.js;
 
  Creates a binding to __DEFAULT__ in boo.js, if it exists, or to the
 module
  instance of boo.js otherwise.
 
  Would that work as a desugaring?

 I suggested something along these lines at some point in the past, but
 there were some concerns with it that, unfortunately, I do not
 remember. Maybe it can be resolved.

 Note, however, that you still assume some hack in the semantics with
 the if it exists part. To avoid that, you need to divorce the import
 syntax from the naming-an-external-module syntax -- which I'd actually
 prefer anyway, and which was the case in the previous version of the
 proposal.

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




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


Re: Module Comments

2012-12-06 Thread Andreas Rossberg
On 6 December 2012 17:46, Matthew Robb matthewwr...@gmail.com wrote:
 What about trying it the other way, flip everything.

 import foo as bar;
 import foo as { baz }

Hm, I don't understand. What would that solve?

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


Re: Module Comments

2012-12-06 Thread Matthew Robb
Well the argument being that as it stands it's inconsistent having the
identifier on the RHS for import from and LHS in import as:

import baz from foo;
import foo as foo;

I'm just throwing out simple options for solving that inconsistency.

Possibly even thinking about them as declarations makes the simplest sense
anyway:

var foo = import foo;
var { baz } = import foo;


On Thu, Dec 6, 2012 at 8:49 AM, Andreas Rossberg rossb...@google.comwrote:

 On 6 December 2012 17:46, Matthew Robb matthewwr...@gmail.com wrote:
  What about trying it the other way, flip everything.
 
  import foo as bar;
  import foo as { baz }

 Hm, I don't understand. What would that solve?

 /Andreas




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


Re: Module Comments

2012-12-06 Thread Kevin Smith
 Note, however, that you still assume some hack in the semantics with
 the if it exists part. To avoid that, you need to divorce the import
 syntax from the naming-an-external-module syntax -- which I'd actually
 prefer anyway, and which was the case in the previous version of the
 proposal.


Could we eliminate the hack on the export side instead?

Every module instance has a $DEFAULT export binding.  Normally, it is set
to the module instance itself.  `export = ?` overrides the value of that
binding.  `import x from y` binds $DEFAULT in y to x.  Maybe?

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


Re: (Map|Set|WeakMap)#set() returns `this` ?

2012-12-06 Thread Rick Waldron
On Thu, Dec 6, 2012 at 3:48 AM, Jussi Kalliokoski 
jussi.kallioko...@gmail.com wrote:

 And if it comes down to precedents in the language, even Array#forEach()
 returns undefined, contrary to popular libraries out there. Let's keep some
 consistency here.


Array.prototype.map and Array.prototype.filter return newly created arrays
and as such, are chainable (and will have the same benefits as I described
above)

// map and return a fresh iterable of values
array.map( v = ... ).values()

// map and return a fresh iterable of entries (index/value pairs)
array.filter( v = ... ).entries()





 I agree with you, fear-driven design is bad. But don't you agree that if
 there's chaining, it's better done at language level rather than having all
 APIs be polluted by `this` returns?


Who said all APIs would return `this`? We specified a clear criteria.


 After all, the APIs can't guarantee a `this` return,


Yes they can, they return what the specification defines them to return.


 since they might have something actually meaningful to return, otherwise
 we might as well just replace `undefined` with `this` as the default return
 value.


In the cases I presented, I believe that returning `this` IS the meaningful
return.




 We could introduce mutable primitives so that meaningful return values
 could be stored in arguments, kinda like in C, but instead of error values,
 we'd be returning `this`, heheheh. :)

 I'm curious, do you have any code examples of maps/sets that could be made
 clearer by chaining?


This is incredibly frustrating and indicates to me that you're not actually
reading this thread, but still find it acceptable to contribute to the
discussion.

https://gist.github.com/4219024


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


Re: (Map|Set|WeakMap)#set() returns `this` ?

2012-12-06 Thread Rick Waldron
On Thu, Dec 6, 2012 at 6:53 AM, Andreas Rossberg rossb...@google.comwrote:

 On 6 December 2012 05:05, Rick Waldron waldron.r...@gmail.com wrote:
  Again, I reject the notion that someone might screw up is a valid
 argument
  for this, or any, discussion. It's one thing to be aware of the potential
  for misuse, but entirely another to succumb to fear driven design.

 Fear driven design is pejorative.


I'll own that, my apologies.


 The argument really is about the
 ability to do local reasoning as much as possible, which is a *very*
 valid concern, especially when reading somebody else's code using
 somebody else's library.

 I agree with other voices in this thread that in general, returning
 'this' rather is an anti pattern.


The evidence I've brought to this discussion shows that the most widely
used and depended upon libraries heavily favor the pattern.



 You can get away with it if you
 limit it to very few well-known library functions,


We established a criteria for built-ins, I don't think we should be using
return this by default, but indeed we should where it will be an
expressive benefit.

https://gist.github.com/4219024


 but I doubt that
 blessing such style in the std lib does help that cause.

 /Andreas

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


Re: (Map|Set|WeakMap)#set() returns `this` ?

2012-12-06 Thread Rick Waldron
On Thu, Dec 6, 2012 at 10:34 AM, Mark S. Miller erig...@google.com wrote:



 Is fear driven design just a derogatory phrase for defensive
 programming?


Not at all.

I wrote fear driven design in a moment of frustration, referring only to
the opposition of adopting a (widely held as) best practice based solely on
what appears to be subjective opinions versus objective observation of real
world use cases.

The argument:

if you have to scan the code to another page to figure out which object
the code is interacting with, it's bad readability

Would apply in only one extreme case that is so incredibly stupid, I posit
this will be an anomaly:

  set.add(...).add(...).add(...).add(...).add(...).add(...).add(...)...

The likely very common cases are quite nice and not at all confusing to
read:

(copied from an earlier message in this thread)

Add value to the Set and get a fresh iterable for the keys, values, entries:

  set.add( value ).keys();
  set.add( value ).values();
  set.add( value ).entries();

Add value to the Set and send each value in the set to another operation:

  set.add( value ).forEach( item = ...send to some operation );

Add value to the Set and spread into an array of unique items:

  [ ...set.add(value) ]; // [ a, b, c, ... ]

And of course, the same for Map.

More here: https://gist.github.com/4219024


I have respect for valid technical and security related concerns and would
certainly love to discuss those if any have been identified.


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


Re: (Map|Set|WeakMap)#set() returns `this` ?

2012-12-06 Thread Jussi Kalliokoski
On Thu, Dec 6, 2012 at 8:25 PM, Jussi Kalliokoski 
jussi.kallioko...@gmail.com wrote:

 On Thu, Dec 6, 2012 at 7:32 PM, Rick Waldron waldron.r...@gmail.comwrote:

 Array.prototype.map and Array.prototype.filter return newly created
 arrays and as such, are chainable (and will have the same benefits as I
 described above)

 // map and return a fresh iterable of values
 array.map( v = ... ).values()

 // map and return a fresh iterable of entries (index/value pairs)
 array.filter( v = ... ).entries()


 Of course, but that's pears and apples, .set() doesn't create a new
 instance. And btw, that .values() is redundant.


Wait, sorry about that, wrote before I investigated.





 I agree with you, fear-driven design is bad. But don't you agree that if
 there's chaining, it's better done at language level rather than having all
 APIs be polluted by `this` returns?


 Who said all APIs would return `this`? We specified a clear criteria.


 You're dodging my question: isn't it better for the chaining to be
 supported by the language semantics rather than be injected to APIs in
 order to have support?


 After all, the APIs can't guarantee a `this` return,


 Yes they can, they return what the specification defines them to return.


 What I mean is that the not all functions in an API can return `this`
 anyway (like getters), so it's inconsistent. After all, it's not a very
 useful API if you can just set but not get.

 since they might have something actually meaningful to return, otherwise
 we might as well just replace `undefined` with `this` as the default return
 value.


 In the cases I presented, I believe that returning `this` IS the
 meaningful return.


 No, it's a generic return value if it's applied to everything that's not a
 getter.



 We could introduce mutable primitives so that meaningful return values
 could be stored in arguments, kinda like in C, but instead of error values,
 we'd be returning `this`, heheheh. :)

 I'm curious, do you have any code examples of maps/sets that could be
 made clearer by chaining?


 This is incredibly frustrating and indicates to me that you're not
 actually reading this thread, but still find it acceptable to contribute to
 the discussion.

 https://gist.github.com/4219024


 I'm sorry you feel that way, but calm down. I've read the gist all right
 and just read the latest version, and imho it's quite a biased example,
 you're making it seem harder than it actually is. For example, the last
 paragraph:

 ( map.set(key, value), set ).keys();

 // simpler:
 map.set(key, value);
 map.keys();

 ( set.add(value), set ).values();

 // simpler:
 set.add(value);
 set.values;

 ( set.add(value), set ).forEach( val =  );

 // simpler:
 set.add(value);
 set.forEach( val =  );

 Why would you need to stuff everything in one line? This way it's more
 version control friendly as well, since those two lines of code have
 actually nothing to do with each other, aside from sharing dealing with the
 same object. Why do you want to get all of those things from .set()/.add(),
 methods which have nothing to do with what you're getting at?

 Cheers,
 Jussi

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


Re: Module Comments

2012-12-06 Thread Brandon Benvie
 Every module instance has a $DEFAULT export binding.  Normally, it is
set to the module instance itself.  `export = ?` overrides the value of
that binding.   `import x from y` binds $DEFAULT in y to x.  Maybe?


That would be how Node.js does. For those unfamiliar with how it works,
it's basically like this

var mod = { exports: {} };
(function(module, exports){
...
})(mod, mod.exports);

So if you assign things to the default exports like
exports.firstExport = value;
exports.secondExport = value;

You're assigning to the default provided export object. But since you also
have access to the container (module) you can opt to fully overwrite it
module.exports = singleExportedThing;

If you added things to exports and then overwrote module.exports with a new
value, those initial exports will not be visible as exports because the
original export object is overwritten.
exports.willBeOverwritten = true;
module.exports = singleExportedThing;


So the single export route is opt-in, but it's opted into in the large
majority of cases.


On Thu, Dec 6, 2012 at 11:54 AM, Kevin Smith khs4...@gmail.com wrote:


 Note, however, that you still assume some hack in the semantics with
 the if it exists part. To avoid that, you need to divorce the import
 syntax from the naming-an-external-module syntax -- which I'd actually
 prefer anyway, and which was the case in the previous version of the
 proposal.


 Could we eliminate the hack on the export side instead?

 Every module instance has a $DEFAULT export binding.  Normally, it is set
 to the module instance itself.  `export = ?` overrides the value of that
 binding.  `import x from y` binds $DEFAULT in y to x.  Maybe?

 - Kevin


 ___
 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: Module Comments

2012-12-06 Thread Brendan Eich

David Herman wrote:

  Cool, definitely want the plain identifier form, it's part of the binding 
(and destructuring) pattern language.


Well, the thing is it isn't consistent with the destructuring meaning: dropping 
the curlies here means extracting a single export (aka property), which is not 
what it means in destructuring assignment/binding anywhere else.


You are so right. Therefore I think Yehuda et al. (as Andreas affirmed) 
are spot-on in advocating


import foo from foo; // import the singleton export = thing from foo
import {bar} from foo; // import the bar export from foo

and we don't have a RTL problem.

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


Re: Comments on Meeting Notes

2012-12-06 Thread Michał Gołębiowski
Luke Hoban lu...@microsoft.com wrote:

  IE10 sort of did. The following code:
 (function(){ 'use strict'; return !this; })();
 returns false in IE10. Who knows what other
 deviations from the standard there are...


 That code returns true in IE10 standards mode.  See test262.ecmascript.orgfor 
 tests validating this and other ES5 implementation compatibility.  If
 you see things not covered there, open bugs suggesting new tests:
 https://bugs.ecmascript.org/enter_bug.cgi?product=Test262.



Indeed, it must have been an earlier IE10 preview version then. I apologize
for the accusation.

-- 
Michał Z. Gołębiowski
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: (Map|Set|WeakMap)#set() returns `this` ?

2012-12-06 Thread Jussi Kalliokoski
On Thu, Dec 6, 2012 at 8:44 PM, Rick Waldron waldron.r...@gmail.com wrote:

 values() returns an iterable of the values in the array. Array, Map and
 Set will receive all three: keys(), values(), entries(). Feel free to start
 a new thread if you want to argue about iterator protocol.


Yes, I apologized for that mistake already, I remembered incorrectly. I
don't have a want to argue, just like I'm sure you don't.

I'm absolutely not dodging the question, I answered this in a previous
 message, much earlier. Cascade/monocle/mustache is not a replacement here.


That wasn't the question I asked. Cascade/monocle/mustache aren't even
ready yet, and are hence in no way an indication that chaining cannot be
made a language-side construct. I believe it can and will, and at that
point, returning this becomes completely meaningless. But (I don't see) how
can you fix this on the language syntax side:

var obj = {
  foo: bar,
  baz: taz
}
set.add(obj)
return set

instead of simply:

return set.add({
  foo: bar,
  baz: taz
})


 What I mean is that the not all functions in an API can return `this`
 anyway (like getters), so it's inconsistent. After all, it's not a very
 useful API if you can just set but not get.


 That's exactly my point. The set/add API return this, allowing
 post-mutation operations to be called: such as get or any of the examples
 I've given throughout this thread.


What? I'm really sorry, but I can't understand how what I said leads to
your point. But I bet we're both wasting our time with this part, so it's
probably best to just leave it.


 No one said anything about applying return this to everything that's not
 a getter. That was exactly what the criteria we have consensus on defines.
 It's in the meeting notes for Nov. 29.


Sorry, about that, the meeting notes (in the part Cascading this returns)
just say:

Supporting agreement
(Discussion to determine a criteria for making this API specification
distinction)
Consensus... with the criteria that these methods are not simply a set of
uncoordinated side effects that happen to have a receiver in common, but a
set of coordinated side effects on a specific receiver and providing access
to the target object post-mutation.

With no reference to the logic behind the conclusion (these methods are
not simply a set of uncoordinated side effects that happen to have a
receiver in common). I fail to see how .set()/.add() are a special case.
Am I missing something?

Please read everything I've written so far, it's not fair to make me
 constantly repeat myself in this thread.


I agree, and I'm sorry, but I have, at least everything on this thread,
those referred to and those that have seemed related. I'm doing my best,
but I'm afraid I can't keep up with every thread in my inbox, and I don't
think it's a good reason for me not to contribute at all.

Of course I could've shown it as you have here, but I made examples where
 the intention was to match the preceding examples illustrated in the gist.


Fair enough, but I fail to see the convenience in your examples.

 Why would you need to stuff everything in one line?


 As evidenced several times throughout this thread, the pattern is widely
 implemented in the most commonly used library APIs, so I guess the answer
 is The kids love it.


document.write() is widely implemented too, doesn't make it good or worth
repeating.


 This way it's more version control friendly as well, since those two lines
 of code have actually nothing to do with each other, aside from sharing
 dealing with the same object. Why do you want to get all of those things
 from .set()/.add(), methods which have nothing to do with what you're
 getting at?


 You could just as easily have them on separate lines, but in cases where
 it might be desirable to immediately operate on the result of the mutation,
 chaining the next method call has the net appearance of a single tasks (if
 that's how a programmer so chooses to express their program).


So it's taste, rather than convenience?

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


Re: (Map|Set|WeakMap)#set() returns `this` ?

2012-12-06 Thread Dean Landolt
On Thu, Dec 6, 2012 at 2:41 PM, Jussi Kalliokoski 
jussi.kallioko...@gmail.com wrote:

 On Thu, Dec 6, 2012 at 8:44 PM, Rick Waldron waldron.r...@gmail.comwrote:

 values() returns an iterable of the values in the array. Array, Map and
 Set will receive all three: keys(), values(), entries(). Feel free to start
 a new thread if you want to argue about iterator protocol.


 Yes, I apologized for that mistake already, I remembered incorrectly. I
 don't have a want to argue, just like I'm sure you don't.



All this misses your important pears and oranges point. These are not
mutable APIs, which is a key distinction. The sort method would have been a
good example of a mutable API returning `this`. But it's not exactly a
model to emulate.



  I'm absolutely not dodging the question, I answered this in a previous
 message, much earlier. Cascade/monocle/mustache is not a replacement here.


 That wasn't the question I asked. Cascade/monocle/mustache aren't even
 ready yet, and are hence in no way an indication that chaining cannot be
 made a language-side construct. I believe it can and will, and at that
 point, returning this becomes completely meaningless. But (I don't see) how
 can you fix this on the language syntax side:

 var obj = {
   foo: bar,
   baz: taz
 }
 set.add(obj)
 return set

 instead of simply:

 return set.add({
   foo: bar,
   baz: taz
 })


 What I mean is that the not all functions in an API can return `this`
 anyway (like getters), so it's inconsistent. After all, it's not a very
 useful API if you can just set but not get.


 That's exactly my point. The set/add API return this, allowing
 post-mutation operations to be called: such as get or any of the examples
 I've given throughout this thread.


 What? I'm really sorry, but I can't understand how what I said leads to
 your point. But I bet we're both wasting our time with this part, so it's
 probably best to just leave it.


 No one said anything about applying return this to everything that's not
 a getter. That was exactly what the criteria we have consensus on defines.
 It's in the meeting notes for Nov. 29.


 Sorry, about that, the meeting notes (in the part Cascading this
 returns) just say:

 Supporting agreement
 (Discussion to determine a criteria for making this API specification
 distinction)
 Consensus... with the criteria that these methods are not simply a set of
 uncoordinated side effects that happen to have a receiver in common, but a
 set of coordinated side effects on a specific receiver and providing access
 to the target object post-mutation.

 With no reference to the logic behind the conclusion (these methods are
 not simply a set of uncoordinated side effects that happen to have a
 receiver in common). I fail to see how .set()/.add() are a special case.
 Am I missing something?

  Please read everything I've written so far, it's not fair to make me
 constantly repeat myself in this thread.


 I agree, and I'm sorry, but I have, at least everything on this thread,
 those referred to and those that have seemed related. I'm doing my best,
 but I'm afraid I can't keep up with every thread in my inbox, and I don't
 think it's a good reason for me not to contribute at all.

 Of course I could've shown it as you have here, but I made examples where
 the intention was to match the preceding examples illustrated in the gist.


 Fair enough, but I fail to see the convenience in your examples.

   Why would you need to stuff everything in one line?


 As evidenced several times throughout this thread, the pattern is widely
 implemented in the most commonly used library APIs, so I guess the answer
 is The kids love it.



But which kids? There certainly appears to be quite a sampling bias in your
survey -- I didn't see a single actual *collection* library. Sampling their
choices would be the most helpful, not *what the kids are doing*.

Plus there are other alternatives I haven't seen discussed, so the design
space has barely been explored. For instance buckets [1] is a nice example
of a collection library that takes an approach more reminiscent of
javascript's existing array mutation methods -- its add method returns
`true` if the item was newly created or `false` if it was already present
in the collection -- a lot like javascript's delete operator. I'm not
necessarily advocating for this, just offering up the idea that any survey
should look closer at existing collection libraries to get a better feel
for the full design space.

[1] https://github.com/mauriciosantos/buckets



 document.write() is widely implemented too, doesn't make it good or worth
 repeating.



That's a low blow :)



  This way it's more version control friendly as well, since those two
 lines of code have actually nothing to do with each other, aside from
 sharing dealing with the same object. Why do you want to get all of those
 things from .set()/.add(), methods which have nothing to do with what
 you're getting at?


 You could just as easily 

Re: (Map|Set|WeakMap)#set() returns `this` ?

2012-12-06 Thread Andrea Giammarchi
Had same thoughts on returning true or false as map.delete(key) would do.

However, it's easy to have ambiguity there ... assuming the key can always
be set, 'cause even a frozen Map should be able, and it is, to set a key
internally, will true mean that key was not there ? will false mean that
key was already set or we reached maximum number of keys? Shouldn't latter
case be an error as it is for Array(Math.pow(2, 32) - 1).push(invalid
array length); ?

This boolean return is semantic with what delete does, less semantic with
(setting[property] = value) logic thought but surely a valid possibility.

Anyway, I would like to know what other TC39 members think, cause they all
agreed already and i see this thread too dead and philosophical at this
point ... :-/

We all have made our points but it has been decided then ... well, we
should simply deal with it?

br






On Thu, Dec 6, 2012 at 12:14 PM, Dean Landolt d...@deanlandolt.com wrote:




 On Thu, Dec 6, 2012 at 2:41 PM, Jussi Kalliokoski 
 jussi.kallioko...@gmail.com wrote:

 On Thu, Dec 6, 2012 at 8:44 PM, Rick Waldron waldron.r...@gmail.comwrote:

 values() returns an iterable of the values in the array. Array, Map and
 Set will receive all three: keys(), values(), entries(). Feel free to start
 a new thread if you want to argue about iterator protocol.


 Yes, I apologized for that mistake already, I remembered incorrectly. I
 don't have a want to argue, just like I'm sure you don't.



 All this misses your important pears and oranges point. These are not
 mutable APIs, which is a key distinction. The sort method would have been a
 good example of a mutable API returning `this`. But it's not exactly a
 model to emulate.



  I'm absolutely not dodging the question, I answered this in a previous
 message, much earlier. Cascade/monocle/mustache is not a replacement here.


 That wasn't the question I asked. Cascade/monocle/mustache aren't even
 ready yet, and are hence in no way an indication that chaining cannot be
 made a language-side construct. I believe it can and will, and at that
 point, returning this becomes completely meaningless. But (I don't see) how
 can you fix this on the language syntax side:

 var obj = {
   foo: bar,
   baz: taz
 }
 set.add(obj)
 return set

 instead of simply:

 return set.add({
   foo: bar,
   baz: taz
 })


 What I mean is that the not all functions in an API can return `this`
 anyway (like getters), so it's inconsistent. After all, it's not a very
 useful API if you can just set but not get.


 That's exactly my point. The set/add API return this, allowing
 post-mutation operations to be called: such as get or any of the examples
 I've given throughout this thread.


 What? I'm really sorry, but I can't understand how what I said leads to
 your point. But I bet we're both wasting our time with this part, so it's
 probably best to just leave it.


 No one said anything about applying return this to everything that's
 not a getter. That was exactly what the criteria we have consensus on
 defines. It's in the meeting notes for Nov. 29.


 Sorry, about that, the meeting notes (in the part Cascading this
 returns) just say:

 Supporting agreement
 (Discussion to determine a criteria for making this API specification
 distinction)
 Consensus... with the criteria that these methods are not simply a set
 of uncoordinated side effects that happen to have a receiver in common, but
 a set of coordinated side effects on a specific receiver and providing
 access to the target object post-mutation.

 With no reference to the logic behind the conclusion (these methods are
 not simply a set of uncoordinated side effects that happen to have a
 receiver in common). I fail to see how .set()/.add() are a special case.
 Am I missing something?

  Please read everything I've written so far, it's not fair to make me
 constantly repeat myself in this thread.


 I agree, and I'm sorry, but I have, at least everything on this thread,
 those referred to and those that have seemed related. I'm doing my best,
 but I'm afraid I can't keep up with every thread in my inbox, and I don't
 think it's a good reason for me not to contribute at all.

 Of course I could've shown it as you have here, but I made examples where
 the intention was to match the preceding examples illustrated in the gist.


 Fair enough, but I fail to see the convenience in your examples.

   Why would you need to stuff everything in one line?


 As evidenced several times throughout this thread, the pattern is widely
 implemented in the most commonly used library APIs, so I guess the answer
 is The kids love it.



 But which kids? There certainly appears to be quite a sampling bias in
 your survey -- I didn't see a single actual *collection* library.
 Sampling their choices would be the most helpful, not *what the kids are
 doing*.

 Plus there are other alternatives I haven't seen discussed, so the design
 space has barely been explored. For instance buckets [1] is a 

Re: On dropping @names

2012-12-06 Thread Claus Reinke

I was hoping for something roughly like

   let lhs = rhs; statements
   // non-recursive, scope is statements

   let { declarations }; statements// recursive, scope is
declarations and statements


Problem is that you need mutual recursion between different 
binding forms, not just 'let' itself.


Leaving legacy var/function out of it, is there a problem with
allowing mutually recursive new declaration forms in there?

   let { // group of mutually recursive bindings

   [x,y] = [42,Math.PI]; // initialization, not assignment

   even(n) { .. odd(n-1) .. } // using short method form
   odd(n) { .. even(n-1) .. } // for non-hoisting functions

   class X { .. }
   class C extends S { .. new X( odd(x) ) .. }
   class S { }
   };
   if (even(2)) console.log(  new C() );

Or did I misunderstand your objection?
Claus

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


Re: (Map|Set|WeakMap)#set() returns `this` ?

2012-12-06 Thread Brendan Eich

Andrea Giammarchi wrote:
Anyway, I would like to know what other TC39 members think, cause they 
all agreed already


You've heard from Mark and me (also Jason Orendorff of Mozilla, who is 
de-facto champion of some ES6 proposals) in this thread, along with 
Rick. You won't get a definitive resolution on es-discuss from TC39, 
however.


Allen may have a thought on how to proceed, but I think this discussion 
is still valuable so long as we don't rehash or butt heads too much.


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


Re: Comments on Meeting Notes

2012-12-06 Thread Jeff Walden
On 12/04/2012 03:57 PM, Brendan Eich wrote:
 Allen Wirfs-Brock wrote:
 The timing of copying is only an issue if the function actually assigns to a 
 formal parameter.  Such assignments should be pretty easy to 
 (conservatively) statically check for.
 
 I'm telling you what engines do. Not what they might do. I did assignment 
 analysis in SpiderMonkey for Firefox 3.6, it was helpful in its day. I think 
 a bunch has been ripped out because modern JITs don't need it.
 
 [...]the point I made, cited above:  engines don't do it currently and feel 
 little pressure to do so. Chicken and egg.

SpiderMonkey's implementation of the arguments object functions exactly as 
described here for functions with strict mode code -- actually for all 
functions, I think.  Regarding the strict mode semantics specifically, it was 
fairly easy to make those optimizations when I was implementing the various 
strict mode arguments semantics, so I did them.  There hasn't been a time where 
SpiderMonkey's had strict mode arguments semantics, without these optimizations.

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