Re: non-self referencial cyclical promises?

2016-02-24 Thread Kris Kowal
With Mark’s direction, the v2 branch of Q handles "vicious cycles" through
the WeakMap that maps promises to their underlying handler. Whenever a
promise is resolved with another promise, it walks forward through the
chain of promises that the promise handler "became" through resolution. The
first promise’s initial handler is a "vicious cycle" rejected promise
handler, so if the walk forward through the resolution returns to itself,
it remains resolved to the vicious cycle.

https://github.com/kriskowal/q/blob/v2/q.js#L181-L204

On Wed, Feb 24, 2016 at 11:38 AM Bradley Meck 
wrote:

> I was doing some recursive data structure work and ended up with a
> cyclical promise that did not use a direct self reference. It can be
> reduced down to:
>
> ```javascript
> var af, a = new Promise(f=>af=f);
> var bf, b = new Promise(f=>bf=f);
>
> af(b);bf(a); // the problem
>
> a.then(_=>_) // some env/libs need this to start checking status
> ```
>
> According to https://tc39.github.io/ecma262/#sec-promise-resolve-functions
> it looks like this should cause a recursive and infinite set of
> `EnqueueJob("PromiseJobs",...)`
>
> This code currently does strange things in stable browsers, but doesn't
> seem to always cause infinite loops in the nightly builds of some things. I
> was wondering what the expected behavior is here because I am having
> trouble making sense of things.
> ___
> 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: `await null` to stay in the same tick?

2016-02-07 Thread Kris Kowal
Await yields to the event loop unconditionally. This is useful for
spreading CPU-bound work across multiple events. You can explicitly await
conditionally.

```
if (guard) { await guard; }
```

On Sun, Feb 7, 2016 at 1:39 PM /#!/JoePea  wrote:

> I'm not sure where's the best place to ask, but if I
>
> ```
> await null
> ```
>
> in an async function does that guarantee that the following code will
> execute immediately (control flow will not go anywhere else)?
>
> - Joe
> ___
> 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: Return value of forEach

2015-10-16 Thread Kris Kowal
forEach should return undefined. Array-like methods for iterators solve the
problem of building unnecessary memory pressure for intermediate maps.

The return value of forEach is special. True, for arrays it is always
undefined. However, the forEach method on an iterator returned by a
generator function should be the return value of the generator. Consider
this range generator that returns the number of visited values.

```js
function *range(start, stop, step) {
for (var index = start; index < stop; stop += step) {
yield index;
}
return (stop - start) / step;
}
var iterator = range(0, 10, 1);
var iterations = iterator.forEach((x) => console.log(x));
console.log(iterations);
```

Kris Kowal

On Fri, Oct 16, 2015 at 7:30 AM, Andrea Giammarchi <
andrea.giammar...@gmail.com> wrote:

