Re: Throwing errors on mutating immutable bindings

2014-10-02 Thread David Herman
On Oct 2, 2014, at 8:31 AM, Andreas Rossberg rossb...@google.com wrote:

 On 2 October 2014 17:17, Allen Wirfs-Brock al...@wirfs-brock.com wrote:
 I believe that the module champions have always wanted static unresolvablse 
 reference rejection to be part of the module semantics.  But we've never had 
 actual specification for that semantics.
 
 Yes, I had always hoped for a stricter mode applied to modules. But
 I don't think that's something that's still possible at this (or a
 later) point. If it had been, then it would have made total sense for
 it to check against const assignments as well, along with a number of
 other things.

Yeah, I did wish for it, but we conceded a long time ago that it wasn't going 
to work out to have additional checks in modules. It's especially problematic 
because whether something is unbound or global is entirely dynamic (globals can 
be added and removed), scripts can be loaded at dynamically unpredictable times 
(so predicting the state of the global at the time code will be loaded is 
hard), in some modes HTML even throws element ids on the global and removes 
them again ...

 
 Personally, I think it would be fine for all of these sort of conditions to 
 be specified as runtime errors and leave it to linters to find them early 
 and JS implementations to optimize the runtime checks away.
 
 Outside modules, with the language being as it is, adding one minor
 new static check definitely does not seem worth the trouble and the
 cost risk.

Agreed. The consolation prize is that modules now make it possible for linters 
to do free variable analysis and errors without any user-configuration at all. 
(By contrast, JSHint has historically required programmers to annotate the set 
of globals they intend to use so that they aren't reported as free variable 
errors.)

Dave

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


Re: Toplevel 'let' binding can be left permanently uninitialized after an error

2014-09-30 Thread David Herman
On Sep 30, 2014, at 4:03 AM, Andreas Rossberg rossb...@google.com wrote:

 On 30 September 2014 12:52, Jason Orendorff jason.orendo...@gmail.com wrote:
 I just realized this has an unfortunate implication for REPLs. Suppose
 you make this typo:
 
js let x = Math.cso(a)// oops, TypeError, should be Math.cos
 
 Now x is irreparably hosed in your REPL. That seems bad.
 
 No surprise. One of the reasons why I always favoured a nested scopes
 model for multiple scripts...

We've had this debate a million times, but for anyone who's unfamiliar with the 
arguments: nested scopes makes recursive bindings across scripts impossible and 
is also hard to understand with things like asynchronous script execution order 
(such as script async). And it's totally different from the existing mental 
model of global code.

But since we're rehashing, this is an example of why *I've* always thought new 
binding forms should just go in the global object just like vars and functions 
do. JS's global scope is extremely complex and subtle, and you can't undo that 
complexity by adding additional layers. And the metal model, while unfortunate, 
already occupies programmers' brainspace -- adding an extra layer of scope for 
some binding forms makes the mental model more complex.

We basically have the following set of constraints that various people have 
tossed into the mixing bowl. It seems no matter which way you mix it, at least 
one of the constraints falls back out of the bowl:

1. Make `let` mean the same thing at top-level that it means locally.
2. Enable recursive bindings across multiple scripts.
3. Avoid the spec/design work of reifying new binding forms' reification in the 
global object.
4. Preserve the mental model of the global object.

Note that, as so often happens, we have one dimension of consistency (scoping 
semantics of `let` in local vs. global contexts) in tension with another 
dimension of consistency (globals going in the global object vs. globals going 
in a new scope layer).

I'm still convinced we made the wrong call, i.e., we chose the wrong dimension 
of consistency. The global scope was always a mess and we aren't going to make 
it less of a mess no matter what we do. We favored a philosophical consistency 
over a historical consistency, with predictable results. But it is what it is. 
We've talked before about exposing a reflection of the extra global layer, 
maybe via the Reflect API but certainly through the Realm API. We may need to 
add controls to that to allow undoing these kinds of annoyances Jason brings up.

I'm usually less concerned about REPLs, since they can decide for themselves 
what kind of context they want to execute in -- or even invent new non-standard 
non-terminals, frankly -- although in this case it's not quite clear what a let 
declaration *should* do in the REPL. Maybe developer consoles should actually 
treat `let` the way IMO we should've done for scripts. :)

Dave

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


Re: ES6 Loader proposed changes

2014-08-29 Thread David Herman
On Aug 28, 2014, at 10:10 AM, Ian Hickson i...@hixie.ch wrote:

 Here are the changes that would be needed to make the ES6 loader 
 infrastructure underpin the Web platform's loader infrastructure 
 (basically, placing the ES6 loader the management layer between the Web 
 platform APIs on top, and Service Workers underneath).
 ...
 If we can reuse this for the rest of the Web platform, it gives authors a 
 really uniform API for all loading operations.

The module loader isn't the right layer for the kinds of things you're trying 
to do. I understand you're trying to avoid having similar mechanisms at 
multiple layers of the platform, but repurposing the module loader system as a 
general purpose web resource loading system means conflating web resources and 
modules, which leads to a mixing of concerns exposed to the development model. 
Let me go into some more detail.

## What the `System` module loader is for

First, let's talk about what the module loader *is* for, and what the important 
requirements the browser's default `System` loader should address. In 
particular, I'm *not* saying that there should be *no* reflection of web assets 
to the JS module system.

### JS module name resolution

* *Basic name resolution for JS modules.* Refer to global and relative modules.

* *Module naming conventions that work across JS ecosystems.* Conventions that 
work on both client and server, particularly with npm.

Straw-examples:
```javascript
import _ from underscore; // global module
import spinner from ./spinner.js; // relative module
```

### HTML interop

* *Making JS modules available to HTML.* Allow HTML files to import from JS.

Straw-examples:
```html
!-- for now: --
script type=module
import $ from jquery;
import frobify from /scripts/frobify.js;
$(.frob).each((i, elt) = {
  frobify(elt);
});
/script

!-- eventually, but we can save this discussion for another day: --
module
import $ from jquery;
// etc.
/module
```

* *Reflecting web assets as JS modules.* Make web assets available to JS as 
modules that export a DOM element.

Straw-example:
```javascript
import icon from ./icon.png;
console.log(icon instanceof HTMLImageElement); // true
```


### Installing HTML/CSS components via module import

* *Applying CSS via import.* Mechanism for applying stylesheets by importing 
them from JS.

Straw-example:
```javascript
import ./main.css; // guarantees CSS is loaded and applied by the time this 
module executes
import $ from jquery;
$(#main).show();
```

* *Installing HTML imports via import.* Mechanism for installing HTML imports 
by importing them from JS.

Straw-example:
```javascript
import widget from ./widget.html;
console.log(widget instanceof DocumentFragment); // true
```


### Enriched response API

* *Cross-origin fetch.* Cross-origin requests should succeed by returning and 
opaque response, just as ServiceWorker does, that cannot be inspected but can 
be returned back into the pipeline for execution.

* *Streaming fetch.* It should be possible for a request to return a stream 
instead of a string, to allow asynchronous stream processing; this should use 
the API that results from the stream standardization process.


## What the `System` module loader is NOT for

* *Bundling requests.*

While it's attractive to use the loader for serving multiple assets in a single 
payload, this wants a more general solution for bundling arbitrary assets -- 
perhaps for performance (since despite the impending coolness of HTTP2, people 
will likely still use bundling as a successful optimization technique for a 
long time), but also for ergonomic deployment and inclusion. Jeni Tennison has 
done an excellent [proposal based on the link 
tag](https://github.com/w3ctag/packaging-on-the-web), and I've started 
exploring another approach based on URLs. Meanwhile people can experiment in 
userland with ServiceWorker-based techniques for bundling payloads.

* *Repurposing the module registry to reflect caching of arbitrary browser 
fetches.*

The registry is meant to record installation of things that are conceptually 
modules, not arbitrary network fetches of web assets. It's not the right place 
to store a cache of fetches. In particular, notice how above I said that it 
makes sense for modules to be able to import from, say, PNG files. In that 
case, the developer has explicitly requested that a web resource be reflected 
as a module, and it should be installed as a module. But using the registry for 
all web fetches means that non-JS is polluting the module registry with random 
modules reflecting arbitrary assets in the application.

* *Forcing resource management to be reflected as modules.*

The ServiceWorker API gives programmatic control over fetching of network 
payloads and a caching API. The module loader API gives programmatic control 
over fetching of modules and a caching API. What you're describing is using the 
latter for programmatic control over fetching and caching web assets, but that 

Re: Adding out-of-band dependencies for a module

2014-08-12 Thread David Herman
On Aug 11, 2014, at 5:06 PM, Ian Hickson i...@hixie.ch wrote:

 So I'm trying to figure out how to spec the HTML spec's Loader.

We should coordinate -- I've been actively working on this (not the spec per 
se, but the design) with people engaged in the JS modules work. The HTML 
default loader design has some requirements that touch on existing JS 
ecosystems and practices, so we need to be sure we don't spec it in isolation.

 One of the things that we're likely to add as part of this is a generic 
 dependency system.

You've mentioned this to me before, but I'm afraid I haven't seen any clear 
rationale written up anywhere, nor a good description of what this means. One 
thing it might mean is a resource-fetching dependency system, meaning that for 
any two elements A and B that require fetching a network resource, you can 
state that A depends on B, meaning that whenever A's resource is fetched, B's 
resource should be fetched too and the system should not consider A's fetch 
complete until B's fetch is complete. If that's what you mean, I'm skeptical 
that an attribute is the right level for programmers to express this kind of 
resource grouping. In particular, HTTP2 and the TAG's work on package 
management are better approaches to grouping network resources than scattering 
dependency attributes across a DOM tree.

Dave

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


Re: Understanding the 'normalize' Loader hook

2014-08-12 Thread David Herman
On Aug 12, 2014, at 2:05 PM, Ian Hickson i...@hixie.ch wrote:

 Assume my script is http://example.com/test.js, and assume that there is 
 no extra information (nobody has registered any module names or anything 
 like that). If I do:
 
   import a;
   import ./a;
   import /a;
   import //example.com/a;
   import http://example.com/a;
 
 ...am I supposed to end up with the same normalized name for all five?
 
 How many entries in [[Modules]] should this result in?
 
 (I understand that the answer depends on the default loader; what I'm 
 asking is, what should the default loader's behaviour be.)

This is part of the design work we're actively working on. I'd ask you to hold 
off until we have some more information for you. I'll keep you posted -- we 
should have some more details for you soon.

Dave

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


Re: Understanding the 'normalize' Loader hook

2014-08-12 Thread David Herman
On Aug 12, 2014, at 2:46 PM, Ian Hickson i...@hixie.ch wrote:

 On Tue, 12 Aug 2014, David Herman wrote:
 
 This is part of the design work we're actively working on. I'd ask you 
 to hold off until we have some more information for you. I'll keep you 
 posted -- we should have some more details for you soon.
 
 Where is the design work happening? I'd love to be part of it, since this 
 directly impacts the rest of the work I'm doing on the HTML spec right now.

Right now what I've been doing is working with various stakeholders gathering 
requirements and constraints and beginning to sketch out what the solution 
space looks like. This includes people working on userland loader 
implementations, people in the Node community and browser development 
communities, people working on the JS modules design and spec, and people 
working on WC and HTML imports. Most of that has been in one-off discussions 
e.g. at the last TC39 face-to-face. I'll be filling out

https://github.com/dherman/web-modules/tree/master/browser-loader

with our progress. I don't want to block you and I'm happy to include you in 
these discussions, but there are enough stakeholders that it's not going to 
work to make everyone come to #whatwg at this stage.

Dave

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


ModuleImport

2014-06-19 Thread David Herman
Thanks to everyone for working through the issues around ModuleImport. I know 
it's been frustrating, but the discussions have really helped clarify the key 
constraints.

## Constraints

First, let me restate the most important arguments. In favor of removal:

* **The syntactic distinction between ModuleImport and default import is 
vague.**

We've consistently seen confusion between the semantics of ModuleImport and 
default export. While certainly some of the confusion might be chalked up to 
misinformation and lack of documentation, we've seen people be confused by this 
even when correctly explained the semantics. The problem with the syntax is 
that the only visual distinction is the initial keyword (`module` vs `import`), 
and it's not clear from that keyword which concept you're talking about. (Once 
you've internalized the structure of module instance objects, you get a hint 
from the `module` keyword, but that doesn't help people who are just learning 
the system, particularly if they're already familiar with other JS module 
systems.)

Against removal:

* **Without ModuleImport, authors of multi-export modules would be pressured to 
circumvent the named exports functionality.**

Without ModuleImport, clients of multi-export modules have two options. Either 
they use named import:
```js
import { readFile, writeFile } from fs;
```
or if they want to explicitly namespace those functions, they have to use the 
dynamic API:
```js
import fs; // state the dependency
var fs = this.get(fs);
```
That's inconvenient, confusing, and makes you feel like you're stepping outside 
the normal usage patterns intended for the system. Since this is a choice 
forced on the clients of a module, the module author will feel pressure to 
circumvent the named export feature altogether and instead export a default 
object with all the properties. This is bad -- it creates pressure for people 
to abandon part of the module system.

## Conclusion

Here's the conclusion I've come to based on all of the above.

* **We need a form like ModuleImport.**

As many have said, clients of named-export modules need the freedom to choose 
whether to explicitly namespace those imports, and they need a syntax that 
doesn't feel like they've stepped outside the normal system.

* **The current syntax of ModuleImport is wrong.**

The confusion reported in developer feedback is real, and it's important.

* **The syntax should still favor default import.**

ES6 favors the single/default export style, and gives the sweetest syntax to 
importing the default. Importing named exports can and even should be slightly 
less concise.

* **A better ModuleImport syntax is possible, and we should settle it soon.**

I'll propose a better ModuleImport syntax below. Syntax being syntax, everyone 
will of course unsheathe their bikeshed paintbrush. That's OK. The champions 
will keep it from going on unbounded and help settle the debate, and we'll make 
sure to capture the conclusion in the next TC39 meeting.

I do acknowledge the concerns about reopening topics for debate and delay. But 
given the usability feedback, I think this case is worth fixing. We should 
resolve it for ES6, perhaps in part because it's less editorial work to change 
the ModuleImport production than to defer it, but more because I don't want to 
delay the resolution so that implementations can ship the better syntax. But 
keep in mind it doesn't matter what spec it lands in as long as implementations 
are shipping it. We're still in the early days of transpiler implementations, 
and there are no native implementations of modules yet. So there's time, as 
long as we don't let the bikeshed go on forever. So let's get to it!

## Proposal

OK, so we're talking about a better syntax for importing a module and binding 
its named exports to a variable (as distinct from importing a module and 
binding its default export to a variable). Here's my proposal:
```js
import * as fs from fs; // importing the named exports as an object
import Dict from dict;  // importing a default export, same as ever
```

Why is this better? Because it dovetails with the named export syntax, **which 
makes it clear that it's binding `fs` to the named exports.** It saves the 
reader from having to know that the module instance object is not the same 
thing as the default export.

So there you have it... Feedback welcome, and as always we'll collect it all, 
weigh it, and try to shepherd consensus.

Oh, and just to put parameters on the discussion:

* **I'm not proposing additional new import forms.**

If this syntax is future-compatible with other possible syntactic forms, that's 
great, but that's not what we're discussing.

* **I'm not interested in discussing changes to the rest of the module syntax.**

This isn't the time or place to redesign the whole system.

* **The `this` binding in modules is a separate topic.**

The `this` binding in modules can be discussed independently of this topic.

tl;dr we're 

Re: ModuleImport

2014-06-19 Thread David Herman
On Jun 19, 2014, at 2:03 AM, Axel Rauschmayer a...@rauschma.de wrote:

 Does the proposed syntax clash with `export * FromClause` (which, I’m 
 assuming, re-exports everything, not just the named exports)?

No inconsistency; it imports everything. Exactly the same semantics as always, 
just a change in surface syntax. Remember that the module instance object 
contains all named exports, but the default export is simply an export with the 
name `default`.

Dave

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


Re: ModuleImport

2014-06-19 Thread David Herman
On Jun 19, 2014, at 3:31 AM, Michał Gołębiowski m.go...@gmail.com wrote:

 Thanks, Dave, for bringing that up, it shows you're open for feedback. That 
 said (bikeshed begins),

lol :)

 what's wrong with:
 ```js
 import fs as fs;
 ```

Indeed we've talked about that one before. Some objected to the inconsistency 
of having the binding appear at the end and not having the module name at the 
end (all other import forms have the binding on the left and the module name at 
the end). But more importantly, this doesn't help with the problem of visually 
disambiguating from importing the default export. To put it another way, the 
`*` is critical in the `* as _` syntax, because it makes it explicit that we're 
talking about the named exports.

 ? I feel that a lot of effort went in ES6 into reducing boilerplate via e.g. 
 arrow functions, classes etc. but if you start with Node's require, this adds 
 clutter. Compare these 3 forms of importing all the module lodash bindings 
 to an object _:
 ```js
 var _ = require(lodash); // Node
 import * as _ from lodash; // Dave's syntax
 import lodash as _;
 ```

My feeling is that the clutter is small, and it's acceptable to have it be 
slightly less minimal than default export since that is the case we are 
favoring. This isn't so cluttered as to be downright *punishing* multi-export 
utility modules (it's literally only two characters longer than your Node code, 
albeit admittedly a little chattier), but it's good that default import is the 
winner.

Dave

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


Re: @@new

2014-06-18 Thread David Herman
Your proposal is appealing but I haven't convinced myself it works. There are a 
couple bits I haven't quite grokked.

 The special `constructor` method in ClassDeclaration/ClassExpression syntax
 would desugar to a static @@new method. This class:
 
class Point {
constructor(x = 0, y = 0) {
this.x = x;
this.y = y;
}
}
 
 would amount to this:
 
class Point {
static [Symbol.new](x = 0, y = 0) {
var obj = super[Symbol.new]();
obj.x = x;
obj.y = y;
return obj;
}
}

You're inlining the method body into the @@new body, but I want to make sure I 
understand what the specification of the Point function itself would be. You've 
said Point !== Point[@@new] but calling Point(...args) should behave the same 
as new Point(...args). So then would the specification of the Point function's 
behavior just be to delegate to Point[@@new](...args)?

 The super Arguments call syntax in the ES6 drafts would be constrained to
 appear only at the top of a constructor, as in Java:

