Octal literals have their uses (you Unix haters skip this one)

# Brendan Eich (12 years ago)

See jashkenas/coffee-script#2021 -- strict mode support in CoffeeScript exposes a valid use-case, Unix-flavor file permissions (mode bits we used to say). Node.js APIs really want users to call with literals such as 0644. Strict mode says no way.

For now CoffeeScript probably will support 0o644 and translate to hex or decimal literals to dodge the strict error. But ES5 still has octal in Annex B, and AFAIK octal support is still required for web compatibility.

Strict mode is not being adopted widely enough, certainly not in node.js code, to kill octal literals. Killing octal literals is user-hostile when it comes to Unix permissions. So I think we should stop tilting at a friendly windmill, and either support octal literals (but not noctal -- no 08 or 09), or support 0o377 etc. as CoffeeScript looks like it will do.

Some may object to lowercase o as prefix. It's clear enough in all fonts, but if we allow uppercase O too, then some might fear user confusion with 0 used instead of O. But if we support 0o377 and 0O377, we can continue to reject (in strict mode and therefore in Harmony) 00377. Anyway, there's no homograph phishing attack threat as with URLs.

If the CoffeeScript experiment with 0o prefixes for octal works out, I think we should adopt that prefix. But at this point I wouldn't be surprised to see retention of 0377 support be demanded by CoffeeScript/Node.js users, and they have a point.

CoffeeScript can certainly compile this to a strict hex or decimal literal to dodge the error, but then JS/Node.js is at a loss, and for no good reason. In this case I will argue for supporting octal literals in strict mode.

# Axel Rauschmayer (12 years ago)

parseInt("377", 8)? Assuming that performance isn’t an issue.

# Brendan Eich (12 years ago)

Sorry, are you seriously proposing that Node.js users when they specify file permissions should manually write that out? Come on! Sorry, that's just way too verbose and ugly.

And performance can be an issue, but the readability and writability problems are enough.

# Herby Vojčík (12 years ago)

Would it be hard to bring in Smalltalkish 8r377? Another (and similar to 0) special char for specific radix - well, wouldn’t it be better to include a letter for all radixes (CoffeeScript can maybe take it on, too).

Herby

-----Pôvodná správa---

# Brendan Eich (12 years ago)

Maybe -- the precedent from Python and Ruby for 0o377 is strong than Smalltalk precedent at this point.

What's more, you seem to want a generalization to any radix, as if all radixes are useful or even used. JS already has 0x for hex, which is much more useful than octal. After octal would come binary, and CoffeeScript, Python and Ruby precedents want 0b111. After that, there really aren't any commonly-used (or all that useful, apart from obfuscation exercises) radixes.

So we have a 0x precedent in JS, from C (by way of Java). We have nearby/upstream scripting language precedents with Python, Ruby, and CoffeeScript, for 0o and 0b. We have zero practical use-cases for arbitrary radixes. Furthermore we won't see people migrate from 0x to 16r, ever.

So all of this says to me we should avoid generalizing for its own sake, and follow nearby precedents first.

# Dean Landolt (12 years ago)

/cc es-discuss (sorry Brendan -- you always seem to be the target of my reply-all fails)

# Brendan Eich (12 years ago)
# Brendan Eich (12 years ago)

[Resending reply with elaboration. /be]

Yes, the ability to quote the octal literal with Node's APIs came up on the gist, but it's not enough.

Quoting is easy to forget, and making the runtime convert string (literal) to number is inefficient compared to having JS do it at compile-time, and making the runtime (even via a call to parseInt) do it also increases bug habitat ever so slightly.

Mainly, users don't have to shun octal in non-strict mode, and they do not in Node code I have seen. They won't be adopting strict mode as far as I can tell. Banning octal is just one more reason for those who might adopt strict mode to reject it.

Agree on parseInt. Old dog, hard to change (runtime-only errors are migration- and user-hostile). Not sure what to do there.

# Wes Garland (12 years ago)

I'll chime in with my vote - I would LOVE to be able to use octal literals again in GPSEE for setting file permissions.