> That's usually a made-up issue ... the example code is using two maps
> instead of computing the entire thing once in a composed function **and**
> it already creates multiple copies of the initial Array.
>
> Anyway, having `var log = DEBUG ? x => console.log(x) || x : x => x` in
> means you could do this:
>
> ```js
> const a = log([1, 2, 3]
>   .map(square))
>   .map(plus1)
>   .reduce(add);
> ```
>
> but again, we are using multiple maps and a reduce so if we want to be
> realistic, and it's for debugging purpose only, I think using map would be
> just fine.
>
> Regards
>
>
> On Fri, Oct 16, 2015 at 3:17 PM, Eric Devine <devin...@gmail.com> wrote:
>
>> Array#map does the non-trivial operation of copying the entire array. In
>> the example for loging to the console, this behavior is unintended. Perhaps
>> an underscore-like tap method should be considered to be added to the Array
>> prototype for these cases.
>>
>>
>> On Fri, Oct 16, 2015 at 9:32 AM, Andrea Giammarchi <
>> andrea.giammar...@gmail.com> wrote:
>>
>>> Like I've written before, if you need to return an array you can use map
>>> instead of forEach
>>>
>>> `arr.map(x => console.log(x) || x)`
>>>
>>> forEach has been like this since ever so while you wonder what kind of
>>> code would look like based on the fact forEach doesn't return  anything, I
>>> actually wonder how come there are still people expecting forEach to return
>>> something.
>>>
>>> So, it would be a breaking change and actually it's not needed since you
>>> have map.
>>>
>>> If the new Array, and for debugging purpose, is not desired, use `var
>>> log = DEBUG ? x => console.log(x) || x : x => x` and abuse it as much as
>>> you like.
>>>
>>> Would any of this work?
>>>
>>> Regards
>>>
>>>
>>>
>>> On Fri, Oct 16, 2015 at 2:23 PM, Niloy Mondal <niloy.monda...@gmail.com>
>>> wrote:
>>>
>>>> > That'd be a compatibility break.
>>>>
>>>> Ugh... you mean people actually depend on `forEach` returning
>>>> `undefined` (which it always does) to do further task?
>>>>
>>>> I wonder what that kinda code would look like >.<
>>>>
>>>> On Fri, Oct 16, 2015 at 6:08 PM, Frankie Bagnardi <f.bagna...@gmail.com
>>>> > wrote:
>>>>
>>>>> That'd be a compatibility break.
>>>>>
>>>>> If we end up getting :: though:
>>>>>
>>>>> ```js
>>>>> function logEach(){
>>>>>   this.forEach((x) => console.log(x));
>>>>>   return this;
>>>>> }
>>>>>
>>>>>
>>>>> const a = [1, 2, 3]
>>>>>   .map(square)
>>>>>   ::logEach()
>>>>>   .map(plus1)
>>>>>   .reduce(add);
>>>>> ```
>>>>>
>>>>> You could make that a global variable so you can sprinkle it around
>>>>> your code in development.
>>>>>
>>>>> Having some developer tools in the language would be nice though. I
>>>>> don't even think console.log is in the spec. A global like Debug.logThis
>>>>> for example would be a more general ::-able.
>>>>>
>>>>>
>>>>> On Fri, Oct 16, 2015 at 5:32 AM, Andrea Giammarchi <
>>>>> andrea.giammar...@gmail.com> wrote:
>>>>>
>>>>>> ```js
>>>>>> const a = [1, 2, 3]
>>>>>>   .map(square)
>>>>>>   .map(x => console.log(x) || x )
>>>>>>   .map(plus1)
>>>>>>   .reduce(ad

Re: RegExp.escape

2015-06-12 Thread Kris Kowal
I believe you need to champion the issue. Create a Github repository and
start editing the fragment of the spec. I do not believe that the issue is
contentious. The color of the shed is obvious. The only thing missing is a
champion willing to do the writing.

On Fri, Jun 12, 2015 at 10:52 AM, Benjamin Gruenaum benjami...@gmail.com
wrote:

 Reviving this, a year passed and I think we still want this.

 We have even more validation than we had a year ago (added by libraries
 like lodash) and this is still useful.

 What would be the required steps in order to push this forward to the
 ES2016 spec?

 ___
 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: Integrating the Webs' dependency systems

2014-05-27 Thread Kris Kowal
This is a great observation, often shared. I recall a related conversation
about a year ago, that echoed a proposal from Yehuda a year prior yet (to
which I hope Yeuhuda can exhume a link).

https://twitter.com/kriskowal/status/400703578605486080

And James Burke brought up some ideas on the topic.

https://gist.github.com/jrburke/7455354

It would be lovely if HTML could be trained to resolve URL’s through the
module system. The module system may provide a level of indirection, so
x/y.css might follow x into another package. Resolving ultimately to
URL’s allows, as Alex Russel insists, keeps the issues of resolution,
packaging, caching, bundling, web components, and service workers all
orthogonal. The issue of how to implement packaging and module identifier
resolution can, as John J. Barton points out, be left as a community
exercise in custom implementations of System, e.g., one compatible with npm.

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


Re: Integrating the Webs' dependency systems

2014-05-27 Thread Kris Kowal
On Tue, May 27, 2014 at 3:04 PM, Ian Hickson i...@hixie.ch wrote:
 On Tue, 27 May 2014, Kris Kowal wrote:
  It would be lovely if HTML could be trained to resolve URL's through the
  module system.
 By HTML here I presume you mean the underlying Fetch mechanism. Could
 you elaborate on exactly how this would work? Would this be in the layer
 before or after Service Workers?

Supposing that a page has both a service worker and a custom loader, I
would expect all requests for URL’s in the page (href, src, etc) to

1. pass through the page’s loader
2. pass through the browser's fetch mechanism
3. pass through the service worker
4. pass through the browser's fetch mechanism again
5. possibly arrive at the true service
6… proxies all the way down?

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


Re: Array.prototype.last()

2014-05-13 Thread Kris Kowal
I am in favor of last() and first() particularly because other collections
like queues and sorted sets can implement it and grow the common interface
of ordered collections. I also favor the last() and first() bike-shed
colors. I wrote a query and binding language that already uses these forms.

http://documentup.com/montagejs/frb/#tutorial/last

Kris Kowal


On Tue, May 13, 2014 at 11:54 AM, Dmitry Soshnikov 
dmitry.soshni...@gmail.com wrote:

 Hi,

 Exactly at the moment I'm writing too many of

   entries[entries.length - 1]

 where `entries` is an array (with of course moving to a helper
 function/prototype method).

 Will it make sense to add it now to ES6?

 For consistency with Object.keys(), it could be exactly a function, not a
 getter:

 entries.last()

 For correlation with entries.length, it could be the getter, yes

 entries.last

 Both work well, just need to peek more practical.

 The pop() is similar, but removes the element.

 (the issue was discussed before, not sure whether it was decided not to
 include it, or was it's just forgotten - don't see it in the draft, but
 seems the useful thing: if not for ES6, probably for ES7)

 (Alternative: entries.peek())

 Dmitry

 ___
 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: RegExp.escape

2014-03-21 Thread Kris Kowal
Continuing a 2 year old thread.

http://esdiscuss.org/topic/regexp-escape
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Promise.cast and Promise.resolve

2014-01-28 Thread Kris Kowal
In this case, a half pursuit of type purity is a side quest at the expense
of users. Having two ways to resolve and two ways to observe a promise is
unnecessarily confusing. In my experience, one method like then, that
unwraps recursively, and one function, like Promise.cast, that
automatically lifts if necessary, and then handlers that return into the
waiting hands of Promise.cast are coherent and ergonomic. Having a choice
between cast and resolve and a choice between then and chain, will
leave developers unnecessarily confused and worried all the while they use
or abandon Promises as too subtle.

For quite some time, grammarians have been losing a war to impose Latin
purity on English, in the case of split infinitives. Not long ago, the
famous phrase, to boldly go, were a racy departure from convention
because in Latin, the infinitive verb to go, is a single word, and you
simply would not break the word in half to put a poetic adverb between the
syllables. English is not Latin, and JavaScript is not Haskell.

Auto-lifting/unwrapping promises are beautiful. Purely monadic promises are
beautifully captured by type theory. But, I would pick one or the other
over one with multiple personalities. I would pick Promise.cast and
then, let complexity melt off the spec, and stop worrying.
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Weak callbacks?

2013-11-12 Thread Kris Kowal
One of the concerns with promises is that they consume exceptions that may
or may not be handled. I have been looking forward for WeakRef as one of
the avenues available to mitigate this problem. A post-mortem finalizer
would be able to surface an error that was trapped by a promise or promises
that were eventually garbage collected, and therefore provably
never-to-be-handled.

It is true that this problem can be decisively mitigated in other ways,
like requiring a promise to forward to a terminal done() in the same turn
of the event loop, but I find this particular solution unpalatable. I do
find a promise inspector compelling, one that will show an error until it
is handled, but even in this case, I think it is compelling to visually
elevate an unhandled error to a provably never-to-be-handled error, and
this is not possible, at least outside chrome-space, without WeakRef.

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


Re: Promises: final steps

2013-09-04 Thread Kris Kowal
My colleagues and I are working on an extension for Chrome Web Inspector
that can communicate with promise libraries, particularly Q, over the
window message port. The tool, which will be renamed and rewritten before
it is ready for general use, adds a Promises tab to Web Inspector that
shows all currently pending and unhandled asynchronous errors, as well as
stack traces for both, and also progress information, albeit determinate,
indeterminate, or indeterminate but lively. There is a video accompanying
for demonstration.

https://github.com/montagejs/continuum

https://www.dropbox.com/s/2h68ax9j5mj7i6c/continuum.mov

The promise client broadcasts when a promise is deferred, when a deferred
promise is resolved, when a deferred promise makes progress (through the
`deferred.notify` interface), when a fulfilled promise is created, when a
rejected promise is created, and when a rejection is handled. As such, the
inspector can reconstruct whatever portion of the program’s promise history
it elects to retain.

In time, I intend to formalize a protocol. Ideally this system would be
useful for both “primordial” and library promises, and combinations of
both. Of course, any assistance would be valuable.

Also, ideally this would approach the functionality available to Causeway
and perhaps even *become* a manifestation of Causeway.

https://code.google.com/p/causeway/wiki/CausewayIntroduction

It would certainly be possible to show promises in multiple contexts,
including cross-origin iframes, and even show time sequence / Stevens
graphs for message passing between promises in multiple JavaScript
contexts, when promises are used as proxies for remote objects through a
facility like Q-Connection

https://github.com/kriskowal/q-connection

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


Re: Optionally ignoring case in String.prototype.contains()?

2013-08-28 Thread Kris Kowal
Perhaps the second argument of `contains`, `startsWith`, and `endsWith`
should be consistent with the second argument of the `RegExp` constructor.
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Optional Strong Typing

2013-08-23 Thread Kris Kowal
On Fri, Aug 23, 2013 at 1:20 PM, J B por...@gmail.com wrote:

 https://mail.mozilla.org/pipermail/es-discuss/2008-August/006837.html This
 is depressing.


J B,

You’re entitled to a dissenting opinion. However, this archives one of the
best moments for the evolution of the language. It was a commitment to
focus on deliberate, consistent, incremental change. We are realizing the
rewards for the Harmony agenda today with property descriptors (which
formalized and exposed an existing concept), new collections, and Proxies.
The cesura on namespaces have provided an opportunity for much much more
deliberately designed modules. Innovation has returned and the pace is
good, neither hasty nor stagnant.

That said, note that your sentiment has been graciously heard. What you are
asking for is well-represented by rigorous research going into TypeScript,
which is very closely aligned with work and proposals that came out of
these discussions. I believe it is fair to interpret Brendan’s last
sentiment, “This again puts unsound warning types outside of the
standards track for a while. But carry on with TypeScript etc. — TC39 is
tracking”, not as “no”, but as “not yet”.

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


Re: July notes: copySlice -- copyWithin ??

2013-08-14 Thread Kris Kowal
The name `copy` matches my intuition for the behavior described, as
informed by the shell command `cp source target` and other precedents. I
would expect `clone` to return a deep copy, as in `Object.clone(object,
depth=Infinity, memo=Map())`, informed by the Java precedent, and I would
not be perturbed by `copy` and `clone` coexisting as such.

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


Re: SortedArray in JavaScript?

2013-08-11 Thread Kris Kowal
On Sat, Aug 10, 2013 at 3:19 AM, Forbes Lindesay for...@lindesay.co.uk
wrote:
 I doubt you want to let it be indexed using `[]` and I see little reason
why it would need to be built into the language.  It would make far more
sense as a nice little library, which creates a much smaller maintenance
burden.

For example,
https://github.com/montagejs/collections/blob/master/sorted-array.js
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: [Map/Set] Add an .update() method, a la Python?

2013-06-27 Thread Kris Kowal
I’ve found it satisfyingly idiomatic to call this `addEach` (for both maps
and other collections) in my work on Collections[1].

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


Re: Where'd Promise#done go?

2013-06-18 Thread Kris Kowal
As Domenic mentions, there will be no place for done in our bright
promise debugger future.

It will however be necessary for promise users to keep on ending their
chains with done() until promise debuggers are ubiquitously available.
This is a simple problem. If you are writing code that targets both old and
new engines, the promise polyfill will simply have to patch a no-op done
onto the engine’s Promise.prototype.

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


Re: The Paradox of Partial Parametricity

2013-05-22 Thread Kris Kowal
Tab’s proposal as I understand it is to standardize Q-like promises and add
a chain method that is then but with behavior tailored for monadic
composition.

This sounds like a good compromise.

The only downside I can contrive is that it gives users, particularly
novices, a subtle choice. Would it be more clear that it is intended for
monadic composition if the name were literally bind?

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


Re: Do futures represent a pipeline? (was Re: Future cancellation)

2013-05-01 Thread Kris Kowal
On Wed, May 1, 2013 at 9:13 AM, Tab Atkins Jr. jackalm...@gmail.com wrote:

 The reasoning behind promises/futures is explained in more detail in
 my blog posts


A while back, I also wrote up an explanation of promises starting from base
principles.

https://github.com/kriskowal/q/blob/master/design/README.js

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


Re: WeakMap better than Private Symbols? (was: direct_proxies problem)

2013-01-10 Thread Kris Kowal
As an aside, Irakli Gozashvili and I independently realized that you
could use a WeakMap for parallel objects with inheritance. Very
similar to Brendan’s createStorage, we put together a parallel
universe constructor.

function Parallel(root) {
var parallel = new WeakMap();
root = root || null;
function get(object) {
if (!parallel.has(object)) {
parallel.set(object,
Object.create(get(Object.getPrototypeOf(object;
}
return parallel.get(object);
}
return get;
}

Irakli’s was a Namespace constructor that appeared somewhere in the
Mozilla Add-on toolkit, but the links have gone stale.

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


Re: Designing a MultiMap (in DOM, would like to be consistent with ES)

2012-11-30 Thread Kris Kowal
Perhaps consider .push(key, …values) instead of .append(key, value)
and .appendAll(key, values).

I’ve seen this kind of MultiMap around, so I presume people like the
heterogenous range type. I’ve gone a different way in my work, where
MultiMap was a Map that would set the value for a missing key to an
empty array. Then, extended Array to have a one or only method.

getAll(key) ~ get(key)
get(key) ~ get(key).one()
setAll(key, values) ~ set(key, values)
set(key, value) ~ set(key, [value])
append(key, value) ~ get(key).push(value)
appendAll(key, values) ~ get(key).push(...values)

For the URL use case, this loses information about interleaving of
keys, which is usually unimportant except (perhaps) in making round
trips between parse and stringify.

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


Re: [Bug 20019] Support subclassing ES6 Map

2012-11-20 Thread Kris Kowal
On Tue, Nov 20, 2012 at 10:57 AM, Mark S. Miller erig...@google.com wrote:
 Since Map and Set will be in ES6 and MultiMap is trivially
 implementable from these, we can wait until we see some experimental
 implementations before standardizing. Hence the ES7 target.

Here’s my experimental implementation, in terms of my Map shim.

https://github.com/kriskowal/collections/blob/master/multi-map.js
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Map.prototype.clear method

2012-10-22 Thread Kris Kowal
On Mon, Oct 22, 2012 at 10:58 AM, Yehuda Katz wyc...@gmail.com wrote:
 What about copying of these new data structures?

The polyfills I have also do .clone(depth_opt, memo_opt), where memo
is a map that breaks cycles and depth defaults to Infinity, 0 means
return this, and 1 is a shallow copy.

https://github.com/kriskowal/collections

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


Re: global object in strict mode

2012-08-24 Thread Kris Kowal
On Fri, Aug 24, 2012 at 10:41 AM, Brendan Eich bren...@mozilla.org wrote:
 I'm not sure what the problem is -- I read the old thread, and noticed the
 solution:
 var global = Function(return this)();
 This is good for any code mode, strict or non-strict. Does CSP ban Function
 as well as eval?

CSP does forbid the Function constructor, by the edict “Code will not
be created from strings”.

http://www.w3.org/TR/CSP/ Section 4.2 “If unsafe-eval is not allowed…”

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


Re: Protected Protocol

2012-04-03 Thread Kris Kowal
On Tue, Apr 3, 2012 at 1:49 AM, David Bruant bruan...@gmail.com wrote:
 Le 02/04/2012 17:59, Irakli Gozalishvili a écrit :
 I remember that one of your complaints about namespaces was that inheritance
 was not supported. Do you think there is a workable middleground between
 namespaces and what I've showed here that would have the benefits of
 namespaces and inheritance?

Yes, prototypical namespaces are a slight revision away, and I believe
Irakli has already integrated that change in Jetpack.

https://gist.github.com/2047799

This gist illustrates parallel prototype chains between namespaces,
and how a namespace can have a common ancestor prototype for each
instance.

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


Re: Array#sort(prop)

2012-04-01 Thread Kris Kowal
This is all pretty straightforward library work. With Narwhal’s util
module and with my previous work on Chiron, I made some small
composable tools, in much the same spirit as Jeremy Ashkenas’s work on
Underscore.  Consider two higher order functions.

by(relation) accepts a relation (a function that accepts a value and
returns a related value) and returns a comparator.

get(name) returns a relation function that retrieves the named
property of an object.

These compose like:

points.sort(by(get(x)))
points.sort(by(distanceFrom({x:10,y:20})))

So that much can be done in libraries.

What can’t be done without shimming the sort function is a Schwartzian
transformation. This is where you do a map/sort/map to reduce
applications of the relation, which can double the performance of a
sort in the most degenerate case: large completely unsorted array and
a costly relation. Some years ago I found that the optimization was
beneficial for arrays longer than 3 for a getter relation.

function schwartzianSort(values, relation, compare) {
return values.map(function (value) {
return [relation(value), value];
}).sort(function (a, b) {
return compare(a[0], b[0]);
}).map(function (pair) {
return pair[1];
});
}

To facilitate this and the above notation, the comparator returned by
the by function was annotated with compare and by properties
which were the original relation and comparator. (by accepted an
alternate comparator as a second argument; the default had sensible
semantics for all same-type pairs of primordials and did not coerce
strings to numbers, a noteworthy wart of the existing specified
default comparator).

The alternate sort (in-place) and sorted (sorted copy) functions
would accept any object with a by property (and optional compare
property) would invoke the Schwartzian transform.

Adding support for this optimization to Array#sort would be
interesting, and the interface might provide an opportunity to allow
users to opt-in for a more sensible default comparator.  If sort
receives an object with compare or by properties, it could go
through the new code-path.  Passing a non-function object would
guarantee the more sensible default compare.

A more sensible default compare would sort strings lexically, and
sort arrays with left-to-right precedence and recurse on each element.

Sensible invocations:

values.sort({by:relation})
values.sort({by:relation,compare:altCompare})
values.sort({compare}) // if default compare is added in global scope
values.sort({}) // default comparator

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


Re: Set polyfill with a has method more efficient than O(n)

2012-03-30 Thread Kris Kowal
I think it is fair, for the shimming crowd, to ask objects to
implement a `hash` method to return a consistent string. Collection
types can degrade to O(n) in the absence of a provided consistent
hash, but enhance to O(1) in the best case.  This would involve having
a two layer internal datastructure, an object that maps consistent
hashes - to array buckets - to values for Set or [key, value] pairs
for Map.  I would also implement Map in terms of Set, just overriding
the hash and equals functions to operate on the key portion of each
pair in the set.

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


Re: simpler, sweeter syntax for modules

2012-03-21 Thread Kris Kowal
On Wed, Mar 21, 2012 at 4:05 PM, Axel Rauschmayer a...@rauschma.de wrote:
 Honest question: Are nested modules really needed?

There is a chance that they would be useful for bundling. Modules
can’t be concatenated.

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


Re: How about replacing | with -

2012-03-02 Thread Kris Kowal
On Fri, Mar 2, 2012 at 2:30 PM, Allen Wirfs-Brock al...@wirfs-brock.com wrote:
 Some examples of this usage of - include:
   MyObject.prototype - {a:1,b:2}
   appArrayBehavior-[0,1,2,3,4,5]
   let subclass = superclass - function () {};
   var p = newRegExpMethods - /[a-m][3-7]/
 What do you think? Do you like - better than | ?  Is it ok to not have it
 available for some possible future function shorthand?

I’ve been contemplating a + symbol.

prototype + {a: 1, b: 2}
arrayExtras + [1,2,3]
let sub = super + function () {};
var p = regexpExtras + /[a-m][3-7]/

There may be little precedent for abusing operators in JavaScript, but
in other systems, I would expect adding collections to produce the
union of those collections, with precedence given to the right hand
operand.  In a world where [1,2,3] + [4,5,6] = [1,2,3,4,5,6] and
{a:10, b:20} + {b:30} = {a:10, b:30}, I think that + would make sense
as an alternative to +, where the result shadows instead of snapshots
the left hand side for the same effect until it changes.

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


Re: RegExp.escape()

2012-01-04 Thread Kris Kowal
On Sun, Jun 13, 2010 at 7:50 AM, Jordan Osete jordan.os...@yahoo.fr wrote:
 Hello everybody.

 How about standardizing something like RegExp.escape() ?
 http://simonwillison.net/2006/Jan/20/escape/

 It is trivial to implement, but it seems to me that this functionality
 belongs to the language - the implementation obviously knows better
 which characters must be escaped, and which ones don't need to.

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


Re: WeakMaps question ?

2011-11-11 Thread Kris Kowal
On Fri, Nov 11, 2011 at 3:28 PM, Irakli Gozalishvili rfo...@gmail.com wrote:
 I really need to know why WeakMaps don't accept primitives as keys, can
 anyone please reply ?

It’s because WeakMaps are intended to drop values if the key is
garbage collected.

A WeakMap guarantees that it will drop its value if it becomes
provably inaccessible.

This works for non-primitive keys because we can guarantee that once
an object has been garbage collected, no future object can be created
that would have been identical to it, making the value inaccessible.

Once a primitive value like 1 or the string abc has been garbage
collected, it is trivial to construct a new value that is identical to
the original key, so we could never implicitly garbage collect the
value corresponding to a primitive key.

Mark Miller has proposed a strong variation of WeakMap, simply Map,
that would serve well in cases where items are explicitly collected.

http://wiki.ecmascript.org/doku.php?id=harmony:simple_maps_and_sets

As I recall, a variant of Map was considered in the ES4 timeline as well.

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


Re: Minimal type guards?

2011-10-13 Thread Kris Kowal
On Thu, Oct 13, 2011 at 11:51 AM, Quildreen Motta quildr...@gmail.com wrote:
 Contracts would be interesting, but perhaps too expensive?

 fib :: (Number) - Number
 function fib(n) {
     return n == 0?  0
  : n == 1?  1
  :  fib(n - 1) + fib(n - 2)
 }

 or function fib(n Number) - Number { }

 Not particularly proposing any syntax though. Not particularly keen on using
 fixed types though -- as JS is not statically typed and types are not
 particularly well defined, definitely not something I'd check for is-a
 relationships --, I'd rather go with a predicate functions, but then that's
 even more expensive.

Quildreen,

Your proposal resembles Waldemar’s guards and trademarks.

http://wiki.ecmascript.org/doku.php?id=strawman:trademarks
http://wiki.ecmascript.org/doku.php?id=strawman:guards

You might consider building on these to make a contracts proposal,
separating the signatures from the declarations.

Alex’s question is whether some subset of these ideas is suitable for
rapid consensus. I will refrain from speculating.

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


Re: That hash symbol

2011-03-25 Thread Kris Kowal
On Fri, Mar 25, 2011 at 11:24 AM, Brendan Eich bren...@mozilla.com wrote:
 No problem -- just don't provoke Zeus to unleash the Crock-en ;-).
 https://mail.mozilla.org/pipermail/es-discuss/2011-February/012761.html

Perhaps there needs to be a venue where non-experts can bounce ideas
and discuss points of pain with volunteering committee members to
reduce noise in this venue. There is little room here for
light-hearted discussion and mentoring for members of the community
who have less than full-time commitment and years of experience in
language design.

It's disappointing to be ostracized, but it is true. I also want to
see careful and well-wrought steady progress. I remember a former
decade when this discussion was impossible to follow, too many bad
ideas were too thoroughly discussed, and much time was wasted.

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


Harmony as a Compilation Target of my Dreams

2011-02-08 Thread Kris Kowal
This is a half-baked idea. Harmony of Brendan's Dreams makes extensive
use of new octothorp syntax. There is perhaps another use for
octothorp prefixes: to annotate generated JavaScript with line numbers
from the source.

source.cs:
number -= 42 if opposite
square = (x) - x * x

target.js:

var opposite, number, square;
#1 if (opposite) { number -= 42; }
#2 square = function (x) { return x * x; }

This would require some form of annotation to connect the line numbers
with the corresponding source code.  The connection could be inferred
easily given the tacit strawman for Module(text, fileName, lineNo) and
I imagine that some similar annotation would be possible on or around
a module keyword.

It might even be useful to implicitly increment the annotation line
number on line breaks to reduce the verbosity so that minifiers can
provide similar annotation at little cost.

A third use-case would be annotating the sources of statically bundled
Simple Modules or whatever succeeds them. I imagine that there would
be a need for tools that transform load directives into inline
modules, so it would be handy to annotate sources for debugging in
that case too.

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


Re: Harmony as a Compilation Target of my Dreams

2011-02-08 Thread Kris Kowal
On Tue, Feb 8, 2011 at 1:39 PM, Mark S. Miller erig...@google.com wrote:
 Much better IMO is the tack taken by Java
 http://blog.csdn.net/dollyn/archive/2009/09/01/4506156.aspx#sourcemapfile,
 Caja, and ClosureCompiler of generating separate source mapping tables that
 map from generated text position back to original text position.
 And I find HOBD's use of # much more valuable. I do not think we should
 have both uses of # coexist in one language.

Ah. With these givens, I agree.

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


Re: idea: try/catch and rethrow...?

2011-02-01 Thread Kris Kowal
In Narwhal, we wrote something like this:

var thrown = true;
try {
// something done that might throw
thrown = false;
} finally {
if (thrown) {
// exception observed but not caught
}
}

If I recall correctly, and I'm sure it's been noticed that I often
don't, this was necessary since we didn't want to baffle Rhino's
stack-trace. I don't think this would have been necessary on V8 since
stack traces are garnered by the Error constructor, not by decoration
at the point of throw.

This both illustrates that the feature is not necessary and that the
workaround is ugly.

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


Re: Simple Modules: lazy dependency evaluation

2011-01-27 Thread Kris Kowal
On Thu, Jan 27, 2011 at 7:27 AM, David Herman dher...@mozilla.com wrote:
 We thought for a while about
 demand-driven evaluation of modules. There are a couple reasons why I
 believe it would be too problematic. First, we'd really like to make the act
 of throwing your code into a module as transparent as possible; changing the
 control flow would make modules more heavyweight. But more importantly,
 since as you mentioned, module evaluation can contain arbitrary side
 effects, evaluating them lazily means laziness with side effects. This makes
 for really hard-to-understand and hard-to-debug initialization errors, where
 you end up having to write mysterious top-level imports to force evaluation
 of modules in particular orders. Laziness + side-effects: bad scene, man.

On the opposite side of the argument, I presume that this means that
modules are evaluated when their transitive dependencies are loaded.
This would imply that the order in which the modules are delivered,
possibly over a network using multiple connections, would determine
the execution order, which would in turn be non-deterministic.
Non-determinisim + side-effects is also a bad scene.

Is there an alternate method proposed in Simple Modules for
deterministically linearizing the evaluation order? Non-determinism is
definitely a greater evil than providing developers a means to
explicate the order in which they would like their side-effects to be
wrought.

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


Re: Simple Modules: lazy dependency evaluation

2011-01-27 Thread Kris Kowal
On Thu, Jan 27, 2011 at 9:14 AM, David Herman dher...@mozilla.com wrote:
 …but it is required to evaluate them in their declared order, 
 deterministically.

Would you explain how declaration order is inferred from the contents
of the unordered of files?

It's clear that the order is at least partially knowable through the
order of module declarations within a single file, and that load
directives would be replaced with a nest of modules, which is similar
in effect to loading on demand if the load directive is considered a
point of demand at run-time. And we're guaranteed that there are no
files that would be loaded that are not reachable through transitive
load directives. I suppose I've answered my question, if all my
assumptions are correct.

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


Re: New private names proposal

2010-12-16 Thread Kris Kowal
On Thu, Dec 16, 2010 at 1:53 PM, David Herman dher...@mozilla.com wrote:

    function Point(x, y) {
        private x, y;
        this.x = x;
        this.y = y;
        ...
    }

 than

    function Point(x, y) {
        var _x = gensym(), _y = gensym();
        this[_x] = x;
        this[_y] = y;
    }

I tend to disagree with most developers, so take it with a grain of
salt that I find the latter form, with all the implied abilities,
easier to understand.

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


Re: simple shorter function syntax

2010-07-23 Thread Kris Kowal
On Fri, Jul 23, 2010 at 10:08 AM, Trans transf...@gmail.com wrote:
  [0, 1, 2, 3].map( f(x) {x * x} )
  [0, 1, 2, 3].map( fn(x) {x * x} )
  [0, 1, 2, 3].map( y(x) {x * x} )
 Any of these seem a much nicer choice than '#', IMHO.

While I agree on principle, the real challenge here is to find syntax
that will not break existing programs by promoting an existing
variable name to a keyword.  Otherwise, you'd have to look ahead to
the curly brace block to distinguish the variable name from the
function keyword.  It's been a long time since I wrote a parser of
this kind, but as I recall, looking ahead is generally hacky.

function expression: name, argument list, block

Of course, if that approach were taken, the spec might as well forgo
having a function keyword at all and use the name or absence of a name
to distinguish a named and anonymous function expression.  But again,
I expect there would be resistance to looking ahead.

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


Re: Composition of Uncoordinated Working Sets of Modules

2010-06-07 Thread Kris Kowal
On Mon, Jun 7, 2010 at 8:37 AM, Sam Tobin-Hochstadt sa...@ccs.neu.edu wrote:
 On Sun, Jun 6, 2010 at 2:00 PM, Kris Kowal kris.ko...@cixar.com wrote:
 ...

Most of this is good clarification, particularly that load
interacts with the exports of the foreign script's implied,
anonymous module scope.  The grammar is clear.  It would be
good for this to be expressed in one of the examples, and
for it to be clarified in the description of semantics that
every script is also an anonymous module from which the
exports are only accessible through the lexical scope
shadowing (I assume) and by being bound to a module
through a load expression.

 Right.

 module M = load foo.js;

 creates a new module M with foo.js as its contents.

This is a point that Ihab clarified for me yesterday
evening that merits bold and emphasis: loaded modules are
not singletons.  You do this to avoid having to compare
MRL's for equivalence, particularly to avoid having to
define equivalence given the potential abundance of edge
cases.

http://example.com/module?a=10b=20
http://example.com/module?b=20a=10

It's worth noting, and please dismiss the implication that
the approach is necessarily proper and correct, that this is
not a problem for CommonJS modules because the specification
limits module identifiers to a very small subset of
expressible URLs and defers the issue of URLs to the
packaging layer, wherein the semantics are similar to those
put forth here.

 * for a script to have importable bindings, these must
 exist in a  module block of the loaded script.

 I don't know what this means.

Ihab clarified that this is not true.  This is a
re-statement of my mis-perception that there is no implicit,
anonymous, top-level module in a script and that therefore
there cannot be exports outside explicit module blocks.  I
stand contentedly corrected on this point.


 It's possible to use the module loader API to do this,
 slightly more verbosely.   But why?  If you say:

 module A = load aQuery.js;

 then A.$ is already available for use in expression
 contexts.

I can make the same argument about import *.  If I import
A, I can access its contents as A.$.  To permit
destructing on all import expressions would be consistent
philosophically.


 link.js
    module aQuery_ = load(scripts/aQuery.js);
    const $ = aQuery_.aQuery.$;

 Your example might point to a need to augment the module
 loader api with information on 'load' calls specifying
 what module the 'load' occurs in.

Exactly.  The Narwhal loader receives an id and a baseId on
from require(id) calls.  Each module gets a fresh require
effectively bound on the baseId.  I think that the loader
handler needs to receive the base MRL as an argument or part
of the request object.


Another thing that Ihab clarified which merits a full
section on the wiki is the dynamic scoping of lexical module
names.  Ihab pointed out that, when a script is loaded, it
inherits the module scope chain of the declarer, permitting
a certain degree of aspect oriented dependency provision,
or external linkage.  This depends on an understanding
that each load always instantiates a module and cannot
ever rebind an existing module (a singleton).

loaded.js
export function poof(el) {
$.poof(el);
}

aQuery.js
export function poof(el) {
// one implementation
}

bQuery.js
export function poof(el) {
// an alternate implementation
}

a.js
module $ = load(aQuery.js)
module X = load(loaded.js);

b.js
module $ = load(bQuery.js)
module X = load(loaded.js);

linkage.js
module A = load(a.js);
module B = load(b.js);

Noting that in this example, having loaded linkage, there
are two instances of loaded.js, each of which sees $ as
aQuery and bQuery respectively.  They also see X, A
and B following the dynamic scope chain.

This is something I have not considered.  It would be good
to do a write-up on what use-cases you have in mind for this
feature.

Also note that, because I was not aware of this feature,
I've been using the terms external linkage and internal
linkage differently, in the context of my first email on
this thread.  I used the terms internal and external to
refer to modules from a given working set of modules from
one coordinated design (a package), and to modules outside
the package, in other packages.  Sorry for the confusion.


At this point I have been convinced that it is possible with
this proposal to integrate uncoordinated working sets of
modules by using the load syntax and script-scoped exports.
I've also been convinced that there is a way to inject free
variables into an isolated context, as mediated by the
loader.  I've been made aware that there exists a way to
implicitly inject modules when loading scripts, which
implies that there is a contract between the loader and
loadee that certain free variables in the loadee will be
bound through the module scope chain.  This provides a finer
grain means of weaving dependencies

Re: Composition of Uncoordinated Working Sets of Modules

2010-06-07 Thread Kris Kowal
On Mon, Jun 7, 2010 at 12:10 PM, Erik Arvidsson
erik.arvids...@gmail.com wrote:
 On Mon, Jun 7, 2010 at 10:35, Kris Kowal kris.ko...@cixar.com wrote:

 Another thing that Ihab clarified which merits a full
 section on the wiki is the dynamic scoping of lexical module
 names.

 This is a common misconception. Simple modules is using static lexical
 scoping, not dynamic scoping. The thing that might be confusing is that the
 loaded module is defined in the lexical scope of the module that loaded it.

Reviewing the idea, it's certainly not dynamic scoping.  If you're
very free with the analogy to a function call as established by the
syntax, I recklessly intuited that there's a case for it sharing the
analyzability problem that dynamic scoping causes, but I have not
found such a case. However, you cannot statically observe a reference
error on a single script in isolation; you need to know the lexical
scope in which it has been loaded.  I don't think that's necessarily a
problem.  It's certainly the same case with any situation where
successive script tags have access to the modules declared by previous
scripts.

Kris Kowal

(For anyone observing the political mess I've made, I do plan to do a
write-up redacting my claim that Simple Modules can't be used to
compose independently designed scripts.  I think this is the big issue
and I'm glad this design has a solution.  I'll continue to ponder the
implications for CommonJS and see if I can come up with a migration
story that makes sense.)
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Composition of Uncoordinated Working Sets of Modules

2010-06-06 Thread Kris Kowal
Supposing that aQuery and bQuery are implemented by independent
uncoordinated authors.

aQuery.js

module $ {
}

bQuery.js

module $ {
}

If my interpretation is correct, these cannot be combined in a single
Application.

script type=harmony src=aQuery.js/script
script type=harmony src=bQuery.js/script

One solution to this problem is to convince A and B to coordinate,
which I've hitherto inferred was the only solution supported by Simple
Modules, in which case they share a fault with Java.

Is this a solution?

script type=harmony
module A_ = load(aQuery.js);
module A = A_.$;
module B_ = load(bQuery.js);
module B = B_.$;
/script

With this example, I am inferring that

* That the web-browser's loader knows the location of the current
  page, so it can resolve the MRL based on that location.
* load can only be used in the context of an importing module
  assignment.
* conceptually, if not at run-time, load returns a module instance
  that contains the top-level modules of the given script.
* that the top-level modules of the remote script are not registered
  as top-level modules of the local application, unlike co-DOM
  scripts.
* for a script to have importable bindings, these must exist in a
  module block of the loaded script.
* there is no notation for destructuring a module from a loaded
  sub-module
* a script is not a module, so exports cannot be used at the top
  level.

If that's the case, I would like to refine this approach, such that
loaded modules can have exports at the top level.  This would permit
the function export.

aQuery.js

export var $ = function () {
};

bQuery.js

export var $ = function () {
};

link.js

module A = load(aQuery.js);
module B = load(bQuery.js);

It would also be good for there to be a way to bind $ without binding
a module.

const A = load(aQuery.js).$;
const B = load(bQuery.js).$;

This obviously breaks a load call outside an import clause, which I
infer is not possible with the present proposal.

Is it possible to decouple name spaces from loaded modules?

Another point of interest is transitive loads.  I do not think that
there is a provision in the specification that would permit load
directives to be resolved relative to the location or MRL of the
module from which load call is declared.

scripts/sazzle.js
module Sazzle {
}

scripts/aQuery.js
module Sazzle_ = load(sazzle.js); // relative to
// scripts/aQuery.js
module Sazzle = Sazzle_.Sazzle;
module aQuery {
export $ = function () {
};
}

link.js
module aQuery_ = load(scripts/aQuery.js);
const $ = aQuery_.aQuery.$;

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


Re: Composition of Uncoordinated Working Sets of Modules

2010-06-05 Thread Kris Kowal
On Sat, Jun 5, 2010 at 3:40 AM, Sam Tobin-Hochstadt sa...@ccs.neu.edu wrote:
 On Fri, Jun 4, 2010 at 9:48 PM, Kris Kowal kris.ko...@cixar.com wrote:
 On Fri, Jun 4, 2010 at 5:17 PM, David Herman dher...@mozilla.com wrote:
 By keeping modules second class, we get a number of benefits, not
 just handling cyclic dependencies. (In fact, cyclic dependencies can
 be handled nicely in a first-class module system as well.) One of
 the benefits of second-class modules is the ability to manage static
 bindings; for example, import m.*; is statically manageable. Allen
 has made some good points about how second-class modules are a good
 fit for the programmer's mental model of statically delineated
 portions of code. At any rate, cyclic dependencies are not the
 central point.

 As far as I can tell, Simple Modules only changes the composition
 hazard introduced by imoprt m.* from a run-time hazard to a
 link-time hazard.

 In your example, certainly the earlier error is a benefit of our
 proposal.

I strongly disagree.  Either Alice is at fault for using import m.*,
Charlie is at fault for altering her API, or neither Alice and Charlie
are at fault because they were merely and earnestly using the features
of the underlying system, in which case the system is at fault.  Alice
should be able to trust the features of her module system.  Charlie
should be able to *augment* her API without breaking her dependents.

 But the really key benefit is this:

 module M {
  export x = 7;
 }

 module N {
  M.y + 3; // an error - just like an unbound variable in ES5 strict
 }

This feature does not preclude the omission of the import * syntax
variant.

 This can be an early error because we statically know a lot about
 modules.  This is good for programmers, because it supports early
 errors, and also good for compiler writers, since it supports
 optimization.

I agree.  I do not think that any of my objections preclude statically
linking name spaces.

 Because Simple Modules is based on lexical scope, collecting modules
 is as simple as collecting objects into a larger object:

 module Container {
  module Sub1 = load http://example.com/foo.js;;
  module Sub2 = Other.InnerModule;
  module Sub3 {
    module SubSub4 = load http://example.org/bar.js;;
  }
 }

And I presume that usage of submodules is:

module Container = load(the script above);
module X = Container.Sub1.SubSub4;

If that's the case, please consider making the nested module export
explicit:

module Container {
export module Contained {
}
}

I am not attached to the name spaces feature of the Simple Modules
proposal, but it's not worth fighting.

 This is also not true; the ability to attach modules to module
 loaders (as well as the dynamic evaluation methods) makes it
 possible for separate module loaders to communicate. However,
 loaders aren't about linking multiple working sets, but rather
 providing isolated subspaces. (One use case I sometimes use is an
 IDE implemented in ES, that wants to run other ES programs without
 them stepping on its toes.)

 Code examples would be insightful.

 Currently, in web-based IDEs such as Bespin, code being developed has
 the ability to muck with the internal state of the IDE and the overall
 page, which is usually undesirable.  With module loaders, simply by
 not sharing access to the DOM or other internal state with the code
 being developed, this would be prevented.

I understand and wholeheartedly agree with the why.  I do not
understand how.  Code examples would be insightful.

 Perhaps I am misunderstanding the scope of a module name.  Is it not
 true that a module is available by its self declared name in all
 modules that share a loader?  Is it actually possible to bind a single
 module name that provides access to all of the modules in another
 loader?

    module X = load(http://example.com/api;);
    module Y = X.Y; // is this possible?

 Yes, if that URL has a module Y in the code that it provides.  For
 example, if that URL produces the code:

 module Y { ... }
 module Z { ... }

 Then it's certainly possible.

Developers should not need to concatenate subsystems to construct
packages.  It should be possible for one to connect loaders to other
loaders.

 Is it possible for MRL's to be CommonJS top-level and relative module
 identifiers?

 We've avoided committing to particular syntax for MRLs so far,
 although the discussion at the last meeting tended toward the
 following syntax:

 MRL = URL | RelativeURL | @Identifier

This notation seems adequate.  The question remains whether relative
URL's are supported by the proposed loader API.  It's my impression
that it is not presently possible for a loader handler to observe the
MRL of the module that requested the module.  If that's the case, it
would be the responsibility of the loader itself to resolve MRL's.  It
would be better if that responsibility were deferred to the loader
handler.

 If that's the case, is it possible

Re: Composition of Uncoordinated Working Sets of Modules

2010-06-05 Thread Kris Kowal
On Sat, Jun 5, 2010 at 2:41 PM, Brendan Eich bren...@mozilla.com wrote:
 I strongly disagree.

 Whoa -- I don't see how anyone can disagree that early error is better than
 a runtime error, if there is an error case at all. It seems to me you're
 instead arguing that no such error should be possible because import m.*
 should not be supported -- that you're arguing against any
 import-everything-that's-exported feature. Right?

Yes, we're in agreement that an early link-error is better than
run-time error.  You are also correct that my argument is that import
* should not be supported.  It also true that this is not my primary
objection and it does not poison the design; it is a side-show.

It is also true that this is a value-judgement between the convenience
of the feature when used responsibly by wise and scholarly programmers
within a system of modules designed in coordination, and the value of
protecting programers from the hazard at the cost of that convenience.

CommonJS put this to vote.  There was support on both sides, but on
CommonJS, the feature was sacrificed to get unianimous support.  Only
Tom Robinson called for the include function (import *) in the final
show of hands, but cast his +1 without the feature.

http://groups.google.com/group/commonjs/browse_thread/thread/d2dc85a2725992be/4a7fb3943fdd?lnk=gstq=modules+include#4a7fb3943fdd

It is likely that it not possible to get a large enough group of
people either in support of the feature or against the feature to
reach unanimity, and that nobody cares enough either way to block
ratification.  This is far more likely than that there is consensus
either way.

 The only reason import m.* is in the proposal is that when one is
 using modules in one's *own* (definitely including the single-author
 case, but also the single-curator and same-origin-hosted case)
 larger program, where the hazard of new names can be controlled by
 testing and auditing, then lack of import m.* is a royal pain. This
 is especially true during rapid prototyping.

Yeah, I've been on both sides of the debate.  I got bitten in the ass
when I was using from django.models import *, which is naturally a
case of using a module in foreign control (which you note is not
proper usage) but also very compelling because of the royal pain you
mention.  I think it would be good to put this issue to vote.  I think
we're in agreement about the nature of the trade-off and we wouldn't
want to make Buridan donkeys of ourselves.

I also think we should get a show of hands on whether we should try to
decouple name spaces (named module clauses per the simple modules
proposal) and modules (as linked with a loader), and whether we need
both layers.

Meanwhile, I would still like to see examples of how to compose
working sets of modules with other working sets of modules that were
not designed in coordination.

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


Composition of Uncoordinated Working Sets of Modules

2010-06-04 Thread Kris Kowal
.  Then, using reflective Loader
or Linker API, it would be possible to create and use optimized
bundles.  Furthermore, package mappings could be accomplished if
browsers provided a URL Linker/Loader that would automatically fetch
and link modules on a particular URL tree.


In summary, the problems worth solving include:

a.) balancing linkage brevity and uniqueness, with the goal of
offloading the global name space problem to DNS, providing
reliable sovereignty over name spaces controlled by:
 * the developer of a single file
 * the developer of a tree of files
 * domain owners
 * IANA
b.) elimination of accidental global variables
c.) the manual explication of transitive dependencies
d.) the manual linearization of execution and linkage
e.) mutual dependency
f.) the elimination of the need for build steps during development and
debugging.
g.) decoupling the utterance of dependencies from the order and timing
in which dependencies are transported in production.
h.) isolation of scopes
i.) isolation of internally consistent modules
j.) reliable linkage to independently develop, internally consistent
working sets of modules

Simple Modules will assist individual designers of coherent groups of
name spaces for the purpose of producing single internally consistent
applications and APIs.

Simple Modules, at present, will not sufficiently assist people
constructing applications and APIs by composing non-coherent groups of
name spaces produced by non-cooperating groups of developers.


In any case, that's my two bucks,
Kris Kowal


[1] http://wiki.commonjs.org/wiki/Packages/Mappings/B
[2] http://limi.net/articles/resource-packages/
[3] http://www.chromium.org/spdy/spdy-whitepaper
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Composition of Uncoordinated Working Sets of Modules

2010-06-04 Thread Kris Kowal
 is the identifier of the module from which this
// module was requested?  I need that to resolve the
// identifier of the request module.
when(fetch(id),
request.provideSource,
request.reject
);
} else {
var external = externalLoaders[parts[0]];
request.provideLoader(external, parts.slice(1).join(/));
}
})

I think it might be best to organize the syntax around MRL's rather
than local short-names.  MRL's can be reasonably short if they're
permitted to be relative paths, which requires the module loader
handler to receive the MRL of the requesting module.

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


Re: Modules: Name capture

2010-06-02 Thread Kris Kowal
On Wed, Jun 2, 2010 at 12:14 PM, David Herman dher...@mozilla.com wrote:
 but if you have a module graph of N modules, and each needs to be
 explicitly linked with N - 1 other modules, then you impose a
 quadratic code-size requirement on programmers. Unless, as I said,
 you beef up your linking-specification language.

I agree that requiring explicit linking is a non-starter.  I do
however favor the option of explicit linking at some level of
granularity.  At reasonable expense, Narwhal provides several layers
at which someone can buy-into explicit linking:

* by manually instantiating a module using the module constructor
  proferred by the loader.

var module = require.loader.load(id);
module(freeVariables);

* by manually instantiating a module using a facility of the sandbox
  that provides the import and export facilities but a.) does not
  memoize the module and b.) permits additional free variables to be
  injected.  This is useful for creating module-enhanged DSL's that
  permit scripts designed for QUnit or Bogart to be migrated without
  alteration, subverting their use of global variables with explicitly
  injected free variables.

require.once(id, freeVariables);

* by manually instantiating a system of modules with a preopopulated
  memo of module instances.

var SANDBOX = require(narwhal/sandbox);
var subRequire = SANDBOX.Sandbox({
modules: {
even: EVEN
}
});
var EVEN = subRequire(odd);

I would invoke the axiom, Simple should be easy, powerful should be
possible.  It's reasonable to pay for what you get.  At the risk of
misrepresenting their views, Ihab and Mark have argued that people
should always use explicit linking for a variety of reasons, but I for
one agree that implicit linking should be the norm, and explicit
linking can at least be deferred to the layer of packages, or
coherently designed sets of modules linking to other coherently
designed sets of modules.  I presume that it is possible to isolate
and explicitly link groups of modules.

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


Re: Tech talk on proxies and traits

2010-05-01 Thread Kris Kowal
On Fri, Apr 30, 2010 at 3:42 PM, Tom Van Cutsem to...@google.com wrote:
 Hi,
 I recently gave a Google tech talk on my joint work with Mark S. Miller on
 Harmony proxies and the traits.js library. Below is an abstract and a link
 to the video.

May I recommend that the enumerate method return a forEach-able
object, such that:

for (x in proxy) …

be reified as:

handler.enumerate().forEach(…)

albeit optimized for proper Arrays?

This would permit at least some degree of laziness.

I've also been working on a handler API for promises in CommonJS,
which has a reasonable degree of symmetry.  One thing that's occurring
to me is that it is probably desirable for a generic, potentially
frozen prototype handler to be exposed so that they can be explicitly
prototypically inherited and extended.  I'm not sure whether you've
specified that handlers must be records, owning all usable trap
properties, but that would preclude meta-object hierarchies.  I
suspect that these will be desirable and that exposing the base
handler prototype would be useful.

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


Re: Tech talk on proxies and traits

2010-05-01 Thread Kris Kowal
On Sat, May 1, 2010 at 6:25 PM, Brendan Eich bren...@mozilla.com wrote:
 W.r.t enumerate, a proxy could return a proxy for an array.

Would be satisfactory if the reification re-checked the length on each
iteration.

 Additionally, enumerate should be modified as soon as there is a solid
 proposal for generators/iterators.

Yeah, I caught that in the preso.  Sounds good to me.

 Dave Herman and I have a generators/iterators proposal coming along --
 should be up some time next week on the wiki.

Excellent.

 Not to worry, traps are accessed as handler properties, not own, just in
 (so possibly in a prototype). See
 http://wiki.ecmascript.org/doku.php?id=harmony:proxies_semantics. Example:

Excellent.

 Mozilla's implementation (see
 https://bugzilla.mozilla.org/show_bug.cgi?id=546590) already includes a
 no-op handler. We envision others that can be reused and delegated to via
 prototypes.

I see, in the unit test, makeNoopHandler.  My suggestion was that this
should be exposed as part of the API as a base type, but on further
reflection, the behaviors of the noopHandler are implied by the
non-existence of properties on the handler.

This is all excellent and I'm really glad it's getting such deeply
detailed attention.  Thanks.

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


forEach on next

2010-03-28 Thread Kris Kowal
[moving this thread onto es-discuss]

On Tue, Mar 23, 2010 at 2:45 PM, Brendan Eich bren...@mozilla.org wrote:
 On Mar 23, 2010, at 2:17 PM, Kris Kowal wrote:

 Aside: I hope we can resolve MarkM's suspicions of composability
 problems with generators; they are one of my very favorite features of
 Python: like UNIX pipes, composability is their middle-name.  The PEP
 he referenced some time ago just provides more terse syntax for
 chained generators; I find that this is a nicety but not a
 demonstration that the simple yield is flawed.

 Yes, just because something doesn't sing and dance  doesn't mean it is not a
 good actor ;-).

 I also hope that
 ECMAScript opts to follow the Python iterator protocol more closely
 than JavaScript 1.6—for chained lazy iterations, next needs to be
 the most discrete layer of the protocol, with forEach implemented in
 terms thereof.

 JS1.6 was forEach and other Array extras.

 JS1.7 introduced generators and iterators, and yes, we didn't incompatibly
 change the Array extras to treat iterators as arrays. We also didn't
 introduce new libraries, e.g. Python itertools workalikes. It's easy enough
 to do this in user-land, and hard for the TC39 committee to get  library
 design right.

Thanks for the clarification.

 At this point how would you make forEach and other Array extras work on
 iterators?

I'm getting all sorts of alarms going off in my head to the tune of
this is all obvious; I probably missed something important. Like,
this is how it works already. I've heard complaints about for each
loops stalling to collect though, so here are my thoughts about
iterators anyway:

I was just looking at some transcoding stream stuff, which follows the
general form of Python's iterator protocol.  The notion is that next
is the most atomic unit of the iterator protocol; if you have an
object that implements iterator, that returns an object that
implements next, you get forEach and friends for free.  This is
important because next is pausable (or progress on explicit
request, really), and forEach is not.  This means that you can
create incrementally iterable generics like mapIterator and thereby
create chains of decorated iterators that can operate on iterations of
indefinite length, and forEach doesn't have to collect the values of
the iterable before entering its loop.

/***
 * @this {Object}
 */
SomethingAutoIterable.prototype.iterator = function () {
return this;
};

/***
 * @this {{iterator}} any iterable object.  `iterator` must
 * return an object with a `next` method that returns the
 * next element of the iteration or throws `StopIteration`.
 */
SomethingAutoIterable.prototype.forEach = function (block, that) {
var line;
var iterator = this.iterator();
while (true) {
try {
line = iterator.next();
} catch (exception) {
if (exception === StopIteration)
break;
throw exception;
}
block.call(that, line);
}
};

If you're crazy, can optimize the crap out of the try/catches
(presumably by removing them for a small set of common types), and
want to take things one step further than Python, you can implement
both continue and break semantics by adding SkipIteration.

…forEach = function (relation, that) {
var iterator = this.iterator();
try {
while (true) {
try {
relation.call(that, iterator.next());
} catch (exception) {
if (exception !== SkipIteration) {
throw exception;
}
}
}
} catch (exception) {
if (exception !== StopIteration) {
throw exception;
}
}
};

And, if you're *really* crazy, you can implement breaking and
continuing outer loops by associating individual StopIteration and
SkipIteration instances with each iterator. By really crazy, I mean
that my PEP got shot down, so I wouldn't be surprised by a repeat
success.

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


Re: simple modules

2010-02-04 Thread Kris Kowal
On Thu, Feb 4, 2010 at 2:04 PM, Sam Tobin-Hochstadt sa...@ccs.neu.edu wrote:
 Module Name Manager/Context/Module Loader: An entity that specifies
 how to find modules, given their names or identifiers.  By creating
 these, programmers can manage what modules can be seen by what code.
 I think this (or the next item) is what Kris called a Context in his
 presentation at the face to face meeting.

The module primordials proposal includes a Context constructor that
creates what is presently an ES execution context and contains its
intrinsic primordials.  The concept of a Context in that proposal is
completely orthogonal from the entity that manages the process of
grabbing module code (Load/Loader) or linking and instantiating them
(Require, which I've called a Sandbox in the past).  It's my
impression that the module statement in your proposal is a Registrar,
or a module transport declaration [1] that enables modules to be
transported in Programs.  I do not understand the Linking and
Instantiation semantics of the Simple Modules proposal, but it's
possible that the concerns of registration, linkage and instantiation
have been combined and additionally coupled to what I called the
context, in which case it would be appropriate to call the entire
entity a Context.  However, I think that for the purpose of this
discussion, it is desirable to separate the layers and concerns so
that we can see the breadth of options.

Kris Kowal

[1] http://wiki.commonjs.org/wiki/Modules/Transport
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: simple modules

2010-02-03 Thread Kris Kowal
On Wed, Feb 3, 2010 at 12:39 PM, Brendan Eich bren...@mozilla.com wrote:
 On Feb 2, 2010, at 6:23 PM, Kris Kowal wrote:
 This verbiage implies black-listing.  It would be good to be clear
 that the object formerly known as a module context should be
 explicitly populated with a white-list of module instances for SES.

 Agreed, and good point.

 Oprah moment: something about the way you wrote makes me want to plead for
 goodwill assumptions in our informal exchanges. No one on the committee is
 trying to open up capability leaks or introduce ambient authority. I doubt
 anyone is unfamiliar with the problems of blacklisting. It seemed clear to
 me that Dave was not specifying rigorously, just giving two examples.

 (Ok, group hug :-P.)

My tone was definitely severe and the content lacked balancing
concessions. My apologies to David.

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


Re: simple modules

2010-02-02 Thread Kris Kowal
Would someone mind posting a summary of the current positions of the
active participants of this discussion, perhaps contrasting the
proposals?

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


Re: simple modules

2010-02-02 Thread Kris Kowal
Presuming that in the proverbial glossary a Context is what ES
presently calls an execution context that has some intrinsic
Primordials, and a Sandbox is a mapping from unique module
identifiers to modules (albeit instances or makers depending on what
proposal you're talking about), does this proposal suggest that there
is exactly one Context for every Sandbox and that any module
block statement evaluated in a context populates the corresponding
sandbox with a mapping from the given module identifier to the first
class exports object of that module?

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


Re: typed array strawman proposal

2010-01-26 Thread Kris Kowal
On Tue, Jan 26, 2010 at 10:43 AM, Vladimir Vukicevic
vladi...@mozilla.com wrote:
 Howdy,

 At Brendan's request, I've just added a new strawman proposal for ES typed
 arrays to the wiki.  This proposal comes from the WebGL group, which needed
 a way of efficient access to and manipulation of native machine-type arrays;
 once we came up with a reasonable baseline API, it looked like something
 that would be generally useful as more interop and performance demands are
 placed on ES.  Typed arrays is probably not the best name; but that's
 probably an easy bikeshed.

I've made three similar proposals over in CommonJS.

http://wiki.commonjs.org/wiki/Binary/B
http://wiki.commonjs.org/wiki/Binary/D
http://wiki.commonjs.org/wiki/Binary/E

ArrayBuffer is a strict subset of what I'm calling ByteArray (which
incidentally fits the TypeArray pattern you establish in your
proposal).  I think we could converge these proposals.  Yours is most
similar to Binary/B.  Binary/D adds some bit types and improved the
details a bit.  Bineary/E abandoned the notion that binary types could
become natives in CommonJS, removed the bit types, and reduced the API
significantly again.

To get closer to your proposal, it would probably be easier to start
from yours and add rather than start from one of mine and subtract.  I
recommend ByteArray for the name.  It matches the pattern you
establish for Integer Arrays.  Secondly, I think slice needs to
return an immutable fixed length type, or ought not be included.
Daniel Friesen proposed a Range type and a range method in
Binary/C which I incorporated in D and E.  range is like slice but
returns a view of the underlying buffer region and supports the
relevant subset of the ByteArray API.  With range, there is no
expectation of indefinite consistency.  I think the various aligned
typed arrays are a good idea, but I think CommonJS would be satisfied
if we were to agree on the byte array buffer type initially.

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


Re: quasi-literal strawman

2009-12-17 Thread Kris Kowal
I am also in favor of the quasi-literal type name not being mangled.
I would, in fact, consider making the quasi-literal type any
expression returning a function, even if this necessitates a
parenthetical expression.

You might consider refining the escaping rules to resemble rraw
strings as in Python.  That would afford a greater degree of
flexibility in escaping rules within the quasi-literal.  The only
difference is that in a raw string, only backslash before the same
quote character as the enclosing quotes and a backslash are treated as
escape characters and all others are preserved.  Then, the
quasi-literal function would be entirely in control of the meaning of
other escaped characters.

There's also a trade-off between using back-ticks and plain
double-quotes.  Using back-ticks affords us an opportunity to have a
default quasi-literal.  On the other hand, I don't miss having to
distinguish front and back ticks in Perl.  Also, it might be
undesirable to have to claim a variable name for the default case,
unless your intention is that the default quasi-literal have a
consistent behavior in any scope.

In one of my former language projects, I considered something similar
for numbers, in suffix.  For example: 3ce for thrice or 1mm for one
millimeter, where ce and mm were constructors in scope.

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


Re: Binary Data - possible topic for joint session

2009-11-14 Thread Kris Kowal
On Fri, Nov 6, 2009 at 11:24 AM, Brendan Eich bren...@mozilla.com wrote:
 Kris did a good job with Binary/B (although I do not see the point of the
 .get method additions) -- I didn't look at the other proposals yet.

Thanks.  The .get method is certainly not relevant for an ECMAScript
spec, where you have the luxury of specifying [[Get]] and [[Put]].
The .get method in the CommonJS proposal is intended to serve as a
stop-gap for implementations that cannot provide properties.

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


Typo in Annex E

2009-11-14 Thread Kris Kowal
The last paragraph of Annex E notes that getPropertyName is among
the divergences from ES3.  I presume this is intended to be
getPropertyNames with plural infection.

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


Hermetic Evaluation, Modules Strawman

2009-09-30 Thread Kris Kowal
I've begun my work on a second draft [1] of the module proposal that
Ihab and I put forth at the January meeting.  Just to get started, I
wanted to emphasize that all we need is hermetic evaluation, and
re-propose the interface for hermetic eval in light of experience with
the CommonJS [2] and Narwhal [3] implementations of the
SecurableModules [4] proposal Ihab and I made to that group a week
later.  We've made a lot of great progress in the last 9 months in
vetting the module system idea.

This new draft proposes that the primitive hermetic evaluator be more
like the Function constructor and permits early exceptions for
non-primordial, non-injected free variables.  The new proposal is
safer since it emphasizes that the module text must be a program
construct, makes explicit what names are being injected into the
program's scope, and explicates that, unlike with blocks, specific
names are injected into a function block scope instead of placing a
stock Object in the scope chain.

It's my intention to copy and edit sections of the original proposal
into the wiki, making minor revisions to match up with CommonJS
SecurableModules, the Module meta-object amendment [5], explicate
synchronous and asynchronous variations of importing modules, and to
specify the API's of module loaders and module sandboxes.  Ihab is
spearheading an effort on CommonJS to formalize packages of modules,
their layout, their metadata, how to verify their signatures, and how
to import modules from packages, which I hope to integrate in a future
draft.  We remain in discord about whether to conflate the name spaces
of injected capabilities and modules, but we had a good discussion
recently that might help us arrive at a compromise.

This all being said, between Object.freeze and hermetic evaluation, we
can do a lot in libraries without native language support so it's
worth kicking off a discussion around that feature early.

Kris Kowal

[1] http://wiki.ecmascript.org/doku.php?id=strawman:modules
[2] http://wiki.commonjs.org/wiki/CommonJS
[3] http://narwhaljs.org/
[4] http://wiki.commonjs.org/wiki/Modules/SecurableModules
[5] http://wiki.commonjs.org/wiki/Modules/Meta
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Spawn proposal strawman

2009-05-21 Thread Kris Kowal
 kevin curtis wrote:
 Is a 'canonical' AST part of the plans for ecmascript 6/harmony.

 On May 9, 2009, at 9:19 AM, David-Sarah Hopwood wrote:
 I hope so; that would be extremely useful. I would like to see an
 ECMAScript source - AST parser (as well as an AST evaluator) in the
 Harmony standard library.

On Sat, May 9, 2009 at 11:57 AM, Brendan Eich bren...@mozilla.com wrote:
 We've wanted this since early in ES4 days. It would help many projects and
 experimental extensions (type checkers, template systems, macro processors,
 etc.) to have a standard AST, which could be serialized to JSON.

Other neat uses for the AST would potentially include comment scraping
for automated documentation tools and minification, which have their
own requirements beyond those for execution, optimization, and static
analysis.

Upon further reflection, I'm not sure that parse(program:String):AST
would serve the purpose of fast sandboxing.  The intent of splitting
parse and execute is to reduce the cost of execution, so that modules
can be reused in many small sandboxes.  Having parse produce a
(mutable) AST, and then leaving execute to translate the AST for the
interpreter might constrain our options for producing the desired
performance.  It might be better to have a compile() routine that
returns an opaque, engine-specific Program object that can in turn be
executed multiple times.

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


Re: Spawn proposal strawman

2009-05-12 Thread Kris Kowal
On Mon, May 11, 2009 at 4:21 PM, Brendan Eich bren...@mozilla.com wrote:
 On May 11, 2009, at 4:10 PM, Kris Kowal wrote:
 Perhaps I'm behind on the times, but I'm under the impression that
 presently the behavior of this function foo declaration has no
 standard behavior:

 (function () {
  function foo() {
  }
 })();

 No, that's fully specified by ES3.

Once again, I've been chasing a JS phantom.  That cuts the complexity
of the options tree roughly in half.  Let's consider:

let asts = {};
let memos = {};

// loading
if (Object.prototype.hasOwnProperty.call(asts, id))
   return id;
let ast = parse(moduleText);
asts[id] = ast;

// executing
if (Object.prototype.hasOwnProperty.call(memo, id))
   return id;
let ast = asts[id];
let exports = memo[id] = {};
let require = Require(id);
execute(ast, {require, exports});

Furthermore, let's assume that execute enforces use lexical scope
and use strict.

These are the ramifications if I understand correctly:

 * free assignment becomes an error at run time.
 * free variable access, apart from primordials, require, and exports
throw reference errors.
 * the object bearing the primordials has no name.
 * global object has no name.
 * the bottom scope has no name.
 * default this for functions and the bottom-scope is undefined.
 * function statements are local to the module and only accessible lexically.
 * var and let declarations in the bottom scope.
 * require and exports get injected into the bottom scope.

What scope contains primordials?  Should primordials be injected into
the bottom scope before require and exports or should their be two
scopes (global, local) in a module?  I see several potential
definitions of execute:

execute(program:AST|String, scope);
 // wherein we create a new global scope and add require and exports
for each program

execute(program:AST|String, local);
 // wherein a shared frozen global scope is implied and a local scope
is pushed above it

execute(program:AST|String, global, local);
 // wherein we reuse the global scope frame and put require and
exports in a scope right above it

In both of these cases, Mark's comments about copying members to a
scope frame instead of using the object itself might apply.  I presume
that this is to avoid following the prototype chain when resolving a
variable.  If globals are shallowly copied into the local/bottom scope
of the module, some things get simpler.  For one, we can freeze the
global object without freezing the bottom of the scope chain, which
would impair module local declarations.  We also wouldn't need two
scopes initially.  However, it would be nominally slower.  I think
that execute should take two arguments either way, since it would be
inconvenient and slower than necessary to do this for every module
execution:

 var scope = copy(global);
 scope.require = Require(id);
 scope.exports = memo[exports] = {};
 execute(ast, scope);
  // scope chain is [Frame(scope)]

…since execute effectively hides an implicit copy to the scope frame,
making the explicit copy superfluous, as opposed to:

 var local = {
   require: Require(id),
   exports: memo[exports] = {}
 };
 execute(ast, global, local);
  // scope chain is [Frame(global), Frame(local)]

Is this on the right line of reasoning?

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


Re: Spawn proposal strawman

2009-05-11 Thread Kris Kowal
On Mon, May 11, 2009 at 9:26 AM, Brendan Eich bren...@mozilla.com wrote:
 On May 8, 2009, at 8:49 PM, Kris Kowal wrote:
 (function (require, exports) { + text + /**/\n}
 Nit-picking a bit on names: require : provide :: import : export -- so
 mixing require and export mixes metaphors. Never stopped me ;-).

I agree about mixing metaphors.  The befuddlement of start : stop ::
begin : end is one that bothers me a lot.  The notion is to desugar
import and export to these two facets, importing and exporting.
imports : exports would be proper, but doesn't read well in code.  The
reason for using the term exports is to ease migration, since:

 exports.a = function a() {};

Is easy to transform textually to:

 export a = function a() {};

So, I'm inclined to stick with exports instead of provide.  The
metaphor would be complete if we used imports(id) or import(id).
Since import is a keyword, it would not be available for the
desugarred syntax.  That leaves imports.

 const {a} = imports(module);


 What makes functions eval'ed hermetically by the module function occur in a
 statement context? They should be nested function declarations, not
 (sub-)statements. Or I'm missing something.

Perhaps I'm behind on the times, but I'm under the impression that
presently the behavior of this function foo declaration has no
standard behavior:

(function () {
   function foo() {
   }
})();

If foo gets bound in function block scope, there's no problem (which
is the case in most browsers, I believe), but if it gets bound as a
member of global, that would be a problem, and if it gets bound like a
free assignment, it would only be a problem if free assignment isn't
localized to the module somehow.


 This is a language change. ES1-5 put free variables created by assignment in
 the object at the bottom of the scope chain.

I'm of course in favor of changing as little as possible.  If the
bottom-most scope is unique to the present module instead of the
global object, there's no need for change here.


 Mark is citing a proposal that *removes* the global object from the scope
 chain; that proposal does not fiddle with where declared and free vars go.

Alright, I'm following now.  I'll explain why I think that this would
be sufficient to fix some problems, although perhaps not necessary.


 Implementations would need to decouple the top of the scope chain and
 the global object.

 Implementations can do this easily, but the issue is language-level: is the
 global object at the bottom of the scope chain? So far, it is.

I've operated on the assumption that the global object was on the
bottom of the scope chain.  There are some concerns about module texts
for parsing and interpreting modules, some of which might be
sufficiently addressed by moving global off the scope chain for module
evaluation, but perhaps not necessarily.

 * free assignment.  I'm less concerned about the behavior of free
assignment.  I'd prefer assignment to global to be explicit, but this
ship may have sailed long ago.  It might be more appropriate for free
assignment to create module locals or module exports, which could be
accomplished by changing the bottom-of-the-scope-chain, or by changing
the behavior of free assignment in the context of a hermetic eval.  In
any case, this is not something I'm deeply concerned with.
 * function statements.  These really must be module local.  I'm not
in-the-know about whether this is a problem or not.  In the case where
hermetic eval runs a program, we'd have to wrap the program in a
function declaration.  In that case, if function statements create
function block scope locals, there's no problem.  If they operate like
free assignment, then there's a problem if the bottom-scope is
global, but not if it's a module local object.  If hermetic eval
returns a module factory function that runs a program with a given
require and exports object, function statements would occur in the
bottom-scope.  In that case, it would be a problem if the bottom-scope
were global, whether or not function statements behave like free
assignment or function block scope declarations.
 * return statement.  This should be a parse error in the top most
scope of a module.  If hermetic eval wraps a module's text in a
function declaration, the return statement would not be a parse error,
which would be a problem.  If heremetic eval returns a function that
executes the module with a given require and exports object, then
return would be a parse error in the bottom-scope.
 * injection attack strings.  These are a weakness of using a hermetic
eval that immediately evaluates a module factory function expression
with the module text inside.

In present implementations, it's possible to have globals available as
free variables by replacing the bottom-scope-chain object with one
begotten from globals.  I'd concede that this is a hack.

Here's a pseudo-code representation of our options and their ramifications:


running a module looks like:
   let require

Re: Spawn proposal strawman

2009-05-08 Thread Kris Kowal
 hope we
can provide a switch on the sandbox machinery so the application
programmer can chose whether they want light-weight sandboxes or heavy
ones.

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


Re: Universal Feature Detection

2009-04-29 Thread Kris Kowal
On Wed, Apr 29, 2009 at 5:30 AM, David-Sarah Hopwood
david-sa...@jacaranda.org wrote:
 David Foley wrote:
 Please forgive me if I'm polluting the list, and re-direct me if I am,
 but considering that  there has been so much focus on browser
 implementation,  that JavaScript is also employable in various
 'environments' (IDE's, Servers etc.) and that all of these environments
 avail different features to developers, that a universal / standard
 feature detection API, perhaps through a standardised global Environment
 object, would be prudent.

 Are there any plans to do such?

 There will probably be some kind of module system in ES-Harmony
 (which will be prototyped before then). It would make sense for that
 to support querying whether a given module is available, its version,
 and other metainformation about it.

Ihab Awad and I made an initial proposal for a module system for
Harmony in January, and presented it to TC39.

Proposal: http://docs.google.com/Doc?id=dfgxb7gk_34gpk37z9vhl=en
Presentation: http://docs.google.com/Presentation?docid=dcd8d5dk_0cs639jg8hl=en

Since then, we've been working closely with a group called ServerJS
that is creating a standard library for server-side JavaScript, with
participants working on prototypes for {Spider,Trace}monkey
(Flusspferd, GPSEE), V8 (v8cgi, k7), and Rhino (Helma NG, Persevere,
Narwhal).  They've converged on a module system specification that is
very close in form to the initial phase of our proposal (that is,
without syntactic sugar). The proposal and links to the relevant
discussions, which have been extensive, are on the Moz wiki:

https://wiki.mozilla.org/ServerJS/Modules/SecurableModules
https://wiki.mozilla.org/ServerJS/Modules
https://wiki.mozilla.org/ServerJS

The proposal does not require augmentation to the global name space,
but it might be desirable.  In the proposal, there's a require free
variable in the module, and various prototypes inject the free
variable into the module's scope, some as an argument to the module
factory function, some as a member of a fresh context object begotten
of global.  So, within modules, there's no need for a global variable.
 There are a couple known options for loading the main, or initial
module.  One of them is to add a require method to the global object.
Another is to introduce a variant of the script tag that loads a
module instead of a global script.  Chiron, my client-side prototype,
uses a script tag to bootstrap a module loader and loads the module in
the script src query string.

Regarding feature testing, the module system might be useful since the
platform, albeit browser, could provide features as modules, in
which case calling require on that module's identifier would throw
an error.  Some prototypes have a require.isLoaded(id) method that
could be used to test whether modules provided by the platform have
already been loaded, without having to catch a require error.

However, these ideas probably don't obviate the need for a feature
testing system for layout, rendering, event, and other features and
quirks that might not be neatly distinguished based on the
availability of a module.

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


Re: Remarks about module import

2008-08-23 Thread Kris Kowal
much like /usr/lib/libc.so usually symlinks to /usr/lib/libc.so.5
on Unices.

So, I recommend that modules be identified by URL's, although not
necessarily Strings since that might compromise static analysis again.
 I also think that, borrowing a meme from python3k, if a URL begins
with a dot, it be module relative.  Consider (where import stands in
for some yet to be determined keyword):

   // in http://my.com/site.html where the moduleRoot is the same
as the page URL by implication:
   import window; // moduleScope.window = require(window);
   import http://jquery.com/jquery-2.6.js;; // moduleScope.jQuery =
require(...);
   import ./widget.js as widget; // moduleScope.widget =
require(http://my.com/widget.js;);
   from ./widget.js import Widget; // moduleScope.widget =
require('http://my.com/widget.js').Widget;

On the topic of PATH, it occurs to me that a page could potentially
subscribe to a module root either hosted by the browser in chrome://
or potentially on a CDN like Google's AJAX modules.  That might answer
my performance concern from walking the PATH and hitting a 404,
extending page load times by a Round-trip-time for each missed module.

This leaves the issue of bundling.  Web page authors will still need
to concatenate scripts and CSS to improve a page load's performance.
To that end, I recommend that module's have a provide or register
function, wherein they can, in a single module, provide a bundle of
module objects that they construct themselves, or declare in the same
way that they would in another file.

   provide(./widget.js, widgetModule.freeze());

   provide ./widget.js {
   }

I'll leave it to the Ihab or Mike to comment on the security
implications of bundling; I suspect they are dire.  Perhaps only
modules in subordinate URLs can be provided by one module.  That's
another tension we should consider.

There was mention on the original wiki page of requiring module
dependencies to form a directed acyclic graph (ok, a tree).  I don't
believe this is any more necessary than in Python, where it's
desirable by not enforced.  Since module objects are singleton and
registered before a module is evaluated, modules have the option of
providing their partially completed module objects to cyclic
dependencies.

Not having a solid module system is my biggest pain-point in modern
JavaScript.  Without it, JavaScripters are relegated to using best
practices and design patterns to make their scripts more but not quite
portable, and more but not quite secure.  I've managed to make most of
these features possible in user-space JavaScript using a collection of
naughty practices like gratuitous use of eval and with and I
consider the sacrifice worthwhile, but something similar needs to just
be natively available for security and ubiquity.  I have great hope
for the fruit of this discussion.

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


Re: Remarks about module import

2008-08-23 Thread Kris Kowal
Peter,

 Can you provide concrete examples (something a few lines longer than a
 hello world module) which shows both the module and importer code?

sink.js

/**
this module provides a `sink` function which allows the
user to cause a DOM element to forward its events to
one and only one, detachable Widget object that implements
`./event.js#Signaler`.
*/

