Why not Profiles? (was: Bringing setTimeout to ECMAScript)

# Mark S. Miller (15 years ago)

On Sun, Mar 20, 2011 at 8:56 AM, David Herman <dherman at mozilla.com> wrote:

I said that WHATWG has done some on work specifying what currently happens in browser (joining with your idea of "be[ing] compatible with existing event queue semantics"). One idea would be to see what they've done, get inspired and specify the event queue in ECMAScript.

OK. I'm on board for that. I'm not committing to ES.next, though; IMO, new features are more important than specifying things that are only de facto standards but generally working pretty well.

Why do you think setTimeout is so special? It seems like just another host-environment API like, say, onClick. It provides access to one of the host environment's system service. I agree that it can be considered as an host-environment API. However, setTimeout seems to be widely implemented. I think it makes more sense to specify it within ECMAScript.

I suppose so.

It could be an occasion to specify what happens when you're in strict mode and you do setTimeout("alert(this)", 0). Is this string interpreted as strict eval code? There is a spec hole here. Bringing setTimeout to ECMAScript would be an occasion to answer the question and not let implementors do whatever they prefer or even to forget the question. This would avoid yet another de facto standard.

That question is orthogonal.

It's only one instance of a larger question, which is what happens when a host environment is asked to trigger JS code and it's not obvious which mode to use. For example, <a onclick="alert(this)">click me</a>. This does not need to be, and shouldn't be, a problem solved exclusively for setTimeout.

Instead, we will have to deal with this -- as always -- in a way that masks out specifics of the browser, but deals with the notion of "legacy mode" evaluation. This is at least in spirit what the purpose of the versioning strawman is for. There's lots of work left to do there.

How is this element's absence any more important than the absence of, say, onMouseover? Granted, it has more applicability than just the browser (since node.js uses it), but as Kyle's already pointed out, some embeddings may not want to expose the system clock. Actually, a conforming ES5 implementation implements Date.now(). In that condition, it's hard to not expose the system clock, or am I missing something?

Sorry, you're absolutely right there. I was completely overlooking Date.now().

Now, an implementor may not want to have to implement an event queue. I won't try to speak for implementors. But setTimeout introduces a different overall program control flow model than the old start-compute-exit model. Most JS embeddings use the interactive, event queue-based model, but it sounds like at least Kyle's doesn't.

But that alone should probably not stop us from moving ahead with concurrency. If an engine wants to provide a sequential JS, they can probably just do so and say they're conformant with everything except for the concurrency parts. Or maybe we can highlight the concurrency parts of the spec and say a sequential JS doesn't have to implement them.

I like this approach, so much that I changed the subject line ;). It gets us back into a practice that tc39 had and dropped before I joined, defining subsets or "profiles" of the full language as normative specs one could conform to. My SES work is essentially such a profile. Some CommonJS folks are considering requiring all CommonJS modules to be compat with ES5/strict, and treating them as such whether they say "use strict" or not. A server-side engine that dropped support for non-strict code could be much simpler. All of these seem like sensible profiles to give normative names to.

So I was wondering, why has our common wisdom become to avoid standard profiles? Do these reasons apply to such cases?

# Brendan Eich (15 years ago)

On Mar 20, 2011, at 9:14 AM, Mark S. Miller wrote:

On Sun, Mar 20, 2011 at 8:56 AM, David Herman <dherman at mozilla.com> wrote:

But that alone should probably not stop us from moving ahead with concurrency. If an engine wants to provide a sequential JS, they can probably just do so and say they're conformant with everything except for the concurrency parts. Or maybe we can highlight the concurrency parts of the spec and say a sequential JS doesn't have to implement them.

I like this approach, so much that I changed the subject line ;). It gets us back into a practice that tc39 had and dropped before I joined, defining subsets or "profiles" of the full language as normative specs one could conform to.

Last we checked, almost no one in TC39 wanted to take this on.