chmod("filename", parseInt("777", 8))

^^^^ just looks stupid when chmod("filename", 0777) would work just fine.

# Greg Smith (12 years ago)

To me this seems like an exception rather than a common problem. Most APIs / tools don't use octals for this type of thing. Seems unnecessary to add to the language for this one use case.

Not a Linux hater by any means, just the parseInt thing doesn't bother me for this one situation. Or am I wrong and there are other common uses for octal literals?

# Brendan Eich (12 years ago)

Greg Smith <mailto:greg at bocoup.com> January 12, 2012 12:08 PM To me this seems like an exception rather than a common problem. Most APIs / tools don't use octals for this type of thing. Seems unnecessary to add to the language for this one use case.

"Add to the language" is not accurate. Octal is already supported by JS engines today, and again, AFAIK, it is required for web compatibility. Banishing octal to the non-normative Annex B, banning it from strict mode -- that does not remove octal from JS in reality.

Given this, the shoe is rather on the other foot: strict-mode has one more drawback from the point of view of a non-trivial cohort of users (Node.js hackers who wrangle Unix permissions).

Not a Linux hater by any means, just the parseInt thing doesn't bother me for this one situation.

That's nice, but Node.js supports JS non-strict and people use it freely, including not quoting octal literals (the API works with string inputs too, so explicit parseInt is not required).

The problem for CoffeeScript users can be solved quickly via 0o prefixing. The problem for JS users is also easy: don't use strict mode. Is this really what we want? What good have we done by banning octal in strict mode?

Or am I wrong and there are other common uses for octal literals?

The only use case I'm citing here is Unix permission modes. That's enough.

# Oliver Hunt (12 years ago)

I'll just add a caveat to brendan's comments below though: JScript doesn't support octal in many (all?) cases, leading to incompatible behaviour when parsing things like 012.

I think the problem with octal numbers isn't a philosophical hate of octal, inasmuch as it is a general unhappiness with the existing octal support, namely a simple 0 prefix switching the parse mode. If we had another (unambiguous) prefix that would (I'm sure) be fine.

If we were willing to add octal with a clear prefix I would be fine with that, for consistency with hex, I'd lean towards 0o<...>, but I'm open to any suggestions that people may wish to add. Personally I'd also like a binary form, a la 0b...., but I'm unsure how useful regular developers would find that (I don't write "realworld" JS so my needs don't always align with those of regular developers).

# Thaddee Tyl (12 years ago)

Can't we just have free competition between "0o644" and "0644"?

Add the former, and we'll see which wins in real code!

If "0o644" wins, and if people like Doug Crockford advocate the drop of "0644", we may then consider including this in a new version of Strict Mode.

Furthermore, I'd like to weigh in with Herby Vojčík and ask for 8r644 support.

# Herby Vojčík (12 years ago)

Hm, it's hard with those precedents already existing.