/* these are modules by the same author, in the same directory */
from ./urllib.js import urlJoin;
from ./base.js import Set;
/* this is a cross-browser compatibility layer */
from ./browser.js import normalizeEventName, browserEventName;
/* presumably browser is a module provided by the browser in some
 * cross-browser compatible way. */
from chrome://js/browser.js import observe;

/* using let or var makes a variable private to the module */
let widgetNs = urlJoin(__FILE__, '#widget'); // or
let widgetNs = urlJoin(moduleUrl, '#widget');
let sinksAttribute = urlJoin(__file__, '#sinks');
/* the name __FILE__, moduleUrl, __file__, or __DIR__
 * isn't as important as the behavior.  It would not
 * be onerous to provide both module file and dir variables,
 * but dir can be inferred from file and is best
 * dealt with via urlJoin which handles both cases unless
 * the provider of __DIR__ is unscrupulous about the
 * final forward-slash. */

/* assigning to this makes it an export */
this.sink = function (element, widget, eventName) {
if (element[widgetNs]  element[widgetNs] != widget) {
element[widgetNs].final();
}
element[widgetNs] = widget;
let sinks = element.getAttribute(sinksAttribute);
element[sinksNs] = sinks;

let normalizedEventName = normalizeEventName(eventName);
let browserEventName = browserEventName(eventName);

if (!sinks.has(normalizedEventName)) {
observe(element, browserEventName, function () {
let widget = this.target[widgetNs];
widget.signal(normalizedEventName, this);
});
sinks.insert(normalizedEventName);
}

/* break reference cycles */
widget = undefined;
element = undefined;
};


index.js

from ./sink.js import sink; // or
let sink = require(./sink.js).sink;
from http://jquery.com/dist/jQuery.10.1.js; import jQuery as $
from ./my-widget.js import MyWidget
sink($('#widget'), MyWidget());


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