ES5 strict is already a dialect of ES5 that has different runtime semantics, not just syntactic restrictions (early errors). Implementors are still rolling stones uphill to get it implemented correctly and to get errant sites evangelized and fixed.

Adding more "profiles" just adds to the combinatorics, even if you try to nest profiles as subsets. More to check, more to go wrong, more work in committee now and in the field later (interop bugs), more time to complete the whole ES.next. Compound that over .next.next, etc. and you get path dependencies that can paint us into corners, magnifying mistakes.

This path dependency exists no matter what, but the fewer profiles or versions, the better. Harmony of my dreams is an opt-in language "close to JS today" but with a handful of incompatible changes, almost all of them caught by early errors (typeof null === "null" is the current exception requiring more aggressive static analysis than a common implementation can afford, or all-paths test coverage).

My SES work is essentially such a profile. Some CommonJS folks are considering requiring all CommonJS modules to be compat with ES5/strict, and treating them as such whether they say "use strict" or not. A server-side engine that dropped support for non-strict code could be much simpler. All of these seem like sensible profiles to give normative names to.

So I was wondering, why has our common wisdom become to avoid standard profiles? Do these reasons apply to such cases?

See above. I've been through this over the years in many context: X, PHIGS/PEX, *GL, MPEG, NFS. We can't avoid some amount of versioning over years and decades (even HTML is versioned by doctype). But we can certainly avoud jumping in with both feet to compound the problem (quadratically, worst case).

# Brian Kardell (15 years ago)

Im not a member of any group, but I follow closely and fwiw, I would like to offer an outside "+1" to Brendan's comments above. Differences and versioning problems and things are going to arise naturally no matter how well things are planned, better to introduce as few of them upfront as possible (preferably none is the goal). On Mar 20, 2011 2:17 PM, "Brendan Eich" <brendan at mozilla.com> wrote:

On Mar 20, 2011, at 9:14 AM, Mark S. Miller wrote:

On Sun, Mar 20, 2011 at 8:56 AM, David Herman <dherman at mozilla.com>

wrote:

But that alone should probably not stop us from moving ahead with

concurrency. If an engine wants to provide a sequential JS, they can probably just do so and say they're conformant with everything except for the concurrency parts. Or maybe we can highlight the concurrency parts of the spec and say a sequential JS doesn't have to implement them.

I like this approach, so much that I changed the subject line ;). It gets

us back into a practice that tc39 had and dropped before I joined, defining subsets or "profiles" of the full language as normative specs one could conform to.

Last we checked, almost no one in TC39 wanted to take this on.

ES5 strict is already a dialect of ES5 that has different runtime

semantics, not just syntactic restrictions (early errors). Implementors are still rolling stones uphill to get it implemented correctly and to get errant sites evangelized and fixed.

Adding more "profiles" just adds to the combinatorics, even if you try to

nest profiles as subsets. More to check, more to go wrong, more work in committee now and in the field later (interop bugs), more time to complete the whole ES.next. Compound that over .next.next, etc. and you get path dependencies that can paint us into corners, magnifying mistakes.

This path dependency exists no matter what, but the fewer profiles or

versions, the better. Harmony of my dreams is an opt-in language "close to JS today" but with a handful of incompatible changes, almost all of them caught by early errors (typeof null === "null" is the current exception requiring more aggressive static analysis than a common implementation can afford, or all-paths test coverage).

My SES work is essentially such a profile. Some CommonJS folks are

considering requiring all CommonJS modules to be compat with ES5/strict, and treating them as such whether they say "use strict" or not. A server-side engine that dropped support for non-strict code could be much simpler. All of these seem like sensible profiles to give normative names to.

So I was wondering, why has our common wisdom become to avoid standard

profiles? Do these reasons apply to such cases?

See above. I've been through this over the years in many context: X,

PHIGS/PEX, *GL, MPEG, NFS. We can't avoid some amount of versioning over years and decades (even HTML is versioned by doctype). But we can certainly avoud jumping in with both feet to compound the problem (quadratically, worst case).