This part is what I'm the most unclear about. What invariant are you trying to 
maintain? It seems like you're using this to attempt to guarantee that all 
superclasses have had the chance to initialize their internal fields before 
user code starts running, so that built-in classes can have consistent internal 
representations and not have to worry about guarding against reading from 
uninitialized internal slots. But this is a tricky invariant to guarantee. 
First of all I think you'd have to put syntactic restrictions in place to 
disallow referring to `this` in the super call, to avoid e.g.:

  class Sneaky extends Date {
constructor(x) {
  super((console.log(this.valueOf()), x));
}
  }

But that's not enough, because you also have to worry about the superclass 
constructors calling overloaded methods:

  class Dupe extends Date {
constructor(x) {
  super(x);
  initDupe();
}
initDupe() { ... }
  }

  class Sneaky extends Dupe {
constructor(x) { super(x); }
initDupe() {
  console.log(this.valueOf());
  super.initDupe();
}
  }

(These are common pitfalls in languages that try to provide hard guarantees 
about field initialization. They come up, for example, in typed OO languages 
that try to provide guaranteed non-nullable fields.)

But maybe I'm misunderstanding what invariant you're aiming at?

 *   Base class constructors are always called.

Are you saying you would not only restrict the super call to the top, but 
require one to always be there? Or would an absence of a super call imply an 
implicit `super()`?

 *   These productions would be dropped from the ES6 grammar:
 
MemberExpression : new super Arguments
NewExpression : new super

Clearly with your design `super[Symbol.new](...args)` is equivalent to `new 
super`. Is it also emulate-able in the @@create semantics also? If so it seems 
like the question of whether to keep or drop the `new super` syntax is 100% 
orthogonal to your proposal.

Dave

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


exposing system time zone

2014-06-17 Thread David Herman
This was brought up on specifiction:

http://discourse.specifiction.org/t/navigator-timezone/152

Does anyone know why it was left out of the first version of the Intl API? Just 
for lack of time? Is it planned for the next edition? Are there tricky issues 
around standardizing IANA time zones, or around incompatibilities between 
different OSes?

Interesting questions in that thread about what to do about time zone changes. 
An event for time zone changes seems important, but we don't currently have any 
precedent for standard library events in ECMAScript. Maybe that remains the 
purview of web APIs. But if we do expose the TZ via a standard API, it should 
have some way of dynamically querying the current TZ rather than just fixing 
the time zone at some random point in time.

Dave

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


Re: exposing system time zone

2014-06-17 Thread David Herman
On Jun 17, 2014, at 5:31 PM, Domenic Denicola dome...@domenicdenicola.com 
wrote:

 Interesting questions in that thread about what to do about time zone 
 changes. An event for time zone changes seems important, but we don't 
 currently have any precedent for standard library events in ECMAScript.
 
 Object.observe change records? A synthetic change event seems perfect for 
 this use case.

I knew someone would suggest that. :)

Personally, I think that's pretty gross: it's encoding a real-world event (e.g. 
I moved into a different time zone) as a reflective object mutation event, 
rather than just building an API at a more intuitive level of abstraction. But 
I suppose if it works without having to actually standardize anything, then it 
just works.

Dave

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


Re: Iterators, generators, finally, and scarce resources (Was: April 10 2014 Meeting Notes)

2014-04-29 Thread David Herman
On Apr 29, 2014, at 12:40 AM, Andy Wingo wi...@igalia.com wrote:

 I'm a bit grumpy that this is being brought up again, and
 this late, and in multiple forums, but as it seems that people want to
 talk about it again, that talking about it again is the thing to do...

