Disallow `void`

109 views
Skip to first unread message

Tim Ruffles

unread,
Oct 14, 2015, 4:29:29 AM10/14/15
to Strengthen JS
In the interests of cleaning up the language, how about removing `void` in strong mode?

Sébastien Doeraene

unread,
Oct 14, 2015, 4:52:05 AM10/14/15
to Tim Ruffles, Strengthen JS
Hi,

Please don't. `void 0` is the most efficient and most robust way to get the `undefined` value. By robust, I mean it can't be affected by definitions of `var undefined = 4;` in the scope. It is extremely useful for compiler writers.

Cheers,
Sébastien

On Wed, Oct 14, 2015 at 10:29 AM, Tim Ruffles <timru...@googlemail.com> wrote:
In the interests of cleaning up the language, how about removing `void` in strong mode?

--
You received this message because you are subscribed to the Google Groups "Strengthen JS" group.
To unsubscribe from this group and stop receiving emails from it, send an email to strengthen-j...@googlegroups.com.
To post to this group, send email to streng...@googlegroups.com.
To view this discussion on the web, visit https://groups.google.com/d/msgid/strengthen-js/db9001c0-0ca0-49f1-b3df-b8736c693c43%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Sébastien Doeraene

unread,
Oct 14, 2015, 5:45:21 AM10/14/15
to Tim Ruffles, streng...@googlegroups.com
Hi,

I think you misunderstood my argument. It doesn't matter whether you're compiling a piece of code that has a local var named `undefined`. Any decent compiler will rename it in the process of compiling, just like it would rename a var named `function` if that happens to be a valid identifier in the source language.

The problem is that your compiled code will end up within some JS scope, and it *might* just be that the surrounding scope (which the compiler never saw in the first place) defines a `var undefined`. The only way the compiler can protect its generated code from outside interference is to not use `undefined` even to get the `undefined` value. You have to use an expression evaluating to `undefined`, which does not use the `undefined` global variable. Currently, `void 0` is the best way to do that, because it's quite short, and it can trivially be constant-folded by the JS compiler into its internal representation for `undefined`. It is even easier to do so than to constant-fold `undefined` to the undefined value (precisely because `undefined` could be redefined). Other ways to get the undefined value in strong mode are actually quite verbose and much uglier, e.g., `(function(){})()`.

Cheers,
Sébastien

On Wed, Oct 14, 2015 at 11:27 AM, Tim Ruffles <o...@truffles.me.uk> wrote:
I think the compiler argument is the valid one. In terms of human written JS having `var undefined` the answer is simply: don't do that, and then you don't need void.

But seems fair enough to remove the feature to make the language smaller, and leave it up to compiler writers to fix if they want to compile to strong mode. It'd be a small part of the job of making their compiler strong-mode compatible.

 e.g if you detect a local var called undefined, wrap that compiled code in a IFFE to get a 'real' undefined.

Andreas Rossberg

unread,
Oct 14, 2015, 7:46:42 AM10/14/15
to Sébastien Doeraene, Tim Ruffles, Strengthen JS
Is there any particular benefit to removing `void`, other than making
a (very large) language slightly smaller? It doesn't cause any
particular problems, as far as I can tell.

As for `undefined`, in strong mode, you cannot rebind it. It is true,
however, that strong code can be nested inside weak code that does
that. But that is a general problem with local mode opt-ins, that
actual has more serious implications (esp. wrt scoping invariants). In
general, such locally strong code will have fewer nice invariants. I'm
not sure what can be done about that, other than recommending against
doing that.

/Andreas

PS: Once we have do-expressions, `do{}` will be the shortest way to
produce undefined. :)
> https://groups.google.com/d/msgid/strengthen-js/CAJwkOg52DXvXFKzopC28wufbvn3vGY25g7CLQeJfqrd6UfSEiA%40mail.gmail.com.

Michael McGlothlin

unread,
Oct 14, 2015, 12:41:47 PM10/14/15
to Andreas Rossberg, Sébastien Doeraene, Tim Ruffles, Strengthen JS
Would it be bad to have strong mode enforce that language features such as undefined, true, false, etc have their original value when strong mode starts? I can't think of any sane reason you wouldn't want it that way if you're choosing to use strong mode anyway.