I was not talking about dropping 0x (or officially obsoleting it), it is really strong pattern. I was just advocating, since they are not in strict mode (0x is, so it's ok), not adding any more 0o and 0b, adding 8r, 2r and generally any radix up to 36r instead.

But again, if 0o and 0b wins everywhere else... I can't say myself which is better... I'd still lean gently for r, but those precedents made it weaker.

Herby

-----Pôvodná správa---

# Brendan Eich (12 years ago)

No, let's not "do everything". That's a bad way to make standards.

We should acknowledge that octal is used in JS today and it'll die hard in certain quarters. I don't think this was considered carefully when the decision to ban octal in strict mode was made.

If we want to support octal in strict mode, we can certainly ban crazy noctal (08, 09). If we choose to prefix, we should pick one prefix (and it should almost certainly be the same one in Python, Ruby, and CoffeeScript: 0o). Binary is plausible (0b), but after that I see no need for arbitrary-radix literals.

# Axel Rauschmayer (12 years ago)

If we were willing to add octal with a clear prefix I would be fine with that, for consistency with hex, I'd lean towards 0o<...>, but I'm open to any suggestions that people may wish to add. Personally I'd also like a binary form, a la 0b....

+1 to both. Then we have three kinds of non-decimal literals, for example: 0b1011, 0o732 and 0xFFFF.

For long literals, Java has started to make "_" as a separator legal, that would be nice to have, too: let aLotOfMoney = 120_327_756_228;

# Greg Smith (12 years ago)

Given that octals are likely here to stay, I think they should look as specialized as they are, so a very conspicuous prefix like 0o really makes sense to me. As to which prefix to use, o seems the easiest to remember.

# Thaddee Tyl (12 years ago)

On Thu, Jan 12, 2012 at 9:57 PM, Axel Rauschmayer <axel at rauschma.de> wrote:

If we were willing to add octal with a clear prefix I would be fine with that, for consistency with hex, I'd lean towards 0o<...>, but I'm open to any suggestions that people may wish to add.  Personally I'd also like a binary form, a la 0b....

+1 to both. Then we have three kinds of non-decimal literals, for example: 0b1011, 0o732 and 0xFFFF.

For long literals, Java has started to make "_" as a separator legal, that would be nice to have, too:      let aLotOfMoney = 120_327_756_228;

+1 to that, too. It does make things easier to read. Ruby has had that for decades.

It is a very specific use-case, but I feel like we shouldn't disregard non-generic use-cases. 0644 (used in node.js in a unix environment) is a non-generic use-case, and as such I feel it shouldn't just die. That is why I would like 0644 and 0o644 to co-exist.

# Oliver Hunt (12 years ago)

On Jan 12, 2012, at 1:04 PM, Thaddee Tyl wrote:

On Thu, Jan 12, 2012 at 9:57 PM, Axel Rauschmayer <axel at rauschma.de> wrote:

If we were willing to add octal with a clear prefix I would be fine with that, for consistency with hex, I'd lean towards 0o<...>, but I'm open to any suggestions that people may wish to add. Personally I'd also like a binary form, a la 0b....

+1 to both. Then we have three kinds of non-decimal literals, for example: 0b1011, 0o732 and 0xFFFF.

For long literals, Java has started to make "_" as a separator legal, that would be nice to have, too: let aLotOfMoney = 120_327_756_228;

+1 to that, too. It does make things easier to read. Ruby has had that for decades.

It is a very specific use-case, but I feel like we shouldn't disregard non-generic use-cases. 0644 (used in node.js in a unix environment) is a non-generic use-case, and as such I feel it shouldn't just die. That is why I would like 0644 and 0o644 to co-exist.

Outside of strict mode 0644, etc will have to continue to exist as I believe both JSC and SpiderMonkey have existing content that depends on that octal notation working. But it would be nice if we could standardise on nicely (unambiguously) prefixed notation that would also work in strict mode.

# Brendan Eich (12 years ago)

Right, as Oliver said, 0644 won't just die in real-world non-strict JS implementations. It's going to stay for web compatibility until someone with enough market share turns it off and survives, and others follow. I don't see anyone rushing to risk market share loss for so little in return.

So adding 0o644 support is the way to go. Once again web compatibility and evolutionary dynamics require doing two things, in order to (far off, hard to predict, might never happen) retire the old form. This is not, however "do everything" and so I don't see why we should do 8r644 as well.

# Allen Wirfs-Brock (12 years ago)

On Jan 12, 2012, at 12:57 PM, Brendan Eich wrote:

No, let's not "do everything". That's a bad way to make standards.

We should acknowledge that octal is used in JS today and it'll die hard in certain quarters. I don't think this was considered carefully when the decision to ban octal in strict mode was made.

My recollection (could be faulty) is that the decision was motivated by a desire to eliminate the error-proneness of the "leading 0 means octal" syntax accompanied by insufficient thought regarding modern use cases for octal. The Unix file permissions is a good one and of course anybody writing a PDP-8 simulator will appreciate the availability of octal

If we want to support octal in strict mode, we can certainly ban crazy noctal (08, 09). If we choose to prefix, we should pick one prefix (and it should almost certainly be the same one in Python, Ruby, and CoffeeScript: 0o). Binary is plausible (0b), but after that I see no need for arbitrary-radix literals.

I think adding 0o to strict mode (while continuing to ban all leading 0digit octal constants (not just 08 and 09)) would be the best way to go. The fix for lack of octal being a barrier to strict mode adoption is for implementor to quickly add 0o constants as an (allowed) extension to strict mode (do it today!). Of course, there is nothing preventing implementations to from also supporting the same extension in non-strict JS code.

0644 not having in strict mode should only be a minor adoption barrier if 0o644 is available everywhere.

# Lasse Reichstein (12 years ago)

Seems like a library interface that isn't well thought through: Accepting a number as input, but it's only reasonably written in one base. Then it's not really a number, but rather a formatted string, so the chmod function should take a string as argument and do its own parseInt(_,8) on it (and accept other formats too, like "a+rw" or "rwxr--r--").

Don't try to fix a single broken interface by adding unnecessary features to the language! /L 'not a Unix hater, but probably a chmod hater'

# Brendan Eich (12 years ago)

The API in question takes a string and does parseInt if necessary. That's not the issue. There is real code using octal and it won't change to quote the numeric literal, and it won't adopt strict mode. Meanwhile CoffeeScript is trying to target strict mode. It can cope, but we're left with non-strict Node.js JS source code as default, with no incentive to change.

What was the good, what benefit was achieved, by banning octal from strict mode? Since it is required for web compatibility, it is already in the spec. Adding 0o is not adding an unnecessary feature if there are valid use cases for octal. Or would you be ok if we simply allowed 0-prefixed octal in strict mode?

# Lasse Reichstein (12 years ago)

I'd like having 0o777 (and 0b1111!) but I thought the reason for removing the existing octal literals was that they were surprising and error-prone (and behaving erratically in different settings, so, e.g., 0100 != +"0100"). That reasoning still stands.

I can't say whether removing them from strict mode was really a benfit. It made strict mode more compatible across browsers than non-strict mode ever was, but it might also have made moving code from non-strict to strict slightly harder. Personally, I'd go for strict mode to be sure that my numbers were not interpreted as octal. But that's what's being argued here - converting existing code (or existing programmers) to strict mode is hampered by them not being able to use the octal numbers they are used to.

Well, these are obviously not programmers that want strict mode to begin with (since it requires very little effort to change the octal literal to a string). It's people that would choose strict mode only if it was trivial or they had a compelling reason for doing it.

I don't think people writing non-strict code as their default for node.js is a problem solved by changing strict mode. It might be changed if there was an actual advantage for the programmers in using strict mode, which there hasn't been - it's not faster, it's not simpler, and it's not what they are used to, and being more compatible between ECMAScript implementations makes no difference when writing for just node.js.

# Brendan Eich (12 years ago)

Lasse Reichstein <mailto:reichsteinatwork at gmail.com> January 13, 2012 1:30 AM I'd like having 0o777 (and 0b1111!) but I thought the reason for removing the existing octal literals was that they were surprising and error-prone (and behaving erratically in different settings, so, e.g., 0100 != +"0100"). That reasoning still stands.

Are there bug reports or other skidmarks from mistakes of this kind? I've never seen one.

bugzilla.mozilla.org/buglist.cgi?field0-0-5=content&type0-0-4=substring&type0-0-5=matches&value0-0-5="octal"&list_id=2058643&short_desc=octal&field0-0-0=product&type0-0-1=substring&field0-0-1=component&type0-0-6=substring&field0-0-4=status_whiteboard&classification=Components&value0-0-2=octal&field0-0-6=cf_crash_signature&query_format=advanced&type0-0-3=substring&field0-0-3=short_desc&value0-0-3=octal&bug_status=UNCONFIRMED&bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED&bug_status=RESOLVED&bug_status=VERIFIED&bug_status=CLOSED&value0-0-4=octal&short_desc_type=allwordssubstr&field0-0-2=alias&value0-0-1=octal&type0-0-0=substring&value0-0-6=octal&value0-0-0=octal&component=JavaScript Engine&product=Core&type0-0-2=substring

Indeed we made bugs for our users in the course of implementing and finalizing ES5. Here's a particularly time-killing exercise:

bugzilla.mozilla.org/show_bug.cgi?id=601262

I don't think people writing non-strict code as their default for node.js is a problem solved by changing strict mode.

Harmony is based on strict mode. V8 is implementing Harmony proposals for ES.next. The recent version-free opt-in thinking in concert with these facts suggest Node.js people will be writing ES.next code at some point. Will octal permission literals work then? It's a small point but I say they ought to.

It might be changed if there was an actual advantage for the programmers in using strict mode, which there hasn't been - it's not faster, it's not simpler, and it's not what they are used to, and being more compatible between ECMAScript implementations makes no difference when writing for just node.js.

This part I agree with. Strict mode did some good things we like (all the early errors, basically). The runtime meaning shifts and their implications for performance (at least, without new optimization effort on the part of implementors, who face little incentive without adoption -- which won't be forthcoming without performance) were not good.

# David Bruant (12 years ago)

Le 13/01/2012 19:15, Brendan Eich a écrit :

Lasse Reichstein:

It might be changed if there was an actual advantage for the programmers in using strict mode, which there hasn't been

I heard some got burnt by a missing "var" [1]. Strict mode and a bit of testing could have prevented this blog post from existing. If strict mode only had introduced this change, I would consider it worthwhile.

it's not faster, it's not simpler, and it's not what they are used to

I recently suggested a newcomers to the language to always be in strict mode ;-)

and being more compatible between ECMAScript implementations makes no difference when writing for just node.js.

This part I agree with. Strict mode did some good things we like (all the early errors, basically). The runtime meaning shifts and their implications for performance (at least, without new optimization effort on the part of implementors, who face little incentive without adoption -- which won't be forthcoming without performance) were not good.

Regarding performance, I'm not sure I understand what the big deal is. It's always possible to develop in strict mode and deploy as non-strict if the performance difference really matters. Code written with in strict mode and with decent discipline (not assuming anything on the 'this' value of a function used as a function, for instance, etc.) should run fine in non-strict, no?

David

[1] blog.meloncard.com/post/12175941935/how

# Brendan Eich (12 years ago)

David Bruant <mailto:bruant.d at gmail.com> January 14, 2012 4:04 PM Le 13/01/2012 19:15, Brendan Eich a écrit :

Lasse Reichstein:

It might be changed if there was an actual advantage for the programmers in using strict mode, which there hasn't been I heard some got burnt by a missing "var" [1]. Strict mode and a bit of testing could have prevented this blog post from existing. If strict mode only had introduced this change, I would consider it worthwhile.

Yes, that alone is worth a lot. But strict mode has a bad rep and these folks did not use it. We should look directly at why.

it's not faster, it's not simpler, and it's not what they are used to I recently suggested a newcomers to the language to always be in strict mode ;-)

Great. Not happening enough at scale to matter, AFAICT. I could be wrong, it's early yet. But we can't use strict-mode adoption as an argument against default version (unversioned script, new syntax as its own opt-in) being the norm.

and being more compatible between ECMAScript implementations makes no difference when writing for just node.js.

This part I agree with. Strict mode did some good things we like (all the early errors, basically). The runtime meaning shifts and their implications for performance (at least, without new optimization effort on the part of implementors, who face little incentive without adoption -- which won't be forthcoming without performance) were not good. Regarding performance, I'm not sure I understand what the big deal is. It's always possible to develop in strict mode and deploy as non-strict if the performance difference really matters. Code written with in strict mode and with decent discipline (not assuming anything on the 'this' value of a function used as a function, for instance, etc.) should run fine in non-strict, no?

It's not just |this| coercion. If you write code that assumes no arguments aliasing and assign to a formal parameter or arguments[i] that aliases it in non-strict mode, and do not get the aliasing (as you expect), but fail to test your non-strict deployed code, you have a subtle and possibly nasty bug.

People won't take such risks without better-communicated incentives, even though the cases are "corner cases". The main selling point as you note is assigning to a free variable is a runtime error. That's good but not great. Harmony (however opted-in) makes it an early error, which is the real deal.