More flexibility in the ECMAScript part?
Le 18/04/2013 09:40, Anne van Kesteren a ?crit :
On Thu, Apr 18, 2013 at 4:07 AM, Tab Atkins Jr. <jackalmage at gmail.com> wrote:
Note that Futures are entirely expressible in today's JS semantics.
(Not to say that it shouldn't be reviewed by the language gurus here, just saying.)
JavaScript does not have an event loop (as I mentioned elsewhere) so that is not true. HTML defines the event loop model and processing model for any asynchronous JavaScript execution. Lifting that up to JavaScript seems difficult.
What do you expect to be difficult? I foresee that it's going to be a lot of work on both sides (W3C/WHATWG & TC39) to move this major piece from one place to another without breaking anything. But I would say it's a lot of "easy" work. It's going to take a lot of eyeballs and probably tests to make sure what the new spec jonction between HTML LS and ES7 conforms to what exists in reality (expecially in the new prose). Is there a particular part of this work that you expect to be difficult.
On Thu, Apr 18, 2013 at 8:48 AM, David Bruant <bruant.d at gmail.com> wrote:
Le 18/04/2013 09:40, Anne van Kesteren a ?crit :
On Thu, Apr 18, 2013 at 4:07 AM, Tab Atkins Jr. <jackalmage at gmail.com> wrote:
Note that Futures are entirely expressible in today's JS semantics.
(Not to say that it shouldn't be reviewed by the language gurus here, just saying.)
JavaScript does not have an event loop (as I mentioned elsewhere) so that is not true. HTML defines the event loop model and processing model for any asynchronous JavaScript execution. Lifting that up to JavaScript seems difficult.
What do you expect to be difficult? I foresee that it's going to be a lot of work on both sides (W3C/WHATWG & TC39) to move this major piece from one place to another without breaking anything.
I don't think that's true at all. We're never going to be able to standardize on ONE event-loop, nor even be able to require that implementations have them...indeed, we've been pretty careful in designs like Object.observe() to avoid dependencies on it.
What we can (and should) do is to say "if you have an event loop, some primitives behave in this way relative to turns". That doesn't require breaking anything.
But I would say it's a lot of "easy" work. It's going to take a lot of eyeballs and probably tests to make sure what the new spec jonction between HTML LS and ES7 conforms to what exists in reality (expecially in the new prose).
Yes, we'll need lots of tests, but the real world gets on fine with event loops and lots of fine-grained, timing-dependent APIs in the web platform today across multiple implementations. We don't have it any harder than any other spec does in that regard.
Le 18/04/2013 13:28, Alex Russell a écrit :
On Thu, Apr 18, 2013 at 8:48 AM, David Bruant <bruant.d at gmail.com <mailto:bruant.d at gmail.com>> wrote:
Le 18/04/2013 09:40, Anne van Kesteren a écrit : On Thu, Apr 18, 2013 at 4:07 AM, Tab Atkins Jr. <jackalmage at gmail.com <mailto:jackalmage at gmail.com>> wrote: Note that Futures are entirely expressible in today's JS semantics. (Not to say that it shouldn't be reviewed by the language gurus here, just saying.) JavaScript does not have an event loop (as I mentioned elsewhere) so that is not true. HTML defines the event loop model and processing model for any asynchronous JavaScript execution. Lifting that up to JavaScript seems difficult. What do you expect to be difficult? I foresee that it's going to be *a lot* of work on both sides (W3C/WHATWG & TC39) to move this major piece from one place to another without breaking anything.
I don't think that's true at all. We're never going to be able to standardize on ONE event-loop, nor even be able to require that implementations have them...indeed, we've been pretty careful in designs like Object.observe() to avoid dependencies on it.
What we can (and should) do is to say "if you have an event loop, some primitives behave in this way relative to turns". That doesn't require breaking anything.
I believe the ES spec should provide the primitives of what type of interaction with the message queue is allowed and what isn't. This set of primitives would obviously contain all the interactions allowed today by HTML5.
For now, I'm aware of only these types of interactions:
- add a message to the queue LIFO-style (which is the default?)
- add a message to the queue FIFO-style also known as "add for the next turn"
- remove a message (clearTimeout which cancels a message added via a setTimeout message).
At least it's not possible to remove an arbitrary message.
There are probably reordering policies that need to be described as well.
I'm not saying these primitives should necessarily be exposed to the runtime directly, but at least to other specs.
Are there other types of interactions with the message queue I'm forgetting?
On 18/04/2013, at 14:40, David Bruant wrote:
I believe the ES spec should provide the primitives of what type of interaction with the message queue is allowed and what isn't. This set of primitives would obviously contain all the interactions allowed today by HTML5.
For now, I'm aware of only these types of interactions:
- add a message to the queue LIFO-style (which is the default?)
This isn't neccessary,
- add a message to the queue FIFO-style also known as "add for the next turn"
This is the only one needed,
- remove a message (clearTimeout which cancels a message added via a setTimeout message).
and this has nothing to do with the events queue.
Le 18/04/2013 14:59, Jorge a écrit :
On 18/04/2013, at 14:40, David Bruant wrote:
I believe the ES spec should provide the primitives of what type of interaction with the message queue is allowed and what isn't. This set of primitives would obviously contain all the interactions allowed today by HTML5.
For now, I'm aware of only these types of interactions:
- add a message to the queue LIFO-style (which is the default?) This isn't neccessary,
- add a message to the queue FIFO-style also known as "add for the next turn" This is the only one needed,
If you only have this one, then you can end up in situations where user inputs are never processed. The 1) is necessary. I assume some re-ordering policies/primitives might be necessary too.
- remove a message (clearTimeout which cancels a message added via a setTimeout message). and this has nothing to do with the events queue.
Can you develop your 3 answers, please? Throwing agreement/disagreement without providing reasons doesn't help the debate to move forward. Timeouts do interact with the event loop at least in the WHATWG spec (see step 10 of [1] as an example)
David
[1] www.whatwg.org/specs/web-apps/current-work/multipage/timers.html#dom
On Thu, Apr 18, 2013 at 6:11 AM, David Bruant <bruant.d at gmail.com> wrote:
Le 18/04/2013 14:59, Jorge a écrit :
On 18/04/2013, at 14:40, David Bruant wrote:
I believe the ES spec should provide the primitives of what type of
interaction with the message queue is allowed and what isn't. This set of primitives would obviously contain all the interactions allowed today by HTML5.
Agreed. Further, ES can't avoid specifying event loops, perhaps even in an ES6 timeframe!! It would indeed be unfortunate if we need to specify this in ES6. But I don't see how we can specify module loaders without doing so. The only alternative I see is that we postpone module loaders till ES7, which many of us (including myself) would find unpleasant.
Although I do not want to see module loaders postponed till ES7, for completeness I will mention one further advantage of doing so. Currently, module loaders are specified in terms of callbacks. Were they postponed, we could instead specify their API in terms of promises. The similarity to the spec dependency dilemmas motivating this thread are indeed striking.
For now, I'm aware of only these types of interactions:
- add a message to the queue LIFO-style (which is the default?)
This isn't neccessary,
- add a message to the queue FIFO-style also known as "add for the next
turn"
This is the only one needed,
If you only have this one, then you can end up in situations where user inputs are never processed. The 1) is necessary. I assume some re-ordering policies/primitives might be necessary too.
LIFO isn't the way the browser specs deals with this issue. Rather, both the browser specs[*] and, lately, nodejs have adopted a two priority event loop, which can be accurately modeled (and implemented) as two fifo queues; call them "inner" (or high priority) and "outer" (or low priority). An outer turn thus consists of a sequence of inner turns. In the browser, rendering only happens as an outer turn. Object.observe and DOMFutures are both careful to queue events only in the inner queue, so all the observation events queued in an outer turn happen within inner turns at the end of that outer turn without the possibility of any intervening rendering.
IO events at least usually queue in the outer queue. Is this always the case? Do any IO events queue in the inner queue?
The Q API has historically queued only in the outer queue. The Q community has lately been debating this issue and tending towards having local Q events queue in the inner queue. Of course, distributed messaging, being layered on IO, would still queue only in the outer queue, but this doesn't seem to create any conflicts.
[*] The HTML5 specs adopt different terminology which obscures the similarity of the two levels of event loop queueing. But it is equivalent to this uniform two-level model.
- remove a message (clearTimeout which cancels a message added via a
setTimeout message).
and this has nothing to do with the events queue.
Can you develop your 3 answers, please? Throwing agreement/disagreement without providing reasons doesn't help the debate to move forward. Timeouts do interact with the event loop at least in the WHATWG spec (see step 10 of [1] as an example)
You don't need to account for cancellation in terms of event queue manipulation. And I agree with (what I believe to be) Jorge's position, that it is less clean to do so. Rather, you can just think of the queued event as having the behavior "do this if it isn't cancelled" and the cancellation as setting a cancellation state to be so tested by that queued event once it fires. Of course, if implemented this way, it would fail to reclaim as much storage. But that's not an observable difference, so the spec can simply use the simpler model.
Agreed. Further, ES can't avoid specifying event loops, perhaps even in an ES6 timeframe!! It would indeed be unfortunate if we need to specify this in ES6. But I don't see how we can specify module loaders without doing so. The only alternative I see is that we postpone module loaders till ES7, which many of us (including myself) would find unpleasant.
Another upside would be easing the near-term workload on TC39 (and Allen most of all).
Although I do not want to see module loaders postponed till ES7, for
completeness I will mention one further advantage of doing so. Currently, module loaders are specified in terms of callbacks. Were they postponed, we could instead specify their API in terms of promises. The similarity to the spec dependency dilemmas motivating this thread are indeed striking.
Part of the problem is that hitherto the core standard library and platform library (DOM) share the same namespace. As such, any activity in this shared namespace has an oversized influence on other designers. Perhaps modules can rectify this situation. What if, going forward, DOM APIs were homed in their own module namespace?
import Future from "dom:future";
let future = new Future({ resolve, reject } => resolve("Anne rocks!"));
I would probably leave the standard core library in the global lexical namespace:
let promise = new Promise({ resolve, reject } => resolve("Mark
rocks!"));
There is still a clash, to a certain degree, but the effects are much more localized.
Le 18/04/2013 17:35, Kevin Smith a écrit :
Also, can someone point me to a real-world example of delayed rejection handling?
What do you mean by "delayed"? If that is: a promise has been rejected and someone later add a .fail/.catch handler to it, then I've never done that personally. If you have another definition, I may have real-world examples, based on your definition.
Also, can someone point me to a real-world example of delayed rejection handling?
What do you mean by "delayed"? If that is: a promise has been rejected and someone later add a .fail/.catch handler to it, then I've never done that personally.
Yes, that's what I mean. Specifically, a real-world example where the rejection handler is added in "some future turn", using a fuzzy definition of that phrase. A contrived example would be:
// Create a future and get the resolver
let resolver, future = new Future(r => resolver = r);
// Reject it
resolver.reject("error");
// Attach a rejection handler 5 seconds later
setTimeout(() => future.then(null, err => null), 5000);
On Thu, Apr 18, 2013 at 9:14 AM, Kevin Smith <zenparsing at gmail.com> wrote:
Also, can someone point me to a real-world example of delayed rejection handling?
What do you mean by "delayed"? If that is: a promise has been rejected and someone later add a .fail/.catch handler to it, then I've never done that personally.
Yes, that's what I mean. Specifically, a real-world example where the rejection handler is added in "some future turn", using a fuzzy definition of that phrase. A contrived example would be:
// Create a future and get the resolver let resolver, future = new Future(r => resolver = r); // Reject it resolver.reject("error"); // Attach a rejection handler 5 seconds later setTimeout(() => future.then(null, err => null), 5000);
There are several DOM APIs planning to use Futures which will return the same future across multiple calls. This future may have been rejected in a previous turn.
An example of this is the Font Load API built with Futures that I'm
currently proposing: www.xanthir.com/b4PV1. The Font#ready
function tracks the loading status of a single @font-face
rule, so it
just returns the same future over and over.
These kinds of APIs could be done by tracking future state internally, and always returning a fresh future matching the internal state, but that seems silly.
thanks for a concrete example. From previous experience in E with similar promises, I agree that registering handlers later is quite natural, but I didn't have time to hunt for an example.
It would indeed be silly to require such a counter-intuitive freshness workaround in order to avoid a counter-intuitive diagnostic.
On Thu, Apr 18, 2013 at 7:42 AM, Mark S. Miller <erights at google.com> wrote:
You don't need to account for cancellation in terms of event queue manipulation. And I agree with (what I believe to be) Jorge's position, that it is less clean to do so. Rather, you can just think of the queued event as having the behavior "do this if it isn't cancelled" and the cancellation as setting a cancellation state to be so tested by that queued event once it fires. Of course, if implemented this way, it would fail to reclaim as much storage. But that's not an observable difference, so the spec can simply use the simpler model.
Further, some event-queue APIs explicitly do auto-cancelling with the "check just before they would run" semantic. The name of one I was discussing with coworkers recently is escaping me, but it's required to do the just-in-time verifying, because whether or not the event finally fires is dependent on the state of something else at that exact moment.
(It could have been written in terms of cancelling, but it would have been much more complicated, as anything that manipulated the state it checked would also have to know to clean out the event queue.)
There are several DOM APIs planning to use Futures which will return the same future across multiple calls. This future may have been rejected in a previous turn.
Ah - excellent. The general idea is that the framework or platform is initiating an async operation without waiting for someone to request it. This use case would surface in any framework with inversion of control.
Le 18/04/2013 05:07, Tab Atkins Jr. a ?crit :
Allen was concerned about the "ECMAScript" definition of what you're loosely calling "JS" while it seems you're referring to "web platform enhanced JavaScript" Specifically, the current semantics uses "queue a task" which interacts with the event loop which is part of the web platform, but not ECMAScript.
I've read intention to move the event loop from HTML Living Standard to ECMAScript 7, but we're not there yet and that work is necessary before adding promises to ECMAScript.