Andreas Rossberg

unread,
Oct 14, 2015, 12:49:46 PM10/14/15
to Michael McGlothlin, Sébastien Doeraene, Tim Ruffles, Strengthen JS
On 14 October 2015 at 18:41, Michael McGlothlin
<mike.mc...@gmail.com> wrote:
> Would it be bad to have strong mode enforce that language features such as
> undefined, true, false, etc have their original value when strong mode
> starts? I can't think of any sane reason you wouldn't want it that way if
> you're choosing to use strong mode anyway.

That would potentially involve extra checking each time you call into
a strong function, so would probably be rather costly. It's an
interesting idea, but I'm not sure it's feasible.

/Andreas

Martin Probst

unread,
Oct 14, 2015, 1:41:50 PM10/14/15
to Andreas Rossberg, Michael McGlothlin, Sébastien Doeraene, Tim Ruffles, Strengthen JS
Do any browsers/VMs actually still allow overwriting undefined? I had Chrome and Firefox around, and they both silently ignore defining a variable called "undefined".

--
You received this message because you are subscribed to the Google Groups "Strengthen JS" group.
To unsubscribe from this group and stop receiving emails from it, send an email to strengthen-j...@googlegroups.com.
To post to this group, send an email to streng...@googlegroups.com.

Sébastien Doeraene

unread,
Oct 14, 2015, 2:08:09 PM10/14/15
to Martin Probst, Andreas Rossberg, Michael McGlothlin, Tim Ruffles, Strengthen JS
In the global scope, indeed. But you can define a `var undefined` locally in a function.

Sébastien

Michael McGlothlin

unread,
Oct 14, 2015, 3:04:36 PM10/14/15
to Sébastien Doeraene, Martin Probst, Andreas Rossberg, Tim Ruffles, Strengthen JS
Would you have to check or could you just blindly assign the values, in the strong scope, back to the original values? It still would take time but usually that sort of thing is faster than bothering to actually check if you need to do it. Not sure how JS engines store the scope internally but I assume that when a function is called it has to define it's scope in memory some way so you could modify that action to have a pre-defined table with the right values already there instead of being a blank table.

Andreas Rossberg

unread,
Oct 14, 2015, 4:11:23 PM10/14/15
to Michael McGlothlin, Sébastien Doeraene, Martin Probst, Tim Ruffles, Strengthen JS
On 14 October 2015 at 21:04, Michael McGlothlin
<mike.mc...@gmail.com> wrote:
> Would you have to check or could you just blindly assign the values, in the
> strong scope, back to the original values? It still would take time but
> usually that sort of thing is faster than bothering to actually check if you
> need to do it. Not sure how JS engines store the scope internally but I
> assume that when a function is called it has to define it's scope in memory
> some way so you could modify that action to have a pre-defined table with
> the right values already there instead of being a blank table.

You could in fact do that with zero overhead -- you'd effectively
treat `undefined` as a keyword, so no need for a runtime
representation as a binding.

However, that would violate the stated goal of being a subset
semantics, because it would silently change the meaning of some
construct in a way that is not raising an error. As described in the
proposal, we would like to avoid making such changes for strong mode,
since it makes porting harder and more brittle.

/Andreas

Sébastien Doeraene

unread,
Oct 14, 2015, 4:18:40 PM10/14/15
to Andreas Rossberg, Michael McGlothlin, Martin Probst, Tim Ruffles, Strengthen JS
What about this:

* Declaring a local `var undefined` is an early error
* Referring to `undefined` is an early error if there exists a binding for `undefined` in the lexical scope

The only uses of `undefined` that are not early errors are accesses of `undefined` in case there is no binding for `undefined` in the lexical scope. In that case, we know `undefined` is looked up in the global scope. And since we know `<global>.undefined` is read-only and can only be the undefined value, we know that `undefined` can only be the undefined value.

Am I missing something?

Sébastien

Andreas Rossberg