Sorry about that. :( But the fact is Jafar joined TC39 very late and his 
technical points have merit, so we do have to grapple with them. (As for 
multiple forums, I wish I had a solution.)

 If I may summarize Jafar's argument, it's that the iterator in a for-of
 may hold a scarce resource, like a file descriptor, and because of that,
 for-of should be able to release this scarce resource on an early exit
 via break.  The provisional consensus elaborates a method to do this.
 
 Is this a fair summary?

I don't quite agree with that summary. These are IMO the most important points:

- Iterators might include on cleanup logic, although this is admittedly rare 
in synchronous code.

- Nevertheless, generators are the common implementation strategy for 
iterators, and try/finally is a part of the language, making on cleanup logic 
more likely to arise. While we can't ever guarantee that code won't run a 
first-class iterator object to its completion (just like you can't guarantee 
that a try block won't iloop), it's a bad smell if code that creates an 
iterator in a for-of loop head, loops over it, and *never even touches the 
iterator directly* doesn't shut down the iterator.

- Iterators are intended to be short-lived (in particular, long-lived iterators 
over mutable data sources are invalidation hazards). So the common consumer of 
iterators, for-of, should properly dispose of them.

- The uncommon case of using an iterator partially and in several loops can be 
easily implemented with combinators (or while loops), but we should be safe by 
default.

- The problems of on cleanup logic will be greatly exacerbated with future 
asynchronous iteration features, which are IMO an extremely high priority for 
the future. The overwhelming majority of JS programs that operate on sequences 
of data are doing so asynchronously. The moment we start going down the road of 
designing asynchronous iteration features (such as `for (await ... of ...)`), 
which in fact Jafar and I have been starting work on, the try/finally hazards 
will show up much more often. If we don't do proper disposal of synchronous 
iterators, we'll create an asymmetry between synchronous and asynchronous 
iteration, which would not only be a nasty wart but also a refactoring hazard.

 Indeed I expect that in
 practice most iterators in an ES6 program will be map, set, and array
 iterators, which in practice will not be implemented with generators.

I strongly disagree with this. Generators will by far be the most convenient 
and common way to implement iterators, regardless of their data source.

 Incidentally I think that if TC39 decided to re-add this method, it
 should be called close() instead, because it doesn't make sense to
 return from a non-generator iterator.

I thought so at first too, until I remembered that iterators have a return 
value. So I still think return is the right name.

 == Calling return() on iterators is rarely appropriate

You're arguing rarely necessary, not rarely appropriate, which is a weaker 
claim. But I dispute that too because of asynchronous iteration, as I explained 
above.

 However in this case it is possible to arrange to close the iterator,
 with a different interface:

This is a *dramatic* weakening of the power of iterators, in that you force 
*all* iteration abstractions to expose their external resources to consumers. 
Again, it may not seem like a big deal now but it'll be completely unacceptable 
for the asynchronous case.

 The other case is when you have an iterator consumer which is decoupled
 from the code that created the iterator, as in:
 
  function (iterable) {
...
for (var x of iterable) {
  if foo(x) break;
}
...
  }
 
 But it is precisely in this case when you would *not* want to close the
 iterator, because you don't know its lifetime.

As I said above, we should not optimize the design for this case. It's easy 
enough to create combinators for it:

  function (iterable) {
...
for (var x of keepalive(iterable)) {
  if foo(x) break;
}
...
  }

But this will not be the common case. The majority of the time when you're 
working with sequences you use the data you need and then you're done with it.

 == return() in generators is semantically weird

It's not as weird as you make it out to be. Return is not much different from 
throw, first of all. Note also that ES7 do-expressions allow expressions to 
return.

 Also, the insistence on a return() that doesn't run catch blocks seems
 to me to be ill-placed.  I think it's telling that the counter-examples
 are from Python, which has a different semantic model, as it has
 finalization.  Implementing abstractions over scarce resources in JS 

Re: Destructuring and evaluation order

2014-04-29 Thread David Herman
On Apr 25, 2014, at 10:42 AM, Allen Wirfs-Brock al...@wirfs-brock.com wrote:

 Nope, it's always been designed this, going back to the original wiki 
 strawman 
 http://wiki.ecmascript.org/doku.php?id=harmony:destructuring#semantics and I 
 assume the original FF implementation.
 
 It has also been something that we has been discussed here and in TC39 
 multiple times.  If we wan to revisit this decision we really need to dredge 
 up all of those previous discussions to see if there is new data that would 
 cause us to change this decision. 
 
 Basically for destructing assignment, each property element can be an 
 arbitrary assignment expression and all of their Reference values would have 
 to be saved to get left to right order.

FWIW (not much probably) I've always agreed with what Andreas and Ollie are 
saying here, but I don't have the time or energy to do the dredging. :)

Dave

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


Re: Iterators, generators, finally, and scarce resources (Was: April 10 2014 Meeting Notes)

2014-04-29 Thread David Herman
On Apr 29, 2014, at 12:17 PM, Domenic Denicola dome...@domenicdenicola.com 
wrote:

 Anyway, regardless of the specifics of my `using` proposal, I hope that 
 highlighting the iterability vs. disposability aspects of this conversation 
 was helpful to people.

I do think it's helpful for understanding the space, thanks.

But here's why I don't think it ultimately helps: we are going to need 
combinators for iterators, and they are going to have to make the same 
decision. We aren't going to have e.g. map and mapDispose. I still contend that 
the common case is that iterators are short-lived, and the language should 
safely ensure they are disposed of. So the combinators should ensure that their 
underlying iterator is disposed of, and for-of should behave consistently with 
the combinators.

Dave

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


Re: April 10 2014 Meeting Notes

2014-04-29 Thread David Herman
On Apr 25, 2014, at 9:10 AM, Allen Wirfs-Brock al...@wirfs-brock.com wrote:

 People will write code like this if we allow it.  But we don't have to allow. 
  We can preserve the semantics of try-finally by simply making the occurrence 
 of the 'yield' operator syntactically illegal within the try block of a 
 try-finally. 
 
 We could do this.  The parameterized grammar notation we now use in the ES6 
 spec. makes it fairly easy to specify that you can't write code like the 
 above.  
 
 Should we do it?  I'm not sure.  I still think that @@return is a reasonable 
 but imperfect alternative that allows generator authors to continue to use 
 what many think is a useful feature.  Outlawing 'yield' in a try-finally is a 
 almost perfect solution to the semantic impedance mismatch between 
 try-finally and generators. But we also loose some expressiveness.

Promised you a reply to this one, sorry -- I'm not comfortable with this 
restriction. It violates my Schemer's intuition [1]. In particular it creates a 
number of refactoring hazards: (1) add some try/finally code around code to 
deal with something other than the yield it contains; (2) refactor some 
try/finally code outside of a generator into a generator.

Here's my perspective:

- Iterators should generally be short-lived.
- We should optimize the language design around ensuring that they will 
generally be exhausted.
- In most use cases users won't even touch an iterator directly; it'll just be 
created and passed directly into the for-of loop (or a combinator, which itself 
will often be implemented with a generator function that consumes the wrapped 
iterator in a for-of loop).
- The fact that iterators are first-class objects means it's *possible* to 
prevent an iterator from being terminated, but termination is never an absolute 
guarantee in Turing-complete languages to begin with.

So the design I favor is:

- Generators always have a .return() method.
- All three of .next, .throw, and .return should take an optional argument.
- All three of .next, .throw, and .return should return an iteration record ({ 
value: any, done: boolean }).
- The semantics of for-of (as well as any combinators we specify post-ES6) 
should call .return() on the underlying iterator iff there's an abrupt 
completion. If the iterator terminates itself the loop should not force a 
.return() -- this isn't just a performance compromise, it avoids calling 
.return() on a closed generator.
- If the implicit .return() of a for-of loop produces done: false, that 
indicates the iterator refused to be terminated, and the for-of loop should 
throw an exception. (This exception should throw from outside the loop, so no 
catch blocks inside the loop should catch it.)

Dave

[1] Programming languages should be designed not by piling feature on top of 
feature, but by removing the weaknesses and restrictions that make additional 
features appear necessary.
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: module exports

2014-03-14 Thread David Herman
On Mar 14, 2014, at 9:27 AM, John Barton johnjbar...@google.com wrote:

 I've used es6 modules for several months now and I'm curious to know when I 
 would want to leverage mutable bindings. 

So cycles work!

// model.js
import View from view;

export default class Model {
  ...
}

// view.js
import Model from model;

export default class View {
  ...
}

This kind of thing just falls flat on its face in Node and AMD.

 I guess I need to begin to imagine that variables bound to imports are really 
 a kind of property name of s secret object:

If that gets you there, that's cool. But it's a bit sloppy. It blurs userland 
data structures with internal language implementation data structures.

Here's how I think about it. A variable in JS denotes a binding, which is 
basically an association with a mutable location in memory. In particular it 
doesn't denote a value. The binding has a value at any given time.

When you export from a module, you're exporting bindings, rather than values. 
This means you can refactor between

module m from foo;
...
m.bar

and

import { bar } from foo;
...
bar

and they're fully equivalent. But it also means that when you have modules that 
mutate their exports during initialization, you don't run into as many subtle 
order-of-initialization issues as you do with AMD and Node, because importing 
something syntactically early doesn't mean you accidentally snapshot its 
pre-initialized state.

(Also, keep in mind that the vast majority of module exports are set once and 
never changed, in which case this semantics *only* fixes bugs.)

Dave

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


Re: module exports

2014-03-14 Thread David Herman
On Mar 14, 2014, at 9:37 AM, Andrea Giammarchi andrea.giammar...@gmail.com 
wrote:

 I like that more I read about this, more the `with` statement comes into my 
 mind ...

There's nothing like this in JS today, so if you're only looking for precedent 
there, you're only going to be able to come up with weak analogies. The 
differences between aliasing bindings from a module with a fixed, declarative 
set of bindings, and aliasing bindings from an arbitrary user-specified and 
dynamically modifiable object are massive.

And see my reply to JJB to get an understanding of why this is such an 
important semantics. tl;dr non-busted cycles.

Dave

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


Re: module exports

2014-03-14 Thread David Herman
On Mar 14, 2014, at 10:50 AM, Russell Leggett russell.legg...@gmail.com wrote:

 I completely agree with this. It looks like a modifier.

This is a good point, and folks working on the Square transpiler noticed this, 
too. I think there's a more surgical fix, though (and I'm not entertaining 
major syntax redesign at this point). In fact it's one with precedent in JS. In 
statements, we allow both expressions and declarations, which is a syntactic 
overlap. But visually people expect something that looks like a declaration in 
that context to be a declaration, so the lookahead restriction breaks the tie 
in favor of declarations.

I think we're seeing the exact same phenomenon with `export default` -- the 
modifiers make it look more like a declaration context. So I think we should 
consider doing the same thing as we do for ExpressionStatement:

ExportDeclaration :
...
export default FunctionDeclaration ;
export default ClassDeclaration ;
export default [lookahead !in { function, class }] AssignmentExpression 
;

This actually results in no net change to the language syntax, but it allows us 
to change the scoping rules so that function and class declarations scope to 
the entire module:

// function example
export default function foo() { ... }
...
foo();

// class example
export default class Foo { ... }
...
let x = new Foo(...);

// expression example
export default { x: 1, y: 2, z: 3 };

I argue that not only does this avoid violating surprise, it's not any more of 
a special-casing logic than we already have with ExpressionStatement, because 
it's the same phenomenon: a context that allows a formally ambiguous union of 
two productions, but whose context strongly suggests the declaration 
interpretation over the expression interpretation in the overlapping cases.

Dave

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


Re: Initializer expression on for-in syntax subject

2014-03-14 Thread David Herman
Sad panda. At least we can disable it in strict mode, right?

And who knows, maybe some day, some day...

Dave, dreaming of ES24

On Mar 13, 2014, at 4:59 PM, Oliver Hunt oli...@apple.com wrote:

 JSC has been trying to kill off the initialiser expression in the for(in) 
 statement, but we've encountered a bunch of reasonably significant content 
 that breaks with it disallowed (a particularly prominent one currently is 
 http://battlelog.battlefield.com/bf4/), so we will be bringing back support 
 for
 
 for (var Identifier = Expression in Expression)
 
 --Oliver
 ___
 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: Detecting a Module object

2014-02-21 Thread David Herman
I think it should be Module.isModule.

Dave

On Feb 21, 2014, at 10:57 AM, Allen Wirfs-Brock al...@wirfs-brock.com wrote:

 it's not going to be instanceof for various technical reasons.
 
 I suspect, we can have a isModule predicate function somewhere.  Perhaps, 
 Reflect.isModule or Reflect.Loader.isModule...
 
 Allen
 
 
 On Feb 21, 2014, at 3:53 AM, Guy Bedford wrote:
 
 Being able to do `m instanceof Module` is certainly a lot nicer here though.
 
 Just to return to the consideration of modules as classes, I still don't 
 understand what the major issue is with having a module as a class without 
 any prototype methods.
 
 
 On 21 February 2014 00:07, Guy Bedford guybedf...@gmail.com wrote:
 Thanks John for explaining. As for the usefulness of this path as I say it 
 is yet to be determined.
 
 Specifically the ability to detect a module instance is needed to allow ES6 
 loaders to load AMD that was transpiled from ES6 into AMD.
 
 It may be a little bit of an obscure use case, the exact details of the use 
 case are described in this gist - 
 https://gist.github.com/guybedford/5622c9ed5c9ad4bc0417.
 
 The key point being raised here is that there is a scenario in which 
 detecting a module instance is useful.
 
 
 On 20 February 2014 23:45, John Barton johnjbar...@google.com wrote:
 
 
 
 On Thu, Feb 20, 2014 at 1:01 PM, Allen Wirfs-Brock al...@wirfs-brock.com 
 wrote:
 
 On Feb 20, 2014, at 12:53 PM, Guy Bedford wrote:
 
  Thanks, if there is some way to detect this it may well be useful.
 
  The use case I came across it was trying to allow ES6 modules to be 
  transpiled into AMD for use in an ES6 loader. I'm still not sure how 
  necessary the use case is, but it definitely would need this functionality 
  work.
 
 The Es6 module loader design has specific hooks to support importing from 
 foreign module systems.  However, I'll leave it to Dave or Sam to explain 
 how to use them...
 
 Guy is trying to support an important path for JS developers to get to ES6 
 and adopt ES module loading: allow developers to mix ES6 and AMD modules.  
 He already supports loading AMD via ES6-loader.  Now he wants to allow that 
 AMD code to depend upon ES6 modules.  This allows AMD teams to transition 
 smoothly to ES6.  He needs something like:
 define(['a', 'b'], function(a, b) {
   if (!(a instanceof Module)) a = { default: a } 
   if (!(b instanceof Module)) b = { default: b }
 
 so his generated AMD code can accept ES6 modules.
 
 HTH,
 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: Detecting a Module object

2014-02-21 Thread David Herman
OK, we can discuss and report back. We'll definitely want to take into account 
Guy's use case about being able to recognize module instance objects as such.

Dave

On Feb 21, 2014, at 12:53 PM, Allen Wirfs-Brock al...@wirfs-brock.com wrote:

 
 On Feb 21, 2014, at 12:08 PM, David Herman wrote:
 
 I think it should be Module.isModule.
 
 I don't think we actually need something named Module, but that's a separate 
 conversation I have in the queue to have with you. 
 
 But food for thought: for module loader reflection purposes, it would be 
 better for use a mirror-like object rather than the actual magic module 
 objects.
 
 allen
 
 
 
 
 
 
 Dave
 
 On Feb 21, 2014, at 10:57 AM, Allen Wirfs-Brock al...@wirfs-brock.com 
 wrote:
 
 it's not going to be instanceof for various technical reasons.
 
 I suspect, we can have a isModule predicate function somewhere.  Perhaps, 
 Reflect.isModule or Reflect.Loader.isModule...
 
 Allen
 
 
 On Feb 21, 2014, at 3:53 AM, Guy Bedford wrote:
 
 Being able to do `m instanceof Module` is certainly a lot nicer here 
 though.
 
 Just to return to the consideration of modules as classes, I still don't 
 understand what the major issue is with having a module as a class without 
 any prototype methods.
 
 
 On 21 February 2014 00:07, Guy Bedford guybedf...@gmail.com wrote:
 Thanks John for explaining. As for the usefulness of this path as I say it 
 is yet to be determined.
 
 Specifically the ability to detect a module instance is needed to allow 
 ES6 loaders to load AMD that was transpiled from ES6 into AMD.
 
 It may be a little bit of an obscure use case, the exact details of the 
 use case are described in this gist - 
 https://gist.github.com/guybedford/5622c9ed5c9ad4bc0417.
 
 The key point being raised here is that there is a scenario in which 
 detecting a module instance is useful.
 
 
 On 20 February 2014 23:45, John Barton johnjbar...@google.com wrote:
 
 
 
 On Thu, Feb 20, 2014 at 1:01 PM, Allen Wirfs-Brock al...@wirfs-brock.com 
 wrote:
 
 On Feb 20, 2014, at 12:53 PM, Guy Bedford wrote:
 
 Thanks, if there is some way to detect this it may well be useful.
 
 The use case I came across it was trying to allow ES6 modules to be 
 transpiled into AMD for use in an ES6 loader. I'm still not sure how 
 necessary the use case is, but it definitely would need this 
 functionality work.
 
 The Es6 module loader design has specific hooks to support importing from 
 foreign module systems.  However, I'll leave it to Dave or Sam to explain 
 how to use them...
 
 Guy is trying to support an important path for JS developers to get to ES6 
 and adopt ES module loading: allow developers to mix ES6 and AMD modules.  
 He already supports loading AMD via ES6-loader.  Now he wants to allow 
 that AMD code to depend upon ES6 modules.  This allows AMD teams to 
 transition smoothly to ES6.  He needs something like:
 define(['a', 'b'], function(a, b) {
 if (!(a instanceof Module)) a = { default: a } 
 if (!(b instanceof Module)) b = { default: b }
 
 so his generated AMD code can accept ES6 modules.
 
 HTH,
 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: System.import FTW

2014-02-14 Thread David Herman
On Feb 14, 2014, at 12:09 PM, John Barton johnjbar...@google.com wrote:

 (There is no spec on System, just rumors that it will be a predefined, 
 global instance of Loader).

Rumors is a bit much. :) The notes do show the discussion but the resolution 
for some reason didn't get recorded. IIRC there was agreement that Reflect and 
System will both be globals (this has also been the general understanding for a 
long time, so it's nothing new).

https://github.com/rwaldron/tc39-notes/blob/9ac398908394f9e2f8a1ac9b1e0c83952cd2f2fa/es6/2014-01/jan-28.md#spec-status-update

Dave

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


Re: The case for modular Loader.

2014-02-10 Thread David Herman
On Feb 7, 2014, at 8:06 AM, John Barton johnjbar...@google.com wrote:

 The first goal listed for ecmascript modules:
   • Obviate need for globals
 (http://wiki.ecmascript.org/doku.php?id=harmony:modules).
 Ironically, the current proposal for module loading includes a global 
 System and possibly Loader.

Sorry the goal was unclear. It didn't mean we should never add globals to JS, 
it meant we should make it so programmers don't need to use globals as a 
mechanism for code sharing. That doesn't mean there's never any point to adding 
globals. Even in languages that are born with a module system from day one, 
they tend to have a standard prelude of globals that are common enough that it 
would be anti-usable to force programmers to explicit import them.

 Worse, it seems like the global System is explicitly expected to be mutated.

This is a red herring; a registry is inherently a shared mutable table, whether 
you make it accessible via a global variable or via a (globally accessible) 
module.

 Just in case the not-global is goal is controversial, consider the following 
 code snippets:
 
 1. Using Globals:
System.import('./myGreatModule');
 2. Using Modules:
import System from './MyCustomLoader';
System.import('./myGreatModule');

This isn't a viable option. The module system needs to be accessible from 
script code (e.g. HTML element attributes), which can't syntactically import.

Dave

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


Re: The case for modular Loader.

2014-02-10 Thread David Herman
On Feb 10, 2014, at 8:55 AM, John Barton johnjbar...@google.com wrote:

 Indeed, however, this herring is only red on one fin: the mutability of 
 System is not limited to the registry and in fact every aspect of the System 
 is mutable. As far as I can tell, a mutation to say normalize or locate is 
 entirely unpredictable without runtime tracing.  Unless I am wrong about 
 this, we should not ignore this herring just because of a small botch of red.

OK, I see what you're saying. I'm just not as concerned because configuring the 
loader is not something everyone should be doing. It's effectively 
application-wide configuration.

 Did we give up on script type='module'?

Didn't give up, no (modulo OT details). But there will always be contexts like 
button onclick=... that are defined to be a script, not a module.

Dave

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


Re: Reason why generators do not have references to themselves?

2014-01-27 Thread David Herman
I'd like to suggest another sense in which you may have gone down a bad path: 
you're assuming that await is paired with function*, but it could instead be 
(like C#) paired with its own async-function syntactic form. Let's say for the 
sake of argument that async is just a keyword that takes a function form:

  async function sizeOfZombocom() {
let all = await download(http://zombo.com;);
return all.length;
  }

Imagine we were designing this with a macro system like sweet.js. The 
temptation is for `async` to unhygienically bind `await` to a macro within its 
body, but Racket has developed a cleaner mechanism for thinking about paired 
forms like this, which they call syntax parameters (kind of a confusingly 
generic sounding name) [1] [2]. The basic idea is that you bind both `async` 
and `await` at the same time, so `await` is always bound, even outside of an 
async function, but the two collaborate so that `async` informs `await` of its 
syntactic context. So it would look something like this:

Example 1:

  import { async, await } from async;

  await 1; // syntax error: await used outside of async function

Example 2:

  import { async, await } from async;

  function* sizeOfZombocom() {
let all = await download(http://zombo.com;); // syntax error: await used 
outside of async function
return all.length;
  }

Example 3:

  import { async, await } from async;

  async function sizeOfZombocom() {
let all = await download(http://zombo.com;); // great success
return all.length;
  }

This makes your abstraction airtight: `await` is a concept that belongs to 
`async` functions, not generator functions; generator functions are merely the 
internal implementation technique.

Currently, sweet.js doesn't have syntax parameters, but it'd be a good 
experiment to add them them and try implementing async/await as I've sketched 
here.

Dave

[1] http://www.greghendershott.com/fear-of-macros/Syntax_parameters.html
[2] http://docs.racket-lang.org/reference/stxparam.html

On Jan 23, 2014, at 2:14 PM, Bradley Meck bradley.m...@gmail.com wrote:

 I was playing around with generators / looking at await for promises and 
 notices a very difficult thing revolving around generators not having a 
 reference to themselves.
 
 See: 
 
 https://gist.github.com/bmeck/72a0f4f448f20cf00f8c
 
 I have to end up wrapping the generator function to get a reference to the 
 generator for passing to nested functions.
 
 Is there a reason the execution context is not a generator / there is no 
 reference back to the generator during [[call]]?
 ___
 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: detecting JS language mode for tools

2014-01-27 Thread David Herman
On Jan 27, 2014, at 10:58 AM, David Bruant bruan...@gmail.com wrote:

 Agreed. Note that I didn't suggest to stop writing inline scripts and 
 proposed an alternative to script@module that can work today.
 Granted, it's somewhat hacky, but I think it can work during the period 
 during which there'll be both ES6 and non-ES6 browsers to support.
 
 I was sloppy in my phrasing. What we don't need is the current inline script 
 execute right now and block everything else semantics, specifically for 
 modules which order of execution shouldn't block things.

OK, sorry I jumped in the middle of things missing some context. In fact, I 
think what we've been planning on proposing is not too far -- I think -- from 
what you're talking about. The plan is *not* a module attribute (that was a 
think-o on my part, and maybe some misinformation that crept into this 
discussion earlier?) but type=module. That way on old browsers it's ignored 
and you can add shims to load it. Shims can be made future-proof via feature 
detection, so type=module can obtain new semantics.

Moreover, the type=module should not actually mean execute right now and 
block everything else, but rather executing asynchronously once all my module 
dependencies are loaded and linked.

Does that make more sense? I realize part of the issue here is there isn't a 
concrete plan or proposal that's been spelled out, it's just been informal 
discussions. That's on us, the modules champions, to put forward a proposal for 
web (i.e. non-Ecma) standardization ASAP. Yehuda's going to be in town for TC39 
this week, so he and I will sit down and do an informal write-up so people can 
see the plan more clearly, while we work on a fuller proposal for 
standardization.

Dave

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


Re: detecting JS language mode for tools

2014-01-27 Thread David Herman
On Jan 27, 2014, at 2:07 AM, David Bruant bruan...@gmail.com wrote:

 Indeed. I'm wondering why we need inline script for modules.

Because people write inline scripts all the time. It's unacceptably 
inconvenient not to be able to bootstrap your app with inline code. It also 
allows you to control for when the scripts resource is there, in particular to 
be sure that necessary bootstrapping/kernel code has loaded before you need to 
do some wiring up of your app.

But it's not even worth overthinking. It's so obviously, obscenely anti-usable 
not to be able to write

script module
import $ from jquery;
import go from myapp;
$(go);
/script

inline that I'm surprised this is even a discussion.

Dave

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


Re: detecting JS language mode for tools

2014-01-27 Thread David Herman
[Resending, not sure why it's not getting through to the list...]

On Jan 27, 2014, at 10:41 AM, David Herman dher...@mozilla.com wrote:

 On Jan 27, 2014, at 2:07 AM, David Bruant bruan...@gmail.com wrote:
 
 Indeed. I'm wondering why we need inline script for modules.
 
 Because people write inline scripts all the time. It's unacceptably 
 inconvenient not to be able to bootstrap your app with inline code. It also 
 allows you to control for when the scripts resource is there, in particular 
 to be sure that necessary bootstrapping/kernel code has loaded before you 
 need to do some wiring up of your app.
 
 But it's not even worth overthinking. It's so obviously, obscenely 
 anti-usable not to be able to write
 
script module
import $ from jquery;
import go from myapp;
$(go);
/script
 
 inline that I'm surprised this is even a discussion.
 
 Dave
 

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


Re: Proposal: Generator returning a value should throw SyntaxError

2014-01-27 Thread David Herman
Here are several ways to think about return:

- A generator function is like a normal function but it can be paused. The act 
of pausing can send an intermediate value out to the caller (yield's argument) 
and the caller can send an intermediate value back in when resuming (yield's 
result). None of this changes the fact that, like ordinary functions, there are 
still arguments passed into the function and a result passed out. Refusing 
return values just breaks down this generalization.

- A generator function produces an iterator object, which produces a record on 
each iteration that has a .value and a .done flag indicating whether the 
iteration is done. Refusing return values eliminates the .value field in this 
special case, making things less consistent.

Finally, task.js is just an example of building a control abstraction out of 
iterators. It happens that the for-of control flow form is imperative and 
doesn't have a use for a return value. That doesn't mean other control flow 
operations won't.

Dave

On Jan 27, 2014, at 2:18 PM, Adam Ahmed aah...@atlassian.com wrote:

 In light of the recent thread discussing async and await keywords, I thought 
 it'd be appropriate to raise this point again, understanding it may be too 
 late to make a change.
 
 As my original post details, the concept of `return` within a generator is 
 surprising in its difference in behavior from `yield`.
 
 This does not do as 'expected' in a for-in:
 
 function * threeCount() {
   yield 1;
   yield 2;
   return 3;
 }
 
 The argument for allowing return values was that usages in the vein of 
 task.js will use the return value as a real return value and the yields for 
 scheduling.
 
 If we' re going to have async and await serve the scheduling purpose as well, 
 can we remove the 'return' foot gun from generators? It sounds like it's just 
 a stopgap until async-await, and a painful one, IMO. A syntax error on a 
 generator that returns values would make the scheduling (async-await) vs 
 iteration (generator) use cases much more clear. It'll be much easier for new 
 JS devs to understand generators.
 
 Happy to be shutdown again, just thought it was worth reconsidering with new 
 async-await keywords in play.
 
 On 27/09/2013 3:46 PM, Brandon Benvie bben...@mozilla.com wrote:
 On 9/26/2013 10:40 PM, Brandon Benvie wrote:
 ```js
 function* foo() {
   yield 'what';
   yield 'ever';
   return DONE;
 }
 
 function* bar() {
   console.log(yield* foo());
 }
 ```
 
 Err, this logs DONE when you do:
 
 ```js
 var gen = bar();
 gen.next();
 gen.next();
 gen.next();
 ```
 but you got the idea...
 ___
 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

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


Re: multiple modules with the same name

2014-01-27 Thread David Herman
On Jan 27, 2014, at 2:18 PM, Marius Gundersen gunder...@gmail.com wrote:

 So then there would be two versions of the same module, and a module could 
 get access to both these modules at the same time. For example, if ModuleB, 
 which depends on ModuleA is loaded and linked, and later ModuleA is 
 redefined, then ModuleC could depend on both ModuleB and ModueA, and would 
 get (indirect) access to two versions of ModuleA. Is this problem preventable?

It's important to be able to modify module registration for things like 
polyfilling. But that doesn't mean it's something people should do in general. 
Note that Jason only gave you an answer in the context of the basic module 
loader semantics; he didn't say what will happen in the HTML semantics. In 
particular, we can make it an error for there to be two definitions of the same 
module name in the same HTML, a la:

  script type=module name=jquery src=jquery1.js/script
  script type=module name=jquery src=jquery2.js/script

I'm inclined to call that an error, and require imperative modifications of 
existing module registrations to use imperative code.

Dave

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


Re: Reason why generators do not have references to themselves?

2014-01-24 Thread David Herman
On Jan 23, 2014, at 4:49 PM, Brendan Eich bren...@mozilla.com wrote:

 Domenic Denicola wrote:
 Task.js is still on JavaScript1.8,  and is not ES6-compatible. It won't 
 work with modern browsers, or with Regenerator.
 
 Fork and fix, should be easy. I expect a PR would be accepted in due course. 
 SpiderMonkey seems to have ES6 generator support somewhat there (thanks to 
 Andy Wingo), should be all there soon enough.

Working on it lately, actually. And using regenerator for the tests (\o/)! Also 
drastically simplifying the library since the customizable scheduler stuff, 
while kind of neat, is probably less compelling than a minimal library. Down to 
under 150 lines, unminified with comments, and still shrinking...

Dave

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


Re: const VS features detection

2014-01-06 Thread David Herman
On Jan 6, 2014, at 8:10 AM, Brendan Eich bren...@mozilla.com wrote:

 To further constrain design (since design is mostly about leaving things 
 out), I will address the ES4-era |let (x = y, z = z /* outer z*/) ...| let 
 blocks and let expressions, which came up recently. We should not revive 
 these, given do expressions. do-exprs compose better with let and const (and 
 other binding form) declarations.

Fully agreed.

Dave

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


Re: “Arrow is not a replacement for all functions that want lexical this”

2013-12-09 Thread David Herman
On Nov 28, 2013, at 12:25 AM, Axel Rauschmayer a...@rauschma.de wrote:

 Source: David Herman, 
 https://github.com/rwaldron/tc39-notes/blob/master/es6/2013-11/nov-20.md
 
 Can someone elaborate? I don’t see an alternative.

I can't remember the example I used in the meeting, but one example is a 
recursive function:

  class Chicken extends Weapon {
constructor(length, elasticity, initialVelocity) {
  this.length = length;
  this.elasticity = elasticity;
  this.initialVelocity = initialVelocity;

  var self = this;

  function animate() {
...
self.velocity
self.elasticity
self.length
...
setTimeout(animate, n);
...
  }

  ...
}
  }

The point I was making in the meeting was that arrow functions are a syntactic 
convenience for a common case, not a general-purpose replacement for all 
functions that need to refer to an outer this-binding. They are not 
general-purpose because they don't support all the features of longhand 
functions.

Dave

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


Re: “Arrow is not a replacement for all functions that want lexical this”

2013-12-09 Thread David Herman
On Dec 9, 2013, at 12:36 PM, Axel Rauschmayer a...@rauschma.de wrote:

 What I’m worried about is conceptual simplicity. I like function declarations 
 and prefer them to function expressions, but recently did a small survey on 
 Twitter and was surprised to find out that the majority of people prefer var 
 + function expression to a function declaration, because then there is only a 
 single kind of function definition.

My only point was that in general, arrow functions will not completely replace 
longhand functions. It may be the case that for some programmers, even many 
(though I'm skeptical), they will. They won't in general.

Dave

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


Re: Modules vs Scripts

2013-11-17 Thread David Herman
On Nov 17, 2013, at 11:59 AM, Axel Rauschmayer a...@rauschma.de wrote:

 On Nov 17, 2013, at 6:14 , David Herman dher...@mozilla.com wrote:
 
 Does this imply module src= ?
 
 Works either way, inline or external. (Requiring src= is one of the 
 reasons why script async was a non-starter.)
 
 Is the value of `src` a module ID or a path? How about when packages are used 
 (for bundling)? Is there a way to combine module IDs and packages?

For the most part the answer to these kinds of questions is that we support 
all of the above, but I'd like to wait just a little bit longer before 
getting into details. Right now we've been focusing on providing a complete 
base (reflective) layer via the Loader API, which is what will be in ECMA-262; 
the rest is an HTML spec. (We are thinking through what pieces are necessary 
for the module tag to ensure we haven't missed anything in the Loader API.) 
I'm focused on getting ES6 out the door, but the next step after that is to 
start fleshing out the module spec.

Dave

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


Re: Modules vs Scripts

2013-11-16 Thread David Herman
On Nov 16, 2013, at 3:32 AM, John Barton johnjbar...@google.com wrote:

 Could someone help me understand why two goals for parsing JS is a good thing?

Hm, it sounds like you've assumed a conclusion already. Let me try to explain 
anyway.

Scripts are for synchronous loading and evaluation; modules are for 
asynchronous loading and evaluation. The former is not allowed to import, which 
triggers I/O. The latter is allowed to import. There was always going to have 
to be a syntactic split.

But there's more. I'll be explaining at this week's TC39 meeting some more 
details about the intended model for browser integration. In short, declarative 
code based on modules will use the module tag (or script type=module, 
which will mean the same thing and allows polyfilling today). This is better 
than script async, which was a hopeless idea. This also works beautifully for 
fulfilling the promise of 1JS: a new, better initial environment in which to 
run top-level application code without requiring versioning.

module
  var x = 12; // local to this module, not exported on global 
object
  import $ from jquery; // asynchronous dependency, NBD
  '$' in this // nope, because all globals are scoped to this 
module
  let y = 13; // yep, let works great because modules are strict
/module

Same number of characters as script, better semantics, better global 
environment, better language.

If you're not excited about ES6 yet, get excited. :)

Dave

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


Re: Modules vs Scripts

2013-11-16 Thread David Herman
On Nov 16, 2013, at 7:54 AM, Matthew Robb matthewwr...@gmail.com wrote:

 Does this imply module src= ?

Works either way, inline or external. (Requiring src= is one of the reasons 
why script async was a non-starter.)

Dave

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


Re: Mutable slots/indirect value API

2013-11-03 Thread David Herman
IOW expose the first-class reference type of ECMA-262 via a standard library? 
Just say no! :)

First, the module function API is written up wrong on the wiki; the function 
won't take any arguments at all. My apologies, I discovered my mistake as I was 
working on the spec writeup in the last few days. I'll be updating the wiki as 
soon as I complete the draft spec.

Here's how cycles work. An AMD compatibility layer would simply use the 
dependency list to look them all up in the loader to pass as arguments to the 
AMD module-function. Any dependencies that are not there yet are assumed to be 
forward references in a cycle, and the compatibility layer synthesizes new 
exports plain-old-objects to pass in to the AMD functions. (BTW we'll be 
building proof-of-concept AMD compatibility layers to demonstrate that this 
works.)

BTW, this whole module-function rigamarole only exists for AMD compatibility, 
so it's only important for it to demonstrate interoperability. For normal ES6 
use cases there's just no need to use it.

Dave

On Nov 3, 2013, at 10:03 AM, James Burke jrbu...@gmail.com wrote:

 With the import/export mutable slots concept, does it make sense to
 allow an API that has expresses that type of concept? I think it would
 allow creating a module-function thunk that would allow robust cycles
 as mentioned here:
 
 https://mail.mozilla.org/pipermail/es-discuss/2013-November/034576.html
 
 So something that returns a value, but when it is looked up by the
 engine, it really is just an indirection to some other value that can
 be set later. Call it IndirectValue for purposes of illustration, but
 the name is not that important for this message:
 
 var value = new IndirectValue();
 
 // something is a kind of ref to a ref engine type under the covers
 var something = value.ref();
 
 typeof something === 'undefined' // true at this point
 
 // Some time later, the code that created the
 // IndirectValue sets the final value for it.
 value.set([100, 200]);
 
 // Then later,
 Array.isArray(something) // true now
 
 IndirectValue.prototype.set() could only be called once, and the
 engine under the covers could optimize the indirections after the
 set() is called so that the indirection would not longer be needed.
 
 James
 ___
 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: computed property keys and ES5 duplicate rule enforcement

2013-11-02 Thread David Herman
On Oct 25, 2013, at 7:49 PM, Allen Wirfs-Brock al...@wirfs-brock.com wrote:

 It turns out that even in pseudo code, this is a fairly complicated set of 
 runtime validation rules to apply.  I'm having a hard time convincing myself 
 that the runtime computational and meta data costs of this dynamic validation 
 is justified.  It costs too much and the actual benefit is pretty small.
 
 ***For that reason, I propose that we drop this runtime validation of object 
 literals (and class definition).  We would still have the static validation 
 and early errors for property definitions that don't have computed keys. But 
 anything that makes it past those checks (including all property definitions 
 with computed names) are just processed sequentially with no duplicate name 
 checking.***

Yep, I fully agree. And I especially appreciate what you say below:

 What about predetermining the shape of literal objects that include 
 computed property keys? 
 
 One of the reason for the dynamic checks was the desire to preserve the 
 characteristics that allowed an implementation to look at an object literal 
 and statically determine exactly how many own properties the resulting 
 objects would have.  The hope was that an implementation could still 
 determine an intended shape and that the dynamic checks would guarantee that 
 the actual constructed objects conform to that predicted shape. If we drop 
 the dynamic checks we loose that shape guarantee.
 
 I think this ability to predict an intended shape was probably a committee 
 pipe-dream.

Amen.

 Consider this function:
 
 function makeObj(a,b,c,d,e) {
return {
   get [a] () {},
   get [b] () {},
   set [c] (v) {},
   set [d] (v) {},
   set [e] (v) {}
 }
 }
 
 The object returned by this function might validly have 3, 4, or 5 
 properties. The is no clearly intended shape to try to guarantee.

The shape predictability concept has never really been defined clearly, and 
this is a good demonstration of why it's fishy.

Anyway, agreed 100%. It's worth revisiting at the November f2f.

Dave

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


Re: Modules loader define method

2013-11-01 Thread David Herman
On Oct 31, 2013, at 7:10 AM, Erik Arvidsson erik.arvids...@gmail.com wrote:

 I see that Jason added a Loader.prototype.define to his reference 
 implementation. 
 https://people.mozilla.org/~jorendorff/js-loaders/Loader.html#section-177. 
 This is great. It is a much needed capability to allow bundling modules into 
 a single file.
 
 It allows you to do something like
 
 System.define(['url-a', urlB], ['export var a = a;', moduleBodyForUrlB]);
 
 However, this is just another form of eval and will therefore not be 
 available in CSP. Can we come up with something that works in CSP 
 environments? How about?
 
 module 'url-a' {
   export var a = a;
 }

As I said in the September meeting, eliminating the named declarative module 
form (a form which, you might recall, you went on record in the London meeting 
as saying was a mistake we'd regret... ;-P) is motivated by separation of 
browser concerns and ES concerns.

The answer to making this work in CSP is to (a) make the loader API 
sufficiently generic that we can (b) solve it in the HTML layer. So the way 
we've done that is to say that loaders have a polymorphic notion of what 
module source is -- it doesn't have to be a string. In the browser API level, 
the AppWorker (aka ServiceWorker aka NavigationController) will be introducing 
ways to load cross-domain opaque payloads that can be absorbed by some sinks in 
the platform that are allowed to absorb them (e.g. img and script tags). 
The browser system loader will then be specified to allow .define to take such 
cross-domain payloads.

There's no need for ad hoc language forms for peculiarities of the web 
platform, when they can much more cleanly be designed with web platform API's.

Dave

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


Re: Modules: import *

2013-11-01 Thread David Herman
On Nov 1, 2013, at 7:44 AM, Jason Orendorff jason.orendo...@gmail.com wrote:

 Now... good use cases could be a sufficient counterargument to all
 this. Maybe we should add `import * from` in 2014. I just want to make
 it totally clear why it's designed this way for ES6. `import * from`
 poses significant problems, both for users and implementations, that
 `export * from` doesn't.

Agreed. I do think there's a good change people will start asking for import * 
more once they've been using the module system, and we can revisit in ES7. 
There could also be additional technical challenges with lexical modules (if 
you can say `import * from x` there are weird scoping paradoxes that are hard 
to eliminate), so it makes sense to wait to reconsider import * until we're 
dealing with lexical modules.

Anyway, this will not be happening for ES6. Let's revisit for ES7.

Dave

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


Re: Modules: import *

2013-11-01 Thread David Herman
On Nov 1, 2013, at 6:19 PM, David Herman dher...@mozilla.com wrote:

 On Nov 1, 2013, at 7:44 AM, Jason Orendorff jason.orendo...@gmail.com wrote:
 
 Now... good use cases could be a sufficient counterargument to all
 this. Maybe we should add `import * from` in 2014. I just want to make
 it totally clear why it's designed this way for ES6. `import * from`
 poses significant problems, both for users and implementations, that
 `export * from` doesn't.
 
 I do think there's a good change

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


Re: Module: export *

2013-11-01 Thread David Herman
On Oct 31, 2013, at 8:06 AM, Erik Arvidsson erik.arvids...@gmail.com wrote:

 Make sense but I'm not sure it is needed/desired.

I agree, actually, despite being the one who put it in there in the first 
place. I originally intended it as a convenience e.g. for quick scripts. But by 
itself it's simply too brittle to work with; as soon as you have an internal 
definition you don't want to export you can't use it -- other languages have a 
way of blacklisting bindings but the export syntax starts getting too baroque 
so I never went there.

I do suspect Sam has a point, that in time people will start wishing for some 
of the conveniences we've eliminated. But I'm happy to revisit it in ES7. For 
now, though, it doesn't make sense to have `export *;` by itself, without 
additional constructs that make it more usable. Call this... maximally minimal 
export syntax. ;-P

Dave

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


Re: proposal for efficient 64-bit arithmetic without value objects

2013-10-30 Thread David Herman
On Oct 30, 2013, at 1:56 PM, Luke Wagner l...@mozilla.com wrote:

 Just to be sure, do you agree that both the {lo, hi}-returning API and the 
 magic-property API should both be able to achieve equivalent performance on a 
 JS engine that has specifically added and optimized these int64 builtins?  I 
 think this is true.
 
 Assuming so, the reason to prefer the rather more awkward magic-property API 
 would be purely because its polyfill is more efficient.  This is a tough 
 choice, but it seems like bending the spec for the polyfill is overly 
 conservative in this case.  A lot of the use cases I hear for int64 come from 
 crypto and other very specific algorithms which already have implementations 
 in JS.  In such cases, it seems like the authors have to write a new version 
 of the algorithm using the new builtins anyway so, if performance was 
 important, they could just keep around the old version and pick which version 
 to call based on whether the new builtins are present.  Or they can just wait 
 until the optimization is broadly available before switching.

Agreed -- the magic-property API is pretty astoundingly wacky, and definitely 
not worth it.

 The other main use case I can think of is large compiled C++ codebases.  
 However, in our experience, C++ codebases tend not to heavily use int64 so 
 the overhead of the polyfill would be less significant.

I'm open to the {lo, hi} version of the API as a stopgap, but since we don't 
see a big need for it in compiled codebases and it's warm beer for human 
programmers, then looking at Slava's rationale...

 I think such API has many advantages:
 
 - can greatly improve performance of numeric algorithms relying on 64-bit 
 math;
 - easily polyfillable in the current JavaScript;
 - does not depend on any complicated language changes (e.g. value objects);
 - simple to implement and optimize on any platform (including 32bit ones);

...I'd say it's not particularly necessary for the short-term, and it's 
definitely not sufficient for the long-term. We can and must do better for 
programmers than declare {lo, hi} as a realistic API for 64-bit integers. Value 
types are in JS's future.

 API considerations aside, though, I like the idea of bringing fast 64-bit 
 arithmetic to JS without waiting for value objects.

As I say, I could see doing the less wacky API for short-term, but I don't 
think it's vital.

Dave

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


Re: Comments on Sept Meeting Notes

2013-09-27 Thread David Herman
On Sep 27, 2013, at 9:07 AM, David Bruant bruan...@gmail.com wrote:

 I agree with the intent of keeping semantics of inter-worker and 
 inter-machine very close, but the difference in terms makes very clear that 
 not being able to differenciate the 2 cases incurs an information loss that 
 can be detrimental to some use cases, especially performance-related ones.

Yeah, I worry about chasing after that holy grail of fully transparent 
distribution, which IMO is in the list of misbegotten CS fantasies, up there 
with fully automatic parallelization and human-level AI.

More to the point: as I see it, unique symbols are, like File objects and 
ArrayBuffers, an ephemeral construct that can only be managed within a single 
VM/computer. GUIDs are a fine thing to use for messaging protocols between 
computers in a distributed setting, but I see nothing wrong with an additional 
marshalling/unmarshalling layer being required to make that work. And I'm 
skeptical of such a layer being automatically managed by the language (probably 
for a similar reason to one of the things Mark hates about structured clone: 
the magic built-in behavior hard-wired to special built-in types).

That said, I could still imagine that if we had a solution for allowing 
handshaking between workers without them sharing state (which AIUI was Mark's 
issue with the registry strawman I suggested in this thread), that a similar 
mechanism could be useful for handshaking between computers: while user code 
would still manage the JSON encoding of symbolic names (e.g. by name mangling 
schemes), the unmarshalling side could then make sure to locally register the 
GUID with a symbol.

Dave

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


Re: Comments on Sept Meeting Notes

2013-09-27 Thread David Herman
On Sep 27, 2013, at 8:28 AM, Allen Wirfs-Brock al...@wirfs-brock.com wrote:

 On Sep 27, 2013, at 7:52 AM, Erik Arvidsson wrote:
 
 What's the use case for Symbol.keyFor?
 
 
 The use case was actually suggested in a response to dherman earlier in this 
 thread when he mentioned sharing symbols between workers.
 
 If you need to serialize an object with symbol keyed properties you need to 
 convert the symbol into sometime that can be equivalently recreated on the 
 other side of the serialization barrier.  For a registered Symbol the obvious 
 way to do this is via its registration name:
 
 Symbol.toJSON = function() {
   let key = Symbol.keyFor(lthis);
   if (key === undefined) return null;  //unregistered symbols can't be 
 serialized in this example
   return **Symbol:+key;
 }
 
 
 The deserializer would have to do a pass over the resulting objects 
 replace=ing **Symbol:... property names with the locally register Symbol 
 under the same key.

Oh, I think I finally understand what you're getting at, and how it avoids any 
shared state. Let me summarize, and forgive me for just repeating what you've 
already said:

- don't share symbols between workers
- registries are per-worker (in which case there's absolutely nothing needed 
from the language mechanism-wise, except to establish conventions)
- use some custom encoding for representing symbolic property names as string 
names that contain their registry key

Then workers can coordinate without needing to do any special handshaking or 
up-front message-passing, they just register names lazily as they encounter 
them in the marshalling/unmarshalling process.

AFAICT this constitutes a complete story for symbol registration that requires 
zero new mechanisms in the language (beyond symbols, of course).

Dave

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


Re: Comments on Sept Meeting Notes

2013-09-27 Thread David Herman
On Sep 27, 2013, at 10:02 AM, David Herman dher...@mozilla.com wrote:

 - don't share symbols between workers

Follow-up thought: it seems there are actually two concepts that both get 
grouped under realms and yet might warrant distinction. These correspond on 
the web to two same-origin windows vs two workers.

Between same-origin windows, you have different realms but a shared heap. In 
that case, you really want e.g. @@iterator to be === regardless of the realm it 
comes from. If one same-origin window shares an iterable object with another 
same-origin window, we want it to remain iterable. So we really want to specify 
that within a heap, multiple realms can share symbols (there's no way to stop 
them from sharing them anyway) and the ES6 standard symbols are unique. This 
also means that you want one registry shared across realms within that heap. I 
still don't think this needs new mechanism from the language, though, since 
same-origin windows can synchronously communicate to handshake on a shared 
registry object.

Between workers, you have different realms and completely separate heaps. 
Allen's suggestion has @@iterator being completely uncommunicable between the 
different heaps.

So I think Allen's protocol still works, you just have to have sharing of 
symbols across multiple realms that exist within the same 
worker/heap/vat/whatchamacallit.

Dave

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


Re: Comments on Sept Meeting Notes

2013-09-27 Thread David Herman
On Sep 27, 2013, at 10:14 AM, David Herman dher...@mozilla.com wrote:

 On Sep 27, 2013, at 10:02 AM, David Herman dher...@mozilla.com wrote:
 
 - don't share symbols between workers
 
 Follow-up thought: it seems there are actually two concepts that both get 
 grouped under realms and yet might warrant distinction. These correspond on 
 the web to two same-origin windows vs two workers.
 
 Between same-origin windows, you have different realms but a shared heap. In 
 that case, you really want e.g. @@iterator to be === regardless of the realm 
 it comes from. If one same-origin window shares an iterable object with 
 another same-origin window, we want it to remain iterable. So we really want 
 to specify that within a heap, multiple realms can share symbols (there's no 
 way to stop them from sharing them anyway) and the ES6 standard symbols are 
 unique. This also means that you want one registry shared across realms 
 within that heap. I still don't think this needs new mechanism from the 
 language, though, since same-origin windows can synchronously communicate to 
 handshake on a shared registry object.

Another follow-up: even easier than creating some new registry is just to use 
the module registry. You can do that when creating a new realm by simply 
sharing an existing module instance:

var newRealm = new Loader(...);
newRealm.set(serialize, System.get(serialize));

Or if you're implementing a web library and you want to be sure that all 
windows see the same symbol the module can initialize its own symbols by 
querying the environment to see if the symbol already exists:

// serialize.js
let m = window.top.System.get(serialize);
export const serialize = m ? m.serialize : new Symbol(friendly name);

Dave

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


Re: Comments on Sept Meeting Notes

2013-09-27 Thread David Herman
On Sep 27, 2013, at 12:05 PM, David Herman dher...@mozilla.com wrote:

export const serialize = m ? m.serialize : new Symbol(friendly name);

And... of course I meant `Symbol()` rather than `new Symbol()`. Haven't 
retrained my muscle memory from the days of the object-based API. ;)

Dave

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


Re: Safe, Closure-free, Serializable functions‏

2013-09-26 Thread David Herman
On Sep 26, 2013, at 1:10 PM, François REMY francois.remy@outlook.com 
wrote:

 TLDR == The web needs a way to express executable code that does not rely 
 on its parent context, is guaranteed to be side-effect-free, and can be 
 executed safely anywhere (even in a different thread/worker/window/device, 
 or as callback for browser code being executed while the DOM is not ready 
 to be accessed)
 Why need? You don't really expose a use case. You only start with
 It's been some time I've been working on this idea of a...
 
 Also, one thing is not really clear to me. Are you trying to protect the
 function from its caller/loader or the caller from the function? both?
 
 The use case is at the bottom: I want to be able to use JavaScript functions 
 inside the browser as part of algorithm customization. For example, use some 
 JavaScript function as part of the layout computation of an object, or as the 
 animation timing function.

This is an area I've put some thought into. However, you've described a 
mechanism but not really made the case that environment-free closures is the 
only or best solution. In fact I think they are a bad idea, but I agree with 
the desideratum that a way to share functions across JS heaps would be highly 
desirable.

## Why shareable functions are desirable

Lots of reasons, such as:

- more convenient workers or worker-like API's (a la Erlang spawn)
- ability to provide JS customization for native API's that want to run JS code 
in parallel or in the background
- more JS customization (a la the extensible web [1]) for core browser 
technologies that doesn't compete with potential parallelization of those 
technologies
- ability to write parallel abstractions (along the lines of map) that can 
concisely but safely -- and ideally efficiently -- share data

## Why environment-free closures is a bad idea

First, I don't want introduce the ability to test whether a function is 
environment-free. This interfere with fundamental information hiding guarantees 
of closures. (And any API that depends on a closure being environment-free to 
protect its invariants requires the ability to perform that test.)

Second, I think it's very confusing to have code that is lexically nested but 
interpreted in a completely different scope:

var x = 42;
spawn(function!() { // imaginary function! syntax
... x ... // x is a global variable in some worker
});

Third, I don't think it's sufficiently expressive. I'd be much more interested 
in seeing something along these lines:

- the ability to define custom serialization logic (as opposed to, or perhaps 
in extension to, the ad hoc structured clone algorithm)
- the ability to define serializable functions whose serialization logic lifts 
through their upvars

This is more expressive than environment-free closures because it allows shared 
functions to also share their closure data. But it also narrows the observation 
you can make on a closure from does it have anything in its environment? to 
is its environment shareable? This is the real question you want to be asking 
anyway, and it doesn't violate the abstraction closures provide.

Don't get me wrong, it's also a much harder problem. But I've been starting to 
get my head around it little by little. It'd require some published protocol 
for customizable serialization (a standardized @@serialize symbol, or maybe 
some kind of traits feature) and some static requirements on the shape of the 
code of a serializable closure. I imagine the serialized upvars would have to 
be const, and we'd probably need to require them to all be initialized at the 
time of serialization. (Or something. More research to do here.) To make 
serialization efficient, you'd want the ability to write directly into the 
other heap in a fast and space-efficient way, but the typed objects API is very 
promising here: user code can pick whatever representation format it wants and 
the code on the other side will be able to interact with the resulting data as 
an object.

There's also a question of whether you'd want a single serialize operation or 
two separate clone vs move operations (analogous to the transfer semantics 
for ArrayBuffers). Tony Arcieri blogged about some similar ideas last year. [2]

At any rate, this is an area I'm very interested in, and so are some others in 
my group at Mozilla Research.

Dave

[1] http://extensiblewebmanifesto.org/
[2] 
http://tonyarcieri.com/2012-the-year-rubyists-learned-to-stop-worrying-and-love-the-threads

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


Re: Comments on Sept Meeting Notes

2013-09-26 Thread David Herman
On Sep 26, 2013, at 3:20 PM, Allen Wirfs-Brock al...@wirfs-brock.com wrote:

 Maybe the exception could be enumerability exception could be concise methods 
 with string literal property names that do not parse as IdentifierName.

http://www.youtube.com/watch?v=VX4DJUr5oYg

Dave

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


Re: Comments on Sept Meeting Notes

2013-09-26 Thread David Herman
On Sep 26, 2013, at 3:48 PM, Domenic Denicola dome...@domenicdenicola.com 
wrote:

 I don't understand why this is happening. There was fairly strong consensus 
 on symbols at the last meeting, and nothing new has been brought to the 
 table. Why are people's opinions suddenly changing? Vague fearmongering about 
 complexity? Symbols are a good solution to a real problem, much better than 
 strings.

+so much

I am very disappointed by this thread.

Dave

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


Re: Comments on Sept Meeting Notes

2013-09-26 Thread David Herman
On Sep 26, 2013, at 3:47 PM, Allen Wirfs-Brock al...@wirfs-brock.com wrote:

 Oh, that's not Hungarian notation, it's just a name space qualifier.

Don't talk down -- Rick was making a metaphor.

 But, if you assume that we will added a real private state mechanism into ES 
 6.1 or ES6.2 will Symbol really carry its weight looking back 10 years 
 from now?

Hell yes, if it saved us from __iterator__ or std:iterator or @iterator or 
@ECMA@262@Edition@6@iterator.

Dave

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


Re: Comments on Sept Meeting Notes

2013-09-26 Thread David Herman
So let's assume there is such a registry. You can avoid accidental collisions 
with the ugliest name in the universe -- gensym that thing to the n'th degree 
-- but you're no longer forcing all clients to deal with the ugliness. You've 
abstracted it behind your library. Let's say I'm implementing a serialization 
library and want to create a @@serialize symbol for people to coordinate on. 
I'd do something like the following:

// serialize.js
import { lookup, register } from js/registry;

const myGUID = 
__@@blarrrhhhAUHHHfnordfnordfnord29834983413451839512@@__;

export default = lookup(myGUID) || register(myGUID, new Symbol(friendly 
name));

Now every client simply gets to use

import serialize from serialize;

obj[serialize] = function() { ... };

without having to care about how ugly the GUID used in the registry was.

Dave

On Sep 26, 2013, at 4:07 PM, Mark S. Miller erig...@google.com wrote:

 I think we swept the collision problem under the registry rug. Let's start by 
 discussing registry designs assuming we do have Symbols. Let's see if we can 
 design a registry that allows cross-realm duck typing without re-introducing 
 the same possibility of accidental collision that we'd have without Symbols. 
 Note: For this question, malicious collision is not an issue.
 
 
 On Thu, Sep 26, 2013 at 4:02 PM, Rick Waldron waldron.r...@gmail.com wrote:
 
 
 
 On Thu, Sep 26, 2013 at 6:51 PM, Domenic Denicola 
 dome...@domenicdenicola.com wrote:
 
 
  On Sep 26, 2013, at 18:49, Yehuda Katz wyc...@gmail.com wrote:
 
  Private state doesn't satisfy these requirements because they trap on the 
  wrong side of the proxy.
 
 Agreed, in many cases I don't want private state; I *want* something that can 
 be copied by Object.mixin, for example. For private state, weak maps are 
 fine, and used today already.
 
 
 Agreed with Yehuda and both of Domenic's points. I don't need/want Symbol for 
 private anything—I want it for cases that don't deserve a WeakMap, should be 
 reflected and can be seen by Object.getOwnPropertySymbols(), but want to 
 avoid the possibility of collision.
 
 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

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


Re: Comments on Sept Meeting Notes

2013-09-26 Thread David Herman
On Sep 26, 2013, at 4:26 PM, Rick Waldron waldron.r...@gmail.com wrote:

 Thinking about this in terms of tooling, at even the terminal level, might 
 look like this: http://gyazo.com/f61d0e25366ce7e526c79ab7fa77cb17.png

No no, the GUID doesn't go in user land objects. It only goes in the registry. 
The user land objects only use the symbol. The GUID is just the entry into the 
registry, used internally by the serialize library.

IOW, I'm saying that symbols are better than obfuscated strings because *even 
if you use obfuscated strings* for managing the installation of globally shared 
symbols, those obfuscated strings are internal to the library and not exposed 
to client code or client objects. The client objects just use the clean symbol.

Dave

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


Re: Comments on Sept Meeting Notes

2013-09-26 Thread David Herman
On Sep 26, 2013, at 4:22 PM, Mark S. Miller erig...@google.com wrote:

 I am saying collision is an issue, but that it only seems that Symbols solve 
 it because we haven't yet designed the registry. So we should do so first, 
 and then re-examine this question in the context of a concrete registry 
 design.

I don't think a registry design is necessary for symbols to be useful today.

But I agree it's a fine thing to consider for future-proofing. Design-wise, it 
would probably be cleanest to have a single function with a test-and-set 
semantics. Something like:

Symbol.register(stringKey[, friendlyName])

which registers in cross-realm shared state a new shared symbol registered 
under the given key, or returns the existing registered symbol if one already 
exists. This avoids any observable race conditions (except for competing 
friendlyNames, but that's pretty harmless) in the semantics but allows 
coordination across realms.

(Specification-wise, it's probably hard to specify the shared state precisely 
without having constructs like workers in the spec. But maybe it could be given 
an informal specification that speaks hand-wavily about being thread-safe.)

Dave

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


Re: Comments on Sept Meeting Notes

2013-09-26 Thread David Herman
On Sep 26, 2013, at 5:03 PM, Allen Wirfs-Brock al...@wirfs-brock.com wrote:

 I meant, if you didn't have symbols you could pretty much do the same thing 
 by exporting a name that is bound to the GUID string as its value.  That 
 exported name could be imported by clients and used as the friendly way to 
 refer to that property name, just like you are suggesting they do with Symbol 
 values. 

The difference is the ergonomics. The GUID shows up in your developer tools, 
when you introspect on the property names, etc. The symbol shows up as a 
symbol, which is conceptually cleaner and vastly more readable. If you have 5 
different GUIDs in your object, and you inspect the object in developer tools, 
you have to go and manually look up which one corresponds to which abstraction. 
Or if you use a human-readable but mildly obfuscated name, then you need a 
naming convention, and then you have the collision problem all over again. 
Finally, you can use an obfuscated GUID-y suffix but with a human-readable 
prefix, so at least humans have some hope of reading it, but you've still made 
your users' lives unpleasant.

With symbols you give all your users the pleasant experience of a clean 
distinction between symbol and string. And with some sort of registry, you can 
provide an abstraction that registers the symbol so that multiple realms can 
even coordinate on the symbol even in the face of multiple distinct copies of 
the library.

Am I not explaining this well? I feel like I've been trying to make this point 
several times over in this thread. One of the biggest issues with GUID's -- the 
thing that makes everyone turn three shades of green every time it gets 
proposed -- is the ergonomics. One of the main complaints people made about 
symbols was that it's not possible to do userland coordination across realms. 
While I don't think we have to solve that for ES6, my examples demonstrate that 
with a registry symbols absolutely can provide cross-realm coordination while 
tangibly beating out string conventions for ergonomics/usability/readability.

Dave

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


Re: Comments on Sept Meeting Notes

2013-09-26 Thread David Herman
On Sep 26, 2013, at 7:01 PM, Kevin Smith zenpars...@gmail.com wrote:

 - Enumerability?  Yawn...  Enumerability of user-created meta-level method 
 names is fine and should be expected, just as we expect enumerability of 
 _-prefixed method names today.

Whether you personally use it, for-in is a reality. Introspection of objects 
happens, so if you ship a library that's putting meta-level properties into 
objects it needs to make them non-enumerable to be robust in the face of client 
code that uses for-in but isn't prepared to understand the meta properties.

 - Duck typing *must* work across Realms.  Symbols without a registry do not.  
 You can make special cases for built-in symbols, but special cases make bad 
 law.

Symbols are absolutely future-proof for a registry. If we don't solve all use 
cases today, we keep working to improve the language and address more use 
cases. Someone I know recently made the point that the perfect is the enemy of 
the good...

 - If you are going to use a symbol registry, then you really need to prove 
 how that is any better than just using the registry key itself.

Between Yehuda and me I count 7 times that we've addressed this point in this 
thread.

https://mail.mozilla.org/pipermail/es-discuss/2013-September/033768.html
https://mail.mozilla.org/pipermail/es-discuss/2013-September/033770.html
https://mail.mozilla.org/pipermail/es-discuss/2013-September/033771.html
https://mail.mozilla.org/pipermail/es-discuss/2013-September/033774.html
https://mail.mozilla.org/pipermail/es-discuss/2013-September/033766.html
https://mail.mozilla.org/pipermail/es-discuss/2013-September/033756.html
https://mail.mozilla.org/pipermail/es-discuss/2013-September/033755.html

 - Is getting a symbol with (1) a GUID and (2) a friendly name, then (3) 
 toting that object around really more ergonomic than just using a string 
 literal?

Once again, read the above links. You aren't distinguishing between the 
ergonomics of the *provider* of a symbol and the *consumer* of a symbol, and 
it's the latter case that matters. The ergonomics are better for the consumer 
of a symbol than that of an obfuscated string, especially when working with 
developer tools or code that manipulates the key and ends up surfacing the 
obfuscated string.

 - Perfect (collision avoidance) is the enemy of the good (collision 
 avoidance).

Being more likely to break isn't actually a *virtue* so I don't think there's 
really anything to respond to here.

 - Symbols are surprisingly tricky at the spec level.  (new Symbol() throws, 
 what?)

Come on now. Auto-wrapping of primitives for method calls is a well-understood 
part of JS, but the wrapped objects themselves are not particularly useful and 
can be an attractive nuisance.

And here I want to second Yehuda's point: we're talking about a different kind 
of concept than strings, so it deserves a different language feature. Excessive 
language parsimony just results in more complexity for the programmer. We've 
seen this movie before: arrays are just objects, integers are just doubles, 
environment records are just objects...

Dave

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


Re: ImportSpecifierSet syntax

2013-09-11 Thread David Herman
Axel wrote:

 The problem is that you have to bite the bullet of syntactic inconvenience 
 for either default imports or normal imports.

Correct. This is the #1 justification.

Rick wrote:

 Subjectively, this is really hard to read, versus the curlies which provide a 
 visual boundary (also subjective)

I also agree with this. Too much word-based syntax without any sigils becomes 
hard to distinguish.

Dave

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


Re: ImportSpecifierSet syntax

2013-09-11 Thread David Herman
On Sep 8, 2013, at 12:45 PM, Brendan Eich bren...@mozilla.com wrote:

 Erik Arvidsson wrote:
 
 Oh, I forgot about that wart.
 
 
 Are default imports a wart no matter the syntax, or only because of this 
 brace imposition issue you've identified? If the latter, perhaps there is 
 another solution that gives us win-win.

Best of luck. :) We've spent a long time in this space, considered many 
competing constraints, and we've settled on a good spot with the syntax. I'm 
not interested in spending more time on it.

Dave

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


Re: Non-extensibility of Typed Arrays

2013-08-30 Thread David Herman
On Aug 30, 2013, at 9:39 AM, Allen Wirfs-Brock al...@wirfs-brock.com wrote:

 I think the right-way to think about structs is as an record structure with 
 no properties fixed behavior provided by a wrapper.  Very similar to the ES 
 primitives except that structs can be mutable.  The way to associate 
 properties with structs is to encapsulate them in an object, preferably via a 
 class definition. If we go that route we can reach the point where ES classes 
 have fixed-shape internal state defined as-if by a struct.

I might give a slightly different angle on this, and describe structs as 
objects with a fixed template for their own properties. They are still objects, 
they still inherit from prototypes. But they have a predefined set of own 
properties.

 Typed Arrays are a different beast that already exist in the real world.  I 
 don't see any need for consistency between Typed Arrays and struct types. 
 Consistency between Typed Arrays and Array is more important.

Mostly agreed, except I'd just refine that to say there's no need for 
consistency *in this dimension*. It would be a shame if typed arrays weren't 
generalized by the typed objects API in general, and I worked hard to make the 
pieces fit together. That nuance aside, the fact that, in practice, arrays are 
patched with additional properties (in fact, IIRC the ES6 template strings API 
adds properties to arrays) suggests that non-extensibility would be a real 
incompatibility between arrays and typed arrays. So I'm cool with making typed 
arrays -- but not structs -- extensible.

Dave

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


Re: Non-extensibility of Typed Arrays

2013-08-30 Thread David Herman
On Aug 30, 2013, at 12:46 PM, Filip Pizlo fpi...@apple.com wrote:

 OK - by sanepants do you mean that there is no weirdo aliasing?  Going back 
 to my example of field 'a' aliasing field 'b' - is it possible?

There is plenty of aliasing possible, but I'm trying to understand what you 
mean specifically by weirdo aliasing. Do you mean that in a given struct it's 
impossible for it to have two fields that alias each other? That's definitely 
true. E.g., if I have a struct type

var T = new StructType({ a: t1, b: t2, ... });

then for any given instance x of T, I know for sure that x.a and x.b do not 
alias the same storage.

Dave

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


Re: Non-extensibility of Typed Arrays

2013-08-30 Thread David Herman
On Aug 30, 2013, at 3:46 PM, David Herman dher...@mozilla.com wrote:

 E.g., if I have a struct type
 
var T = new StructType({ a: t1, b: t2, ... });
 
 then for any given instance x of T, I know for sure that x.a and x.b do not 
 alias the same storage.

(Except, of course, if t1 and t2 are pointer types like Object.)

Dave

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


Re: Non-extensibility of Typed Arrays

2013-08-30 Thread David Herman
On Aug 30, 2013, at 3:54 PM, Filip Pizlo fpi...@apple.com wrote:

 Yup, that's what I was concerned about.  And reading over the spec I agree.  
 But just for sanity, we're guaranteeing this because you cannot create a 
 struct type instance by pointing into an arbitrary offset of a buffer - you 
 can only instantiate new ones, or alias structs nested as fields in other 
 structs.  Right?

Hm, I must be missing something obvious, but I don't see why you'd need that 
restriction to guarantee this. A struct type with two different fields 
guarantees they're at different offsets from the base:

var T = new StructType({
a: int32, // offset 0
b: int32  // offset 4
});

so even if I point an instance of T into the middle of a struct, x.a and x.b 
must be at different offsets.

Dave

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


Re: Non-extensibility of Typed Arrays

2013-08-30 Thread David Herman
On Aug 30, 2013, at 4:20 PM, Filip Pizlo fpi...@apple.com wrote:

 This is the kind of weirdness that I hope struct types *don't* have, if their 
 alleged purpose is to help people optimize their code.

This is a great point, thanks. On the one hand, I concluded long ago the 
exposure of the buffer seems like something we can't really avoid, since it's 
necessary for WebGL arrays-of-structs, which is a main use case. On the other 
hand, that doesn't necessarily mean we need the ability to overlay a struct 
type into random points in a buffer. We'd have to do this carefully, though: I 
believe we'd have to restrict overlaying to just the legacy typed array 
constructors, not to any new kinds of array types (since they may have structs 
nested inside them), in order to guarantee lack of aliasing. And then we'd want 
to make sure this covered the WebGL use cases.

 Now, I don't object to typed arrays having this behavior - it is what it is, 
 and it's certainly useful for doing graphics type stuff.  It's also 
 indispensable for emscripten.  And I'm OK with struct types also having this 
 behavior; in fact I would *expect them to have such behavior* if they're 
 supposed by help C-to-JS code generators or the like.

Not really for C-to-JS, no. I do want them to be useful for e.g. Java-to-JS 
code generators, but those shouldn't need the casting.

Dave

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


Re: Non-extensibility of Typed Arrays

2013-08-27 Thread David Herman
On Aug 27, 2013, at 9:47 AM, Filip Pizlo fpi...@apple.com wrote:

 I do. Placing named properties on arrays makes sense. Consider a matrix 
 implemented as a Float32Array, with named properties telling you the numRows 
 and numCols. Just one example. 

There are of course other ways to achieve this that don't involve patching the 
array object, such as building a data abstraction for matrices that has-a 
Float32Array, or creating a new array type with additional methods:

var Matrix = new ArrayType(float32);
Matrix.prototype.numRows = function() { ... }
// or
Object.defineProperty(Matrix.prototype, { get: function() { ... }, ... });

 TA instances having no indexed expandos but allowing named ones is weird. 
 Better to be consistent to users
 
 Consistency would imply doing what other indexed types do. 

Consistency arguments won't get you very far. The indexed properties of typed 
arrays by design act very differently from other indexed types. That's their 
whole reason for existence.

And the other consistency dimension is between array types and struct types. Is 
anyone arguing that structs should also have expandos?

Dave

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


Re: Some Typed Objects Confusion

2013-08-21 Thread David Herman
Any, String and Object should still be uppercase. The naming convention is: 
value types lowercase, reference types uppercase.

Dave

On Aug 21, 2013, at 4:21 AM, Dmitry Lomov dslo...@chromium.org wrote:

 string, boolean, object and any are all lowercase (we should fix the wiki)
 
 FWIW, I am already working on a new version of polyfill. It is fully ES5.
 Here is a pull request: https://github.com/dherman/structs.js/pull/12 - I'll 
 merge it soon, and work more to cover everything in the proposal.
 
 Thanks,
 Dmitry
 
 
 
 On Wed, Aug 21, 2013 at 3:21 AM, Andrea Giammarchi 
 andrea.giammar...@gmail.com wrote:
 sorry, point 3 was actually the question about point 2
 
 
 On Tue, Aug 20, 2013 at 6:20 PM, Andrea Giammarchi 
 andrea.giammar...@gmail.com wrote:
 Uhm, just a couple of extra question about that page if/when you have time:
   • string and boolean are mentioned, but nowhere in your `struct.js` 
 prolyfill code. Will string and boolean be accepted?
   • `Object` and `Any` are mentioned, but exported as object and any in 
 your `struct.js` prolyfill example. W
   • Which is the right way?
 The reason I am asking is to be able to create code that does absolutely 
 nothing (for performance reason) but will look like the real thing so I can 
 start experimenting with static structures and possibly a develop VS 
 production version of an ES3 to ES5 compatible polyfill since I believe your 
 code won't run anywhere except in SpiderMonkey (which is OK but it's not 
 suitable for a lightweight migration to structure like logic)
 
 Thanks.
 
 
 On Tue, Aug 20, 2013 at 4:55 PM, Andrea Giammarchi 
 andrea.giammar...@gmail.com wrote:
 Awesome, thanks!
 
 
 On Tue, Aug 20, 2013 at 4:12 PM, David Herman dher...@mozilla.com wrote:
 On Aug 20, 2013, at 1:31 PM, Andrea Giammarchi andrea.giammar...@gmail.com 
 wrote:
 
  [In this 
  page](http://wiki.ecmascript.org/doku.php?id=harmony:typed_objects), and in 
  the latest meeting note too, I can read both uint8 and Uint8, as example.
 
 Bug. Fixed, thanks.
 
  **The Question**
  How is `new StructType({x:Uint32, y:Uint32})` supposes to understand the 
  type? `instanceof Uint32` or `typeof v === uint32` or ... both in case of 
  `boolean` and `string` ?
 
 Neither. It tells you that the x and y fields have typeof 'number' and that 
 their values are constrained to be integers in the range [0, 2^32).
 
  A bonus question would be: does anybody know when this stuff is planned to 
  go out? Not a single beta/alpha channel is exposing anything at all so far.
 
 Nikhil Marathe and Niko Matsakis are actively working on the implementation 
 for SpiderMonkey:
 
 https://bugzilla.mozilla.org/show_bug.cgi?id=578700
 
 Dmitriy Lomov is actively working on updating the prollyfill to match the 
 current API:
 
 https://github.com/dherman/structs.js
 https://github.com/dherman/structs.js/pull/12
 
 Not sure if anyone on the V8 team (which includes Dmitriy) has started 
 implementation but I believe they're interested. Right now Dmitriy is focused 
 on the prollyfill and spec.
 
 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: Binary Data types in window context (was Some Typed Objects Confusion)

2013-08-21 Thread David Herman
The intention has always been for them to be in a module. I'll make that 
clearer on the wiki.

Dave

On Aug 21, 2013, at 10:42 AM, K. Gadd k...@luminance.org wrote:

 moving back onto list
 
 It might be worth doing. On the one hand, I don't really feel like these 
 names *should* collide with anything, but it seems like the risk is kinda 
 high... and it's a little weird seeing them in global scope and having to 
 figure out that they're actually types for binary data and not, for example, 
 the constructor for boolean or some sort of value type ctor.
 
 Once 64-bit signed/unsigned ints are in will there be two names for those as 
 well? I.e. Uint64(...) produces one of the new 64-bit unsigned ints, while 
 uint64 is the name you use when creating a StructType to specify the type of 
 a field?
 
 If the type names used by binary data actually work as constructors to get an 
 instance of that type, that might make it more justified for the names to be 
 in global scope, but that seems like probably unmerited scope creep.
 
 Having the types be in a single 'BinaryTypes' namespace or something at 
 window-level seems like it would be pretty reasonable; if you're going to be 
 referring to types a lot you can pull them into locals, or use 'with' in a 
 gross non-strict function (yuck yuck yuck)
 
 I assume specifying type names as strings, i.e. { field: uint32 } was 
 considered and ruled out (it would definitely be strange to mix that with 
 passing in actual StructType instances).
 
 -kg
 
 On Wed, Aug 21, 2013 at 10:36 AM, Dmitry Lomov dslo...@chromium.org wrote:
 On Wed, Aug 21, 2013 at 6:50 PM, K. Gadd k...@luminance.org wrote:
 Does this mean the addition of binary data to a browser defines dozens of new 
 names in 'window' scope, like 'string' and 'boolean' and 'uint32' alongside 
 existing names? That's kind of surprising to me (though I can understand why 
 it might be necessary)
 
 Yes, this is where we are at now.
 Maybe we should pack the whole thing into a module.
 
 Dmitry
  
 
 
 On Wed, Aug 21, 2013 at 4:21 AM, Dmitry Lomov dslo...@chromium.org wrote:
 string, boolean, object and any are all lowercase (we should fix the wiki)
 
 FWIW, I am already working on a new version of polyfill. It is fully ES5.
 Here is a pull request: https://github.com/dherman/structs.js/pull/12 - I'll 
 merge it soon, and work more to cover everything in the proposal.
 
 Thanks,
 Dmitry
 
 
 
 On Wed, Aug 21, 2013 at 3:21 AM, Andrea Giammarchi 
 andrea.giammar...@gmail.com wrote:
 sorry, point 3 was actually the question about point 2
 
 
 On Tue, Aug 20, 2013 at 6:20 PM, Andrea Giammarchi 
 andrea.giammar...@gmail.com wrote:
 Uhm, just a couple of extra question about that page if/when you have time:
   • string and boolean are mentioned, but nowhere in your `struct.js` 
 prolyfill code. Will string and boolean be accepted?
   • `Object` and `Any` are mentioned, but exported as object and any in 
 your `struct.js` prolyfill example. W
   • Which is the right way?
 The reason I am asking is to be able to create code that does absolutely 
 nothing (for performance reason) but will look like the real thing so I can 
 start experimenting with static structures and possibly a develop VS 
 production version of an ES3 to ES5 compatible polyfill since I believe your 
 code won't run anywhere except in SpiderMonkey (which is OK but it's not 
 suitable for a lightweight migration to structure like logic)
 
 Thanks.
 
 
 On Tue, Aug 20, 2013 at 4:55 PM, Andrea Giammarchi 
 andrea.giammar...@gmail.com wrote:
 Awesome, thanks!
 
 
 On Tue, Aug 20, 2013 at 4:12 PM, David Herman dher...@mozilla.com wrote:
 On Aug 20, 2013, at 1:31 PM, Andrea Giammarchi andrea.giammar...@gmail.com 
 wrote:
 
  [In this 
  page](http://wiki.ecmascript.org/doku.php?id=harmony:typed_objects), and in 
  the latest meeting note too, I can read both uint8 and Uint8, as example.
 
 Bug. Fixed, thanks.
 
  **The Question**
  How is `new StructType({x:Uint32, y:Uint32})` supposes to understand the 
  type? `instanceof Uint32` or `typeof v === uint32` or ... both in case of 
  `boolean` and `string` ?
 
 Neither. It tells you that the x and y fields have typeof 'number' and that 
 their values are constrained to be integers in the range [0, 2^32).
 
  A bonus question would be: does anybody know when this stuff is planned to 
  go out? Not a single beta/alpha channel is exposing anything at all so far.
 
 Nikhil Marathe and Niko Matsakis are actively working on the implementation 
 for SpiderMonkey:
 
 https://bugzilla.mozilla.org/show_bug.cgi?id=578700
 
 Dmitriy Lomov is actively working on updating the prollyfill to match the 
 current API:
 
 https://github.com/dherman/structs.js
 https://github.com/dherman/structs.js/pull/12
 
 Not sure if anyone on the V8 team (which includes Dmitriy) has started 
 implementation but I believe they're interested. Right now Dmitriy is focused 
 on the prollyfill and spec.
 
 Dave

Re: Binary Data types in window context (was Some Typed Objects Confusion)

2013-08-21 Thread David Herman
If necessary, i.e. if people want to release it before modules, we can make it 
available in a single top-level object, but I would not at all favor dumping 
everything onto the global scope.

Dave

On Aug 21, 2013, at 12:07 PM, David Herman dher...@mozilla.com wrote:

 The intention has always been for them to be in a module. I'll make that 
 clearer on the wiki.
 
 Dave
 
 On Aug 21, 2013, at 10:42 AM, K. Gadd k...@luminance.org wrote:
 
 moving back onto list
 
 It might be worth doing. On the one hand, I don't really feel like these 
 names *should* collide with anything, but it seems like the risk is kinda 
 high... and it's a little weird seeing them in global scope and having to 
 figure out that they're actually types for binary data and not, for example, 
 the constructor for boolean or some sort of value type ctor.
 
 Once 64-bit signed/unsigned ints are in will there be two names for those as 
 well? I.e. Uint64(...) produces one of the new 64-bit unsigned ints, while 
 uint64 is the name you use when creating a StructType to specify the type of 
 a field?
 
 If the type names used by binary data actually work as constructors to get 
 an instance of that type, that might make it more justified for the names to 
 be in global scope, but that seems like probably unmerited scope creep.
 
 Having the types be in a single 'BinaryTypes' namespace or something at 
 window-level seems like it would be pretty reasonable; if you're going to be 
 referring to types a lot you can pull them into locals, or use 'with' in a 
 gross non-strict function (yuck yuck yuck)
 
 I assume specifying type names as strings, i.e. { field: uint32 } was 
 considered and ruled out (it would definitely be strange to mix that with 
 passing in actual StructType instances).
 
 -kg
 
 On Wed, Aug 21, 2013 at 10:36 AM, Dmitry Lomov dslo...@chromium.org wrote:
 On Wed, Aug 21, 2013 at 6:50 PM, K. Gadd k...@luminance.org wrote:
 Does this mean the addition of binary data to a browser defines dozens of 
 new names in 'window' scope, like 'string' and 'boolean' and 'uint32' 
 alongside existing names? That's kind of surprising to me (though I can 
 understand why it might be necessary)
 
 Yes, this is where we are at now.
 Maybe we should pack the whole thing into a module.
 
 Dmitry
 
 
 
 On Wed, Aug 21, 2013 at 4:21 AM, Dmitry Lomov dslo...@chromium.org wrote:
 string, boolean, object and any are all lowercase (we should fix the wiki)
 
 FWIW, I am already working on a new version of polyfill. It is fully ES5.
 Here is a pull request: https://github.com/dherman/structs.js/pull/12 - I'll 
 merge it soon, and work more to cover everything in the proposal.
 
 Thanks,
 Dmitry
 
 
 
 On Wed, Aug 21, 2013 at 3:21 AM, Andrea Giammarchi 
 andrea.giammar...@gmail.com wrote:
 sorry, point 3 was actually the question about point 2
 
 
 On Tue, Aug 20, 2013 at 6:20 PM, Andrea Giammarchi 
 andrea.giammar...@gmail.com wrote:
 Uhm, just a couple of extra question about that page if/when you have time:
  • string and boolean are mentioned, but nowhere in your `struct.js` 
 prolyfill code. Will string and boolean be accepted?
  • `Object` and `Any` are mentioned, but exported as object and any in 
 your `struct.js` prolyfill example. W
  • Which is the right way?
 The reason I am asking is to be able to create code that does absolutely 
 nothing (for performance reason) but will look like the real thing so I can 
 start experimenting with static structures and possibly a develop VS 
 production version of an ES3 to ES5 compatible polyfill since I believe your 
 code won't run anywhere except in SpiderMonkey (which is OK but it's not 
 suitable for a lightweight migration to structure like logic)
 
 Thanks.
 
 
 On Tue, Aug 20, 2013 at 4:55 PM, Andrea Giammarchi 
 andrea.giammar...@gmail.com wrote:
 Awesome, thanks!
 
 
 On Tue, Aug 20, 2013 at 4:12 PM, David Herman dher...@mozilla.com wrote:
 On Aug 20, 2013, at 1:31 PM, Andrea Giammarchi andrea.giammar...@gmail.com 
 wrote:
 
 [In this 
 page](http://wiki.ecmascript.org/doku.php?id=harmony:typed_objects), and in 
 the latest meeting note too, I can read both uint8 and Uint8, as example.
 
 Bug. Fixed, thanks.
 
 **The Question**
 How is `new StructType({x:Uint32, y:Uint32})` supposes to understand the 
 type? `instanceof Uint32` or `typeof v === uint32` or ... both in case of 
 `boolean` and `string` ?
 
 Neither. It tells you that the x and y fields have typeof 'number' and that 
 their values are constrained to be integers in the range [0, 2^32).
 
 A bonus question would be: does anybody know when this stuff is planned to 
 go out? Not a single beta/alpha channel is exposing anything at all so far.
 
 Nikhil Marathe and Niko Matsakis are actively working on the implementation 
 for SpiderMonkey:
 
https://bugzilla.mozilla.org/show_bug.cgi?id=578700
 
 Dmitriy Lomov is actively working on updating the prollyfill to match the 
 current API:
 
https://github.com/dherman

Re: Binary Data types in window context (was Some Typed Objects Confusion)

2013-08-21 Thread David Herman
On Aug 21, 2013, at 12:49 PM, Dmitry Lomov dslo...@chromium.org wrote:

 I really hope that uint64 from value type spec and uint64 from typed object 
 spec are one and same thing (we now in typed objects spec allow using 
 uint8/uint16/.. co to be used as conversion functions).

Agreed, and my feeling is that for now we should leave them out. They can be 
added to the API once the value type exists.

Dave

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


Re: Some Typed Objects Confusion

2013-08-21 Thread David Herman
On Aug 21, 2013, at 2:36 PM, Brendan Eich bren...@mozilla.com wrote:

 David Herman wrote:
 Any, String and Object should still be uppercase. The naming convention is: 
 value types lowercase, reference types uppercase.
 
 Is String really a reference type? Currently you can't tell, and JS docs and 
 books don't (AFAIK) say reference type apart from object (not null; 
 including function). String also happens to spell the constructor/converter 
 function, which sadly both returns a primitive and creates a String object 
 depending on how it is called.

You can tell, in that a type that includes String must be opaque. The 
might-be-a-pointer property of a type is observable in the typed objects API in 
that it cannot expose its backing storage as an ArrayBuffer. Strings 
necessarily might-be-a-pointer.

I take your point that it's confusing on the primitive/object axis, though.

So... all right, let's break out those paintbrushes. Let's say we use the 
lowercase naming convention for purely immutable types, independent of whether 
they might-be-a-pointer. This still leaves Dmitry's question about the 
unfortunate name collision -- even though modules make this okay, it's still 
a PITA in practice not to be able to import Object without shadowing the 
built-in Object.

Personally I'd be fine with just lowercasing all the things. Brendan, you cared 
about using capitalization for object types, though. What color is your 
bikeshed?

Dave

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


Re: Keywords as method names

2013-08-21 Thread David Herman
In Lisp it makes sense to allow binding keywords because there's no such thing 
as a keyword: once you bind it, it's a variable and you can refer to it. In JS 
it's impossible to refer to it as a variable so it's just an (un)attractive 
nuisance.

The only place where I could see this being arguably useful in ES6 is:

// foo.js
export function function() { }

// main.js
module foo from foo;

foo.function();

But that's still probably not advisable, since it means you can't import the 
name:

import { function } from foo;
// d'oh

So I don't see any reason why a person shouldn't just use rebinding for that 
use case:

// foo.js
function function_() { }

export { function_ as function };

To wit: I say leave it out.

Dave

On Aug 21, 2013, at 4:13 PM, Jason Orendorff jason.orendo...@gmail.com wrote:

 The ES6 draft says:
 
MethodDefinition : PropertyName ( StrictFormalParameters ) { FunctionBody }
PropertyName : IdentifierName
 
 This means a method name can be a keyword: `obj = {if() {}}`. This is
 consistent with other property names (`{if: true}` is allowed), but
 inconsistent with other function names (`function if(){}` is not
 allowed).
 
 Why not allow keywords as function names, too?
 
 -j
 ___
 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: Some Typed Objects Confusion

2013-08-20 Thread David Herman
On Aug 20, 2013, at 1:31 PM, Andrea Giammarchi andrea.giammar...@gmail.com 
wrote:

 [In this page](http://wiki.ecmascript.org/doku.php?id=harmony:typed_objects), 
 and in the latest meeting note too, I can read both uint8 and Uint8, as 
 example.

Bug. Fixed, thanks.

 **The Question**
 How is `new StructType({x:Uint32, y:Uint32})` supposes to understand the 
 type? `instanceof Uint32` or `typeof v === uint32` or ... both in case of 
 `boolean` and `string` ?

Neither. It tells you that the x and y fields have typeof 'number' and that 
their values are constrained to be integers in the range [0, 2^32).

 A bonus question would be: does anybody know when this stuff is planned to go 
 out? Not a single beta/alpha channel is exposing anything at all so far.

Nikhil Marathe and Niko Matsakis are actively working on the implementation for 
SpiderMonkey:

https://bugzilla.mozilla.org/show_bug.cgi?id=578700

Dmitriy Lomov is actively working on updating the prollyfill to match the 
current API:

https://github.com/dherman/structs.js
https://github.com/dherman/structs.js/pull/12

Not sure if anyone on the V8 team (which includes Dmitriy) has started 
implementation but I believe they're interested. Right now Dmitriy is focused 
on the prollyfill and spec.

Dave

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


Re: Refutable destructuring

2013-08-15 Thread David Herman
On Aug 14, 2013, at 9:54 AM, Dmitry Soshnikov dmitry.soshni...@gmail.com 
wrote:

 throws
 
 to bind to undefined you would say:
 
 var {p=undefined} = {};
 
 
 OK, so it's turned out to be refutable nevertheless.

This is *not* what I remember of the conversation, at all.

My understanding was that pretty much everyone in the room, at least those who 
participated in the conversation, felt that refutable destructuring was a 
mistake, but that we couldn't really come to any conclusions without Brendan 
and Andreas there, since the two of them had championed refutable destructuring.

IOW, we don't have consensus about this issue.

Dave

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


Re: Refutable destructuring

2013-08-15 Thread David Herman
On Aug 15, 2013, at 9:27 PM, David Herman dher...@mozilla.com wrote:

 we couldn't really come to any conclusions without Brendan and Andreas there

My mistake, Brendan was there. It was only Andreas who wasn't there.

Dave

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


Re: setImmediate

2013-08-12 Thread David Herman
On Aug 8, 2013, at 7:09 AM, Anne van Kesteren ann...@annevk.nl wrote:

 On Thu, Aug 8, 2013 at 3:03 PM, Domenic Denicola
 dome...@domenicdenicola.com wrote:
 To me the answer always seemed obvious: use the slow-script dialog. What am 
 I missing?
 
 That seems like a bad answer. Slow-script dialogs are a misfeature.
 They only exist because otherwise single-threaded browsers would be in
 a world of hurt.

Wait, what? The semantics of the web demands that runaway JS block any other 
even turns, or page layout/rendering from proceeding. Multi-process browsers 
can prevent cross-origin pages from interfering with each other, and Servo can 
do speculative layout to reward well-behaved pages, but badly-behaved pages 
unavoidably destroy the UX. Maybe I'm unimaginative but the only alternative to 
the slow-script dialog I can see is to allow a page to completely destroy 
itself unrecoverably.

Dave

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


Re: setImmediate

2013-08-12 Thread David Herman
On Aug 8, 2013, at 2:08 PM, K. Gadd k...@luminance.org wrote:

 Why is the slow script dialog box even relevant for setImmediate? As I 
 understand it, setImmediate is equivalent to DoEvents in Visual Basic/Windows 
 Forms and pumping the message loop in a normal C application. That is, you 
 can use setImmediate to make your application run as fast as possible while 
 still allowing the browser to pump messages, which ensures keyboard/mouse 
 inputs are processed and the window does not get flagged as unresponsive.

Yeah, I'm actually not at all clear which of (at least?) four plausible 
semantics could be meant by setImmediate:

(a) push a new microtask (to the front of the current microtask list)
(b) enqueue a new microtask (to the back of the current microtask list)
(c) push a new event (to the front of the event queue)
(d) enqueue a new event (to the back of the event queue)

I'd always assumed it meant (d), which seems to me it's what setTimeout(.., 0) 
really wanted to be. If people want something for scheduling microtasks I'd 
think they would still want something for scheduling events.

For the record, my opinions on this whole space are:

- I'm pretty sure we have to leave implementations free to throttle event 
queues, but current competitive pressure over performance would ensure that a 
new API would not be as heavily throttled as setTimeout 0.
- Microtasks should not be throttled since they block the event queue.
- Microtasks should be treated the same as ordinary synchronous code.
- I see *no* reasonable alternative to runaway microtask churn other than 
slow-script dialog.

(Opinions subject to revision yadda yadda yadda.)

Dave

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


Re: Modules: do re-exports also import?

2013-08-12 Thread David Herman
On Aug 4, 2013, at 8:01 AM, Axel Rauschmayer a...@rauschma.de wrote:

 My guess: if you re-export something from a module, then you still have to 
 import it if you want to use it in that module. Is that correct?

Correct.

 Examples of re-exporting:
 
 export * from crypto;// re-exporting another 
 module's exports
 export { foo, bar } from crypto; // re-exporting specified 
 exports from another module
 
 That seems redundant. Maybe one could mark things that should be re-exported 
 when importing them? On the other hand, this may be rare enough that it 
 doesn’t warrant the extra syntax.

Not worth it. We can consider more conveniences post-ES6 but I doubt even then 
this particular one would be worth it.

Dave

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


Re: setImmediate

2013-08-12 Thread David Herman
On Aug 12, 2013, at 5:40 PM, François REMY francois.remy@outlook.com 
wrote:

 I don't think of you as unimaginative, but I think there are other options.

:)

 Sure, there must be a way to kill a script that's burning your CPU but it 
 doesn't have to be a dialog.

That's fine, I guess I didn't really mean dialog box was the only UI, just that 
killing the JS entirely is the only reasonable semantics I can imagine.

 Firstly, there's nothing really preventing a browser to perform a layout if 
 it actually pauses the script, even if it may be hard to pause a thread while 
 keeping all its pointer safe in an environment that's changed by another 
 thread. But this is not impossible.

Not impossible to implement, but very bad. It would create new preemption 
semantics to shared state in JS, which is mst of the time trying very hard 
to be strictly based on cooperative concurrency. Not only would injecting this 
preemption be a new potential source of very subtle bugs, it could be a 
security problem (run some slow script to force a new layout and use that as a 
bogus communication channel).

 Secondly, when a website becomes resource-intensive, you can display a 
 toolbar saying 'This website looks to overuse your computer.' with a (stop 
 the script) button that doesn't interrupt your experience (you can switch tab 
 if you want, which will in return cause the tab to get way less system 
 resources since he's in the background) or continue to use the website if it 
 turns out it's just slow but not stuck in an infinite loop.

Sure-- again, playing with the UI isn't really what I meant. It's that 
semantically I see no alternative to a slow script but killing JS.

Dave


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


microtask timeouts (was Re: setImmediate)

2013-08-12 Thread David Herman
On Aug 12, 2013, at 5:43 PM, David Bruant bruan...@gmail.com wrote:

 - I see *no* reasonable alternative to runaway microtask churn other than 
 slow-script dialog.
 So did Dominic [1]. I suggested something else [2] and he found the idea 
 interesting. What do you think?

Quoting you from

 [2] https://mail.mozilla.org/pipermail/es-discuss/2013-August/032630.html

you said:

 Maybe implementations could decide to break a microtask chain, but 
 instead of prompting a dialog, they just break it and call a callback 
 (later, in a different task, not microtask) so that the script knows and 
 can try to recover.

It is an interesting idea, I missed it the first time around; you might 
describe it as an asynchronous TimeoutException. I'm thinking about it, but I'm 
pretty skeptical. It's still effectively preemption semantics. At any 
nondeterministic (and not portably defined) point, your code can simply be 
stopped. It's not even clear what the atomicity guarantees would be around 
valid preemption points in the semantics. For example, can you preempt code 
halfway through the modification of a 64-bit word? Can you preempt code that 
hasn't spilled its registers back to memory? Am I scaring you yet? ;-)

Even if we could provide a fully well-specified definition for concurrent 
interruption, I really have no idea how code could ever realistically recover 
from such an event. The only thing the system tells you is at some point in 
some turn we just stopped you from whatever you were doing, and now you're 
expected to reconstruct your state. This reminds me of exception safety in C++.

Dave

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


Re: microtask timeouts (was Re: setImmediate)

2013-08-12 Thread David Herman
On Aug 12, 2013, at 6:32 PM, David Bruant bruan...@gmail.com wrote:

 How do people recover today from when the user click stop script?

They don't; it's a crash -- the web equivalent of this application has stopped 
responding. You might as well ask for a solution to the halting problem! :)

Dave

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


Re: Module syntax

2013-06-06 Thread David Herman
On Jun 5, 2013, at 3:59 PM, Axel Rauschmayer a...@rauschma.de wrote:

 This makes a lot of sense. It would obviate the need for braces, right?

No, at least not for imports. This is only about exports. I'd argue we should 
keep the braces on export { x, y, z } for symmetry with imports.

Dave

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


Re: Module syntax

2013-06-06 Thread David Herman
On Jun 6, 2013, at 11:05 AM, Axel Rauschmayer a...@rauschma.de wrote:

 OK, so you don’t want to replace
 
 import foo from single_export_module;
 
 with (braceless!)
 
 import default as foo from single_export_module;

That's correct, I don't want to use `import default`.

Dave

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


Re: Module syntax

2013-06-05 Thread David Herman
On Jun 5, 2013, at 11:51 AM, Kevin Smith zenpars...@gmail.com wrote:

 It occurs to me that this is valid under the current grammar:
 
 import { default as foo } from foo;
 export { foo as default };
 
 We've discussed using a well-known symbol for the default export, but this 
 simple desugaring might be another option:
 
 import foo as foo; 
 // = import { default as foo } from foo;
 
 export default = expr; 
 // = let __genident__ = expr; export { __genident__ as default };
 
 This would provide easy access to the default export on a module instance 
 object without having to obtain a reference to a symbol.
 
 module Foo from foo;
 F.default();
 
 Just throwing an idea out...

Yes, this is actually the direction I've been going in my thinking, based on 
the critique that export default is the only export form that isn't a binding 
form, especially when combined with a named function literal (`export default 
function f() { ... }`). I also like the conceptual simplicity of the default 
export simply being a public export named default. Moreover, Yehuda has urged 
me to consider

export x = 17;

as sugar for

export let x = 17;

When you put this all together, you can actually just see `export default = 
...` as sugar for `export let default = ...`. We can also allow the keyword 
`default` to be used for the other exported declaration forms like `export 
function default(...) { ... }` and `export class default { ... }`. (We'll 
finesse the .name property of such a declared function to be taken from the 
module name, a la Brandon's accepted proposal for .name in ES6.) To recap, the 
following all become valid ways to specify the default export:

export let default = 17;
export default = 17;
export default = function f() { ... };
export default = class { ... };
export function default(...) { ... }
export class default { ... }

And you can now import both the default and non-default exports of a module in 
a single line:

import { default as $, ajax } from jquery;

Dave

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


Re: Minor questions on new module BNF

2013-06-04 Thread David Herman
On Jun 4, 2013, at 6:31 AM, Kevin Smith zenpars...@gmail.com wrote:

 Looks good, but I'm thinking that this should probably _not_ be allowed:
 
 import {,} from x;

Right you are! Fixed, thanks.

Dave

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


Re: Module syntax

2013-06-03 Thread David Herman
On Jun 3, 2013, at 1:55 PM, Juan Ignacio Dopazo dopazo.j...@gmail.com wrote:

 Now that it's been decided that braces are not a form of destructuring and 
 the colon replaced with `as`, what's the benefit of using braces? Why not 
 this previous proposal?
 
 import foo as foofoo from foo;
 
 import bar as bar;

Because it's ambiguous with default import; without curly braces, a single 
named import, without the as renaming, would have indistinguishable syntax 
from importing the default export.

Dave

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


Re: Module syntax

2013-06-03 Thread David Herman
On Jun 3, 2013, at 10:29 AM, Axel Rauschmayer a...@rauschma.de wrote:

 Bikeshedding:

Well, here comes a fun thread...

 Rationale:
 – Reducing the grawlix factor.
 – Making non-default imports more convenient – which I assume will happen 
 more often(?)

That's what this comes down to: do you expect the common case to be small 
modules with a main export, or large modules with many named exports. We opted 
for the former, since there are many prominent libraries and communities in the 
JS world that have gravitated towards small modules. That said, the extra 
burden of two curly braces is very, very small.

Dave

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


Re: Minor questions on new module BNF

2013-06-03 Thread David Herman
On Jun 3, 2013, at 9:33 AM, Yehuda Katz wyc...@gmail.com wrote:

 On Mon, Jun 3, 2013 at 12:24 AM, Domenic Denicola 
 dome...@domenicdenicola.com wrote:
 From: sam...@gmail.com [mailto:sam...@gmail.com] On Behalf Of Sam 
 Tobin-Hochstadt
 
  I would just write `import {} from someModule;`
 
 That appears to be disallowed; I believe
 
 { ImportSpecifier (, ImportSpecifier)* ,? }
 
 requires at least one `ImportSpecifier`.

Oversight. Fixed.

 (It's also sad and ugly; any reason not to allow `import someModule;`?)
 
 I've advocated for this in the past. I believe it should be allowed.

I've always liked this too, and just hadn't really gotten to it. But I've added 
it to the wiki page too. I'll work with Jason to add this to the reference 
library; it should be a small addition.

 Separately, I would like this form to be specified as deferring execution 
 until bindings are explicitly imported (from another module), or a 
 synchronous `System.get` call is made.
 
 This would make it possible to guarantee that a synchronous `System.get` will 
 succeed, without being forced to execute the module first.

Yep, agreed. (To be pedantic, it's not that it defers execution so much as that 
it doesn't force execution.)

Dave

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


Re: Minor questions on new module BNF

2013-06-03 Thread David Herman
On Jun 3, 2013, at 12:24 AM, Domenic Denicola dome...@domenicdenicola.com 
wrote:

 Ah, that makes sense! It's a nice way of prohibiting `scriptexport function 
 foo() { }/script` as well, assuming inline `script` corresponds to 
 `Script`. It would be helpful to update the wiki with this, or more generally 
 to show how this grammar will integrate with the rest of the grammar.

I added a note at the end of the grammar section. Do you think that helps make 
it a little clearer?

Thanks,
Dave

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


Re: Module naming and declarations

2013-05-20 Thread David Herman
On May 9, 2013, at 6:30 AM, Andreas Rossberg rossb...@google.com wrote:

 In your scheme, I honestly cannot tell. Which ones are absolute
 logical module names, which ones are relative logical module names,
 and which ones are relative URLs?

I realized I left this sub-thread hanging. While I think you've overstated your 
argument in several places, I do recognize that combining URL's and module 
names that look like paths into one syntactic space is confusing.

But really, there was no real need for loading directly from a URL in the first 
place, since it's better practice to use an abstract name and configure it to 
the URL you want anyway. (If people really want the additional convenience they 
can configure the loader to accept URL's.)

So the right resolution for this question is: the browser loader recognizes 
logical modules names only. No URI's, no URL's, just logical module name paths. 
If a particular module name needs to be loaded from a remote URL, you can use 
the ondemand configuration to map the logical name (jquery) to the URL 
(http://code.jquery.com/jquery-1.9.1.min.js;).

Dave

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


Re: Module naming and declarations

2013-05-18 Thread David Herman
On May 15, 2013, at 10:42 AM, Andreas Rossberg rossb...@google.com wrote:

 (1) Change the set-up of .ondemand calls.
 (2) Change the invocation of your bundling tool.
 
 As soon as you have to go there, you've lost almost all advantages of
 the ID-based declaration form. Its assumed convenience doesn't scale
 to non-trivial scenarios.

No. You've missed the point. Configuration code is not the problem; there's at 
most a 1:1 relationship between modules and their configuration.

There is a 1:many relationship between a module and import declarations that 
refer to it. This is what matters: even if you reconfigure the app to change 
the way the module is shipped, every client module's import declaration should 
remain the same. This may include repackaging, file renaming, switching between 
CDN's, switching between versions, etc.

 I do realise now, however, that it gets uglier when an import triggers
 _multiple_ ondemand scripts at once, because then their execution
 would have to be sequentialized.

That's exactly what I meant. If you have to sequentialize the execution of the 
transitive *package* dependency graph, then you over-sequentialize the fetching 
of the transitive *module* dependency graph.

 When is the script body
 executed? And what effect do updates to the loader during execution of
 that script have?

The execution semantics goes roughly like this: once all the module 
dependencies are computed and fetched, the linking process begins. If there are 
no module-factories (i.e., the AMD-style modules that require their 
dependencies to have been executed before they can compute their exports), 
linking is observably atomic. Then the bodies (script bodies and any as-yet 
unexecuted module bodies that have any clients importing from them) are 
executed sequentially. If, however, there are module-factories, the process is 
more interleaved: the system atomically links all declarative modules 
transitively required by each module factory, then executes those declarative 
modules, then executes the module factory, rinse, repeat.

When linking is atomic, loader updates don't matter. When the interleaving 
happens, loader updates can affect future linkage. It's not a good idea to be 
mucking the loader in the middle of initializing modules. It's better to place 
it at the very beginning of an application, before any importing starts 
happening.

 - intra-package module references should be internal and fixed,

You keep making this claim as if there's some black-and-white distinction. When 
we pointed out that your intra-package references are not tamper-proof given 
the translate hook, you said well but in practice... So, that argument cuts 
both ways. In practice, intra-package references will not be messed with 
externally. They are only hookable at compile-time; once runtime starts they 
are completely hard-bound. And if there are any collisions, there will be a 
compile-time error anyway. This is a tempest in a teapot.

 - implement the package in multiple files via some extension to ECMAScript 
 (e.g., include) that requires a tool to assemble it back together in a 
 single file with only lexical modules.
 
 Why would that require an extension? Import from URL is just fine for
 that purpose. And when you deploy, you run the tool, see above.

It requires non-standard semantics if you want to allow cyclic module 
dependencies, and probably also if you want to preserve the same execution 
semantics as lexical modules.

 Counter question: what other options are available in the current
 design, under your no-tool and no-staging assumption? AFAICS, you can
 do either of the following:
 
 - Write script files with module declarations...
 
 - Write module files...

I never said staging is bad, I said the staging in your solution is broken: it 
over-sequentialize the fetching of resources.

The requirement I'm talking about -- which is absolutely critical for the 
practicality and adoption of ES6 modules -- is that the system has to work well 
out of the box without tools. And the current system does. The only thing you 
have to change if you decide to repackage modules into scripts is a *single* 
piece of code staged before application loading that configures the locations 
of the modules. Note that this is how require.js works.

 I don't envision many people would want ever to use the first option...
 And the other option requires tool support.

That's simply not true. Look at require.js:

http://requirejs.org/docs/api.html#config

With even just a reasonably convenient ondemand, you can easily move some or 
all of your modules into scripts by hand. Even without ondemand, the resolve 
hook is straightforward. (BTW I hate the name `ondemand`; it'll get renamed to 
something more declarative-sounding, like AMD's `paths`.)

Your suggestions would result in a system that is unusable without tools. 
That's not acceptable and it's not going to happen.

Dave


Re: yield* desugaring

2013-05-13 Thread David Herman
On May 13, 2013, at 10:51 AM, Andy Wingo wi...@igalia.com wrote:

 If I'm implementing an iterator via a generator and I have to perform
 a inner-iteration over an contained iterable (for example, some sort
 of flattening operation) the way I code that inner iteration shouldn't
 depend upon whether or not the implementor of the inner iterable chose
 to use a generator rather than a stateful object as the iterator.
 
 +1

Agree with the goal, as long as we can sensible achieve it.

 First why do we need send at all.  Why not simply allow an argument to
 be passed to next (of course, it is already allowed) and leave it up
 to the generator implementation as to whether or not they pay any
 attention to it.
 
 +1

I'm fine with that; also fine with Andreas's resume name, which would help 
with learnability if nothing else. (I have found I've had the most success 
introducing beginners to generator functions by describing them as being like 
regular functions that you can pause.) Of course, the next name is more 
appropriate for the for-of use case. (I'm laying down my bikeshed brush on this 
one.)

 That leaves only throw as an issue.  Personally, I'd just make it part
 of the Iterator interface and provide an Iterator abstract class that
 provides
   throw(exception) {throw exception}
 as the default throw implementation so most iterator authors don't
 even have to think about it.
 
 +1

I lmost agree. I want to agree. But part of the importance of the 
structural type is that you don't have to use subclassing. You can't mixin 
this default throw-through behavior with a base class. We could, of course, 
offer a mixin function:

iterator({ next: ... })

But that sucks given that we expect most iterators will want the default 
behavior. Alternatively, we could make the .throw method optional and have it 
automatically throw-through. I was worried at first that that might be creepy, 
but really it's kind of sensible. It's an optional iterator method for the MOP 
that has a sensible default behavior.

Dave

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


Re: yield* desugaring

2013-05-13 Thread David Herman
On May 13, 2013, at 11:07 AM, Allen Wirfs-Brock al...@wirfs-brock.com wrote:

 It closes down this whole edge-case focused discussion and that's valuable in 
 itself.  Also, since it turns try {yield expr} finally{} into a syntax error  
 we could revisit the decision in a future edition if somebody actually comes 
 up with compelling use cases.

I'm very uncomfortable with this restriction. Ad hoc restrictions break 
compositionality. They come back to bite you because you broke generality for 
want of use cases, when we all know we can't predict all the use cases of a 
general-purpose programming mechanism. This gets our responsibility backwards: 
ad hoc restrictions that break generality should be extremely strongly 
motivated, rather than requiring use cases for the semantics they disallow.

Meanwhile this point:

 It's all about finally which up to now has been a strong guarantee.

is wrong. (I've explained this in past meetings, I think at an Apple meeting a 
year or two ago.) The guarantee of finally does *not* provide a *strong* 
(total) guarantee, it provides a guarantee of the partial correctness flavor:


If control reaches the end of the execution of the try block, either by 
normal completion or abrupt completion, then execute the finally block before 
proceeding.


A good intuition (and an equivalence that we should strive to preserve) is that 
`yield` is acting like a function call to the main continuation, which can 
choose to return back to the generator or not. This is just the same as if you 
write:

function infiniteLoop() { while (true); }

try {
infiniteLoop();
} finally {
console.log(and now we are done);
}

We don't guarantee anything about execution of finally blocks if control never 
reaches the end of their try blocks.

Dave

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


Re: Module naming and declarations

2013-05-13 Thread David Herman
On May 10, 2013, at 7:18 AM, Andreas Rossberg rossb...@google.com wrote:

 Can you explain how one form of module declaration is easier to move
 around? In a single script there surely is no difference.

Clients of a module can write:

import { f } from foo;

and regardless of how the module foo is shipped -- in a separate file or with 
an explicit module declaration in a bundled file -- the client code is 
unperturbed. This means that a single package can easily be deployed with any 
number of files without affecting client code.

 OK, perhaps I am under wrong assumptions about the semantics of
 ondemand. I assumed that when you first import a module that has been
 registered via ondemand, the respective script will be executed,
 recursively, and then linking of the outer script continues, taking
 the updated loader environment into account.

OK, this is a big difference between your imagined system and the current one. 
The current system does not execute modules until dependencies have been 
fetched and linked -- I explained this in the March meeting. (The .ondemand 
method is sort of a distraction; it's nothing more than an API convenience 
layered upon the underlying resolution hook.) This means that cyclic 
dependencies work, and dependencies are resolved statically across multiple 
files, causing a full static dependency graph to be concurrently fetched.

What you describe has a sharp distinction between packages and modules, where 
packages cannot have cyclic dependencies, must be dynamically loaded and 
registered, and are composed only of lexically scoped modules. What this seems 
to mean is, to implement a package (such as a library, application, or 
component of an application), you have to choose from one of three options:

- implement the package in one big file.
- implement the package in multiple files via some extension to ECMAScript 
(e.g., include) that requires a tool to assemble it back together in a single 
file with only lexical modules.
- split the package into smaller packages, each comprising only one or at least 
very few modules, forgo any cyclic dependencies, and effectively get little to 
no benefit from lexical modules.

Please do tell me if I'm missing something, because all of the above scenarios 
seem obviously impractical. In particular, it's a necessity that the system 
should work well out of the box, with no additional tools. Obviously large and 
sophisticated applications will be willing to buy into additional 
infrastructure, but you should certainly be able to put a package's modules in 
separate files without build tools.

Dave

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


Re: yield* desugaring

2013-05-13 Thread David Herman
On May 13, 2013, at 6:11 PM, Brendan Eich bren...@mozilla.com wrote:

 We've been over this at least twice. Let's get it right. No close, yield in 
 try-with-finally ok.

+1

 Merge next and send by letting next take an optional parameter? Ok by me.

+1

 Make yield* work on any {next, throw}, not necessary but ok by me too.

Yes with one delta: if there's no .throw it still works, it just defaults to 
(x) = { throw x }. This way you can write ordinary iterators without having to 
worry about providing the default throw, and they still function properly as 
generators.

Dave

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


Re: yield* desugaring

2013-05-13 Thread David Herman
On May 13, 2013, at 4:15 PM, David Herman dher...@mozilla.com wrote:

 On May 13, 2013, at 11:07 AM, Allen Wirfs-Brock al...@wirfs-brock.com wrote:
 
 It closes down this whole edge-case focused discussion and that's valuable 
 in itself.  Also, since it turns try {yield expr} finally{} into a syntax 
 error  we could revisit the decision in a future edition if somebody 
 actually comes up with compelling use cases.
 
 I'm very uncomfortable with this restriction. Ad hoc restrictions break 
 compositionality. They come back to bite you because you broke generality for 
 want of use cases, when we all know we can't predict all the use cases of a 
 general-purpose programming mechanism. This gets our responsibility 
 backwards: ad hoc restrictions that break generality should be extremely 
 strongly motivated, rather than requiring use cases for the semantics they 
 disallow.

And what was I thinking, of course there are use cases: anything where you'd 
use try/finally in a language with synchronous I/O, you would use try/finally 
in task.js.

  spawn(function*() {
let splashScreen = $(splash);
try {
  splashScreen.style.display = 'block';
  let assets = yield downloadAssets();
  // ...
} catch (e) {
  // ...
} finally {
  splashScreen.style.display = 'none';
}
  });

Dave

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


Re: Module naming and declarations

2013-05-09 Thread David Herman
On May 8, 2013, at 7:39 AM, Andreas Rossberg rossb...@google.com wrote:

 On 7 May 2013 21:17, Sam Tobin-Hochstadt sa...@ccs.neu.edu wrote:
 On Thu, May 2, 2013 at 10:47 AM, Andreas Rossberg rossb...@google.com 
 wrote:
 My point on the topic of external naming is that the language (1)
 should not prescribe any specific naming scheme; (2) should not
 willfully violate URI semantics; (3) should properly separate it from
 internal naming.
 
 (1) No naming scheme is prescribed here, unless you mean the
 semantics of relative paths
 
 Well, of course it is. You are prescribing the syntax of logical names
 in the form of module IDs. It's a very specific (and kind of
 arbitrary) choice. I'd prefer if we did not bake that into the
 language beyond saying the syntax for external module names is URIs,
 a loader can interpret that in whatever way it sees fit.

There's something I fear may be getting missed in this conversation. Maybe you 
were aware but I think it's important to clarify.

The naming policy we're talking about here is purely for the web's default 
System loader, not baked into the core language. In the core language, the 
semantics of module names is that they are strings, nothing more. The core 
semantics doesn't care what's in those strings. IOW: the syntax for module 
names is strings, a loader can interpret that in whatever way it sees fit.

Note that requiring them to be a URI would be strictly *more* of a policy.

 The point I'm making is that logical names aren't URLs, they aren't
 specified to be URLs, and thus treating them differently isn't a
 violation of the meaning of URLs.
 
 It is, if logical names (1) syntactically overlap with URI references,
 (2) are used in places where you also allow URI references, and (3)
 have a meaning different from (and incompatible with) the respective
 sublanguage of URI references. Unfortunately, your design is doing
 exactly that.

I think this is the crispest statement of your objection to the browser's 
module name syntax. I feel you are being absolutist: the syntax is simply the 
(disjoint!) union of absolute URI's and a separate production (one that happens 
to overlap with URI references, but they are simply not part of this language). 
This is perfectly well-defined. It's simply a different grammar than that of 
general URI's. It just happens to overlap in some ways.

Now, you can argue that that design is *confusing*, because the presence of 
absolute URL's might lead a user to conclude incorrectly that something that 
isn't an absolute URL has the semantics of a URI reference. I think that's a 
fair objection, as far as it goes (although I personally disagree). You are 
overreaching, however, to say that it's a violation or suggest that it's some 
sort of fundamental unsoundness.

But let's look at the options here. We're talking about a syntax that allows 
for a user to specify either a logical name or a URL. So the syntax needs to 
accommodate those two cases. I see three basic categories of alternatives:

Option 1: distinguish the cases explicitly by injecting them into a common 
super-language
  e.g.: { 'path': 'a/b/c' } and { 'url': 'http://example.com' }
  e.g.: jsp:a/b/c and http://example.com;

Option 2: distinguish the cases implicitly by exploiting their syntactic 
disjointness
  e.g.: a/b/c and http://example.com;

Option 3: distinguish the cases explicitly by *only* injecting one case into a 
syntactically disjoint wrapper
  e.g.: a/b/c and url(http://example.com)

My issue with Option 1 is that it taxes the common case of logical names with 
extra boilerplate. Littering entire programs with jsp: at the beginning of 
every module name is just a non-starter. However, I actually find something 
like the example in Option 3 pretty appealing, since it doesn't tax the common 
case, and it uses a familiar syntax from CSS. It also makes it possible to 
admit relative URL's, which seems like a win.

 In line with what I said above, string-named module declarations (if
 we need them at all) should allow arbitrary URI syntax, and not
 prescribe some specific form of logical name. It wasn't clear from
 Dave's response (or any of the design notes) whether you intend that
 to be the case or not. For symmetry, I hope you do. :)

They allow arbitrary *string* syntax, so yes, of course, you can define a 
module declaratively with a URI as its name.

(More replies to your next message in a few minutes...)

Dave

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


Re: Module naming and declarations

2013-05-09 Thread David Herman
On May 8, 2013, at 8:05 AM, Andreas Rossberg rossb...@google.com wrote:

 You seem to believe otherwise, but I think you still need to explain
 how any of the above cases is not sufficiently (or even superiorly)
 supported by lexical modules + the loader API.

The most important flaw of this is staging. The loader API lets you 
*dynamically* modify the registry, but those changes cannot be used by code 
compiled at the same time as the code that does the modification.

 In any case, I don't see how this observation necessarily implies
 _anything_ for the form of module *declarations*. I suspect that your
 thinking had very much to do with (naive) concatenation, but
 concatenation without a tool will never be possible for modules
 anyway. So it really is a totally moot point.

I think it's important not just to be able to write bundlers, but to be able to 
do the transformation in a fine-grained way. It should be possible to move 
module declarations around by hand, it should be possible for servers to make 
on-the-fly decisions about where to place module declarations, etc. And it 
should be possible to do this without greatly perturbing the shape of the 
resulting code.

Put differently, controlling where and when code is bundled together is 
something that sophisticated web applications do often and sometimes at fine 
granularity, and it's done by experts at web development who shouldn't have to 
be experts at writing compilers or reading their output. Consider Eric 
Ferraiuolo's examples of servers making decisions to speculatively bundle 
additional modules in a response to a request. These are decisions that are 
about network efficiency, and they shouldn't have to deal with code 
transformations at the same time.

 OK, let's get concrete and see how this works. Assume you are writing
 some subsystem or library. There are three phases.
 
 1. Development. Most modules will typically be in individual files,
 that you import through external names...
 
 2. Deployment. Once you're ready to release, you want to bundle
 everything into one file (concatenation). Either way, that requires
 a tool.

You don't necessarily bundle *everything* into one file. Large-scale apps may 
bundle things in various ways.

 With lexical module declarations, the tool will be similar, but
 distinguishes the set of module paths that you intend to export from
 the package. The resulting file will again contain all individual
 files wrapped into module declarations, but this time with lexical
 names (generated by some means -- the details don't matter since there
 is no intention of making them accessible; you could even wrap
 everything into an anonymous module). All import file names referring
 to non-exported modules are replaced by their lexical references. In
 addition, the tool generates a couple of suitable calls to loader.set
 for registering the exported modules. The names for those are picked
 in the same manner as in the other approach.

As I said above, this is broken. If we don't provide a declarative way to 
register modules, then they have to be added to the registry *in a different 
stage* from any code that uses them. This forces you to sequentialize the 
loading of different packages of your application, which is a non-starter.

What's more, when you start from your assumption #1 (and I do) that most 
modules will be in separate files, then lexical modules aren't buying the user 
much at all. Except for the cases where it makes sense to have small 
sub-modules that fit within a single file. As I've said before, I can imagine 
this being occasionally useful, but it's simply not important enough for ES6.

 The advantage of the latter approach is again that all intra-bundle
 references can be (1) cheap and reliable

Sounds like you're misinterpreting the semantics of static linking. I have 
clarified this several times already. References between ES6 modules are not 
dynamically indirected through a dynamic table. They are statically resolved at 
link time. Linked modules are every bit as cheap and reliable as lexical 
references.

 and (2) don't pollute the
 global namespace. At the same time, you are free to export as many of
 the modules as you like. So this approach is strictly more powerful,
 the user has control.

Except that as I explained above, without a way to register a module name 
declaratively, this forces you to load dependencies sequentially, which is 
unacceptable.

It also couples structural containment (module X is conceptually part of 
package Y) with textual containment, which is strictly less flexible for 
controlling the delivery of the source over the wire.

 3. Usage. In both approaches, the bundled file you have created
 contains a number of modules with external (logical) names. There are
 two ways to fetch them in another program: (a) either through a script
 tag, or (b) by calling loader.ondemand with the list of provided
 names. Both ways work equally for either of the designs!

Doing 

Re: yield* desugaring

2013-05-02 Thread David Herman
On May 2, 2013, at 6:25 AM, Andreas Rossberg rossb...@google.com wrote:

 On 1 May 2013 02:06, David Herman dher...@mozilla.com wrote:
 It also has a smell to it: the idea that an expression can cause a return, 
 without the syntactic appearance of `return`. (I'm not opposed to the idea 
 of being able to return from expressions -- I still love do-expressions. But 
 I prefer `return` to be a syntactically apparent control effect.)
 
 Of course, there is no need to allow 'return' or friends in
 do-expressions. In fact, I'd be opposed to that. ;)

I know, you've already stated that. This is OT.

Dave

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


  1   2   3   4   5   6   7   >