unread,
Oct 14, 2015, 4:32:03 PM10/14/15
to Sébastien Doeraene, Michael McGlothlin, Martin Probst, Tim Ruffles, Strengthen JS
On 14 October 2015 at 22:18, Sébastien Doeraene <sjrdo...@gmail.com> wrote:
> What about this:
>
> * Declaring a local `var undefined` is an early error
> * Referring to `undefined` is an early error if there exists a binding for
> `undefined` in the lexical scope
>
> The only uses of `undefined` that are not early errors are accesses of
> `undefined` in case there is no binding for `undefined` in the lexical
> scope. In that case, we know `undefined` is looked up in the global scope.
> And since we know `<global>.undefined` is read-only and can only be the
> undefined value, we know that `undefined` can only be the undefined value.
>
> Am I missing something?

Yes: `with` and sloppy `eval`. :) They might still inject bindings into
some intermediate scope after you have checked.

(On the other hand, those are a big problem anyway, and I've been
seriously considering disallowing opting into strong mode inside any
such dangerous scope. Unfortunately, that would break Chrome's
devtools, which heavily relies on hacks with `with`...)

Michael McGlothlin

unread,
Oct 14, 2015, 5:10:02 PM10/14/15
to Andreas Rossberg, Sébastien Doeraene, Martin Probst, Tim Ruffles, Strengthen JS
Disallowing 'var' seems to kill pretty much everything not made for strong mode anyway. If I try to load Node's repl up with strong mode on it throws an error because of that. It doesn't seem any less a subset to disallow undefined equalling anything other than undefined. Not really adding to the language or even giving it unexpected semantics.

Andreas Rossberg

unread,
Oct 15, 2015, 1:49:35 AM10/15/15
to Michael McGlothlin, Sébastien Doeraene, Martin Probst, Tim Ruffles, Strengthen JS
On 14 October 2015 at 23:10, Michael McGlothlin
<mike.mc...@gmail.com> wrote:
> Disallowing 'var' seems to kill pretty much everything not made for strong
> mode anyway. If I try to load Node's repl up with strong mode on it throws
> an error because of that. It doesn't seem any less a subset to disallow
> undefined equalling anything other than undefined. Not really adding to the
> language or even giving it unexpected semantics.

Hm, not sure I follow. The problem is `undefined` being rebound
_outside_ strong mode. Outside strong mode you can also use `var`.
Inside you can't, but inside you also cannot rebind `undefined`. So I
don't disagree with what you say, but I also don't quite understand
how it relates?

Disallowing strong code to occur within certain weak contexts would be
a new dimension of restriction.

Michael McGlothlin

unread,
Oct 15, 2015, 3:25:46 PM10/15/15
to Andreas Rossberg, Sébastien Doeraene, Martin Probst, Tim Ruffles, Strengthen JS
I guess I'm saying that disallowing 'var' seems to be more of a porting issue than giving sanity to things like 'undefined' such that they always mean what the majority of people would expect. The lack of 'var' impacts pretty much every program written before 'let' and 'const' were widely available while 'undefined' as a keyword only impacts the few people that tried to do something weird with it.

Youness Belfkih

unread,
Mar 26, 2016, 4:22:11 AM3/26/16
to Strengthen JS
What about `let vuid;` isnt vuid  undefined ?

Shelby Moore

unread,
Sep 11, 2016, 1:18:19 PM9/11/16
to Strengthen JS, sjrdo...@gmail.com, o...@truffles.me.uk
On Wednesday, October 14, 2015 at 7:46:42 PM UTC+8, Andreas Rossberg wrote:
Is there any particular benefit to removing `void`, other than making
a (very large) language slightly smaller? 
...

PS: Once we have do-expressions, `do{}` will be the shortest way to
produce undefined. :)

Shelby Moore

unread,
Sep 11, 2016, 1:39:53 PM9/11/16
to Strengthen JS, sjrdo...@gmail.com, mike.mc...@gmail.com, martin...@google.com, o...@truffles.me.uk
How about disallowing undefined instead of disallowing void :)

To make sure strong mode has stronger invariants for performance optimizations.

Shelby Moore

unread,
Sep 11, 2016, 1:42:39 PM9/11/16
to Strengthen JS, ross...@google.com, sjrdo...@gmail.com, martin...@google.com, o...@truffles.me.uk
Rather I think he was referring to porting the strong mode implementation to other VMs and/or transpiling strong mode code to other VMs which don't currently implement the strong mode. Thus `var` is entirely inapplicable to his point about porting.
Reply all
Reply to author
Forward
0 new messages