should issue a warning when "strict mode"; is missing

1,471 views
Skip to first unread message

AJ ONeal

unread,
Jan 20, 2012, 2:11:57 PM1/20/12
to node.js mailing list
There seem to be few primary reasons that people aren't using strict mode:
  • 99% Laziness (the inefficient kind)
  • 0.9% FUD - They're new to JavaScript or otherwise don't know about / understand it
  • 0.09% They forget to type it out
  • 0.009% They wan't to pretend to be cool using `with`
  • 0.0001% They have a deep hatred for other living creatures and purposefully and knowingly use `this` to access the global object
Since node is all about speed and "use strict"; mode allows for significant performance enhancements, why doesn't it warn you when you forget or are lazy?

I'm watching one of the Crockford videos right now as and just aching inside as I think of how many rookie mistakes make it in to npm that wouldn't have a chance with a simple "use strict";

AJ ONeal

Mark Volkmann

unread,
Jan 20, 2012, 2:24:11 PM1/20/12
to nod...@googlegroups.com
+1 for 'use strict';


AJ ONeal

--
Job Board: http://jobs.nodejs.org/
Posting guidelines: https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines
You received this message because you are subscribed to the Google
Groups "nodejs" group.
To post to this group, send email to nod...@googlegroups.com
To unsubscribe from this group, send email to
nodejs+un...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/nodejs?hl=en?hl=en



--
R. Mark Volkmann
Object Computing, Inc.

Isaac Schlueter

unread,
Jan 20, 2012, 2:27:46 PM1/20/12
to nod...@googlegroups.com
A while ago (0.5, I think?) I looked into adding a NODE_USE_STRICT
environment var that the module system could respond to, by putting
"use strict"; in the module wrapper.

It didn't seem to affect any of our benchmarks. So, to claim speed
changes, we'll have to see proof.

Attributing 99% of non-strict JS use to laziness is a bit
presumptuous. I don't use strict in my own code primarily because I
prefer my C-style languages to support octal literals.

HG

unread,
Jan 20, 2012, 3:30:11 PM1/20/12
to nod...@googlegroups.com
I agree that the 99% is not due laziness... as well... I'm quite
noobie to the language and I admit that I just don't know about it.
Didn't find any mention on nodejs.org... so any tutorial on how and
why specially on node.js?

On Fri, Jan 20, 2012 at 9:27 PM, Isaac Schlueter <i...@izs.me> wrote:
> Attributing 99% of non-strict JS use to laziness is a bit
> presumptuous.  I don't use strict in my own code primarily because I

--
HG.

Matt

unread,
Jan 20, 2012, 5:03:47 PM1/20/12
to nod...@googlegroups.com
The big reason "use strict" ticked me off is just that it's not strict enough, and seemed to only fail a lot of stuff at runtime. I still use it though.

Mostly I think people don't use it because a lot of nodesters are web programmers, and they aren't used to using it in browsers.

AJ ONeal

unread,
Jan 20, 2012, 5:10:04 PM1/20/12
to nod...@googlegroups.com



Every newbie who wants to like JS rather than hate it should watch these videos:

YUI Blog: Crockford on JS (3 & 7 particularly)
yuiblog.com/crockford - video 3 and 7

Google Tech Talk: JavaScript, The Good Parts
youtube.com/watch?v=hQVTIJBZook



Here's the gist:

The LiveScript language spec was written in just a few weeks and then it instantly was on every computer in the world (and was changed to JavaScript when Sun bought Netscape in order to confuse people who liked Java into thinking it was similar when it isn't similar at all).

As part of that mishappenstance there were several bugs in the language specification that were never addressed:
  • People think it's Java Script
  • objects are global by default
  • `this` is global by default
  • `with` has terrible scope ambiguity (and makes the language slow)
  • native prototypes behave differently than extended ones
  • assigning a value to a read-only property silently fails
Strict mode throws errors when you're doing something on accident - like misspelling the name of a variable.

AJ ONeal

Adam Crabtree

unread,
Jan 20, 2012, 6:13:26 PM1/20/12
to nod...@googlegroups.com
This seems pretty naive and unnecessarily flamy. Off the top of my head I'd list the following potential reasons for not using strict mode:

arguments.callee removed - I regularly use this to avoid having to name or track renaming of my functions. granted this is non-optimal, but often so are other conveniences like Array.forEach and Function.bind

non-default globals => It's very convenient when intending to create a global for scripts that will run in both node and the browser to do this as their global objects rather than detecting window.

But most importantly, it's not lazy to not read up on strict mode,


add it to "individual functions" rather than globally as it recommends, test it to verify nothing was overlooked, and ensure testing in a strict mode compatible environment (Node v0.7+ w/ V8 flags) that may break APIs. Honestly to me that just sounds like a grossly insufficient value proposition -- at least for me personally -- especially for scripts I've already written. I'd certainly consider your advice to "use strict" going forward, but maybe you were just being silly when you listed everything above...

Cheers,
Adam Crabtree


AJ ONeal

--
Job Board: http://jobs.nodejs.org/
Posting guidelines: https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines
You received this message because you are subscribed to the Google
Groups "nodejs" group.
To post to this group, send email to nod...@googlegroups.com
To unsubscribe from this group, send email to
nodejs+un...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/nodejs?hl=en?hl=en



--
Better a little with righteousness
       than much gain with injustice.
Proverbs 16:8

Bradley Meck

unread,
Jan 20, 2012, 6:49:10 PM1/20/12
to nod...@googlegroups.com
The one true thing that is infuriating about strict mode:

Octals, I use chmod and permissions parseInt('666',8) everywhere is painful when you want to do permissions operations with bitwise operators. Its in C, and why are you prefacing numbers with '0'!? you do not need all the chars to align.

There are other annoyances as well that people don't talk about:
  Arguments.caller for monkey patch detection / debugging utility functions
  Delete throwing like a mofo, say hello to typeof and Object.getPropertyDescriptor if you have a generalized key on a variable that is deleted (especially evil with prototypes).
  Globals, if you need / want them (and sometimes you do for ease of logging / config etc. on an app [not a library]), you cannot get access to it if someone deletes the 'global' reference (I've seen some libs muck with globals in the past).

Ben Combee

unread,
Jan 20, 2012, 6:57:02 PM1/20/12
to nod...@googlegroups.com
> Octals, I use chmod and permissions parseInt('666',8) everywhere is painful
> when you want to do permissions operations with bitwise operators. Its in C,
> and why are you prefacing numbers with '0'!? you do not need all the chars
> to align.

I keep seeing this and wondering why not modify the bindings for any
APIs that want to take a permissions value to also take a string that
supports octal numbers, so you could just write chmodSync(filename,
"666") or chmodSync(filename, "r+") and have the API figure it out.
Having to figure out the numeric value for this is so C-like.

Thomas Shinnick

unread,
Jan 20, 2012, 7:11:48 PM1/20/12
to nod...@googlegroups.com
node.js does this - see modeNum() in fs.js. 

On Friday, January 20, 2012 5:57:02 PM UTC-6, Ben Combee wrote:

I keep seeing this and wondering why not modify the bindings for any
APIs that want to take a permissions value to also take a string that

The beef is that the language change makes you change your libraries and your code for what is more or less a language regression - removing octal numbers.

And... just for fun, the latest TC39(?) meetings have agreed to _restore_ octal number capabilities, but in the form  0b666 .  So... no relief from source code changes.  We are not amused.

Martin Cooper

unread,
Jan 20, 2012, 8:18:38 PM1/20/12
to nod...@googlegroups.com
On Fri, Jan 20, 2012 at 3:57 PM, Ben Combee <ben.c...@gmail.com> wrote:
>> Octals, I use chmod and permissions parseInt('666',8) everywhere is painful
>> when you want to do permissions operations with bitwise operators. Its in C,
>> and why are you prefacing numbers with '0'!? you do not need all the chars
>> to align.
>
> I keep seeing this and wondering why not modify the bindings for any
> APIs that want to take a permissions value to also take a string that
> supports octal numbers, so you could just write chmodSync(filename,
> "666") or chmodSync(filename, "r+") and have the API figure it out.

Node's 'fs' functions already allow you to pass an octal string
instead of a numeric value for mode. Your "666" example above will
work as you expect.

--
Martin Cooper


> Having to figure out the numeric value for this is so C-like.
>

Bradley Meck

unread,
Jan 20, 2012, 10:45:00 PM1/20/12
to nod...@googlegroups.com
I use bitwise operators, doing this on strings is... ugly.

Matt

unread,
Jan 21, 2012, 12:49:40 AM1/21/12
to nod...@googlegroups.com
Why 0b and not 0o? Surely 0b should be binary?

--

AJ ONeal

unread,
Jan 21, 2012, 1:00:47 AM1/21/12
to nod...@googlegroups.com
Redoing my numbers
---
  • 43% FUD (newbies and experienced dev alike)
  • 42% lazy (not wanting to learn or use the workarounds for the edge cases)
  • 0.9% C programmers that want octal
  • 0.09% people using callee and caller instead of creating an object
  • 0.01% hate the world
 

strict mode
---

All you need to do to remove harmful and confusing features of the language is to start each file you right (browser or node) like this:

(function () {
  "use strict";

}());

If you write your code in strict mode, then I don't believe there are any cases where it will fail on an older es3 system.

If you convert your code to strict mode, except for the unusually high number of C developers on this list (most javascript / node gurus I run into come from ruby) using octal, the only thing that fails is usually using `this` as a global or using implicit globals.



Globals
---

Globals are EVIL. BAD. RUDE. INCONSIDERATE. NASTY.

I can't believe I'm hearing support for globals!!

Seriously, that blows my mind.

I'm being sincere. I thought that everyone in the programming communities had gotten the memo that globals and gotos are words you feel dirty inside for using (except in the kernel where you use gotos to implement the decorator pattern without the overhead of function calls - and the people there are hopefully disciplined enough to not make severe design mistakes).



Browser
---

You don't need globals either. A TON of effort has gone in to making sure that you can write modular JavaScript. Thanks to RequireJS, Pakmanager, and Ender, you can install straight from npm into packed browser-safe code.



Octals
---

This is another one that blows my mind.

I guess since a lot of people on this list work with c++ for native node modules it makes sense.

But JavaScript is a high-level language primarily used for interacting with users.
If you want to use octals... USE C!

Do you know how many times I've been bitten by parsing user input that had a leading '0' and have scratched my head for too long trying to figure out where the math had gone wrong? A lot! (but I'm getting better and remembering to check for corner cases that strict mode can't protect me from);

Of all the C devs I know (myself included, from time-to-time), we only use hex. What's the use case for octal?


callee caller
---

function blah () {
}

var module = {
    blah: function () {
    }
};

problem solved. It's a few extra characters - but it's how all of the big libraries that I've seen, such as jQuery, do it.

I used to use callee when I was a starting out. But ever since I got an understanding of how closures and objects work I've never even had a case where it would have mattered.



Bitwise Operators
---

no difference between strict mode and regular mode.

AJ ONeal

On Fri, Jan 20, 2012 at 8:45 PM, Bradley Meck <bradle...@gmail.com> wrote:
I use bitwise operators, doing this on strings is... ugly.

--

Mark Hahn

unread,
Jan 21, 2012, 1:10:06 AM1/21/12
to nod...@googlegroups.com
 I thought that everyone in the programming communities had gotten the memo that globals and gotos are words you feel dirty ...

Sure, but I do a lot of things that make me feel dirty.  You make it sound like a bad thing. 

I use whatever tools are available to make the best product.  Sometimes that includes dirty things.  You shouldn't make a sweeping statement that one particular tool is always a bad thing.

P.S.  GOTOs are making a comeback in some modern languages.  There is a time and place for everything.

AJ ONeal

unread,
Jan 21, 2012, 1:13:25 AM1/21/12
to nod...@googlegroups.com
Thanks Mark.

I think I get it now... You're all mad!

Where are my beer goggles when I need them?

I give up. 

:-P

AJ ONeal 

P.S. What legitimate use of goto isn't an instance of the decorator pattern?

Mark Hahn

unread,
Jan 21, 2012, 1:24:25 AM1/21/12
to nod...@googlegroups.com
The biggest use-case for gotos is getting out of deeply nested situations.  Using try/catch is a crappy solution for this.  There are also just ordinary algorithms that work well with gotos, like state machines.

Dijkstra started the gotoless religion and for decades it was gospel.  We have grown up since then and don't need religious guidance.  If code is well structured, readable, and efficient, who's to argue?

Of course a worse religion came along since then. I'm speaking of OOPS and a four-letter language that bows to that religion.

I started coding right before gotoless code was invented.  I've seen many fashions in programming come and go.  The only thing I've learned over all these years is to trust my own assessment of what is readable and efficient and not listen to others.

One thing I hate is when someone puts a feature into a tool that is there to protect me from myself.  If it is just an option that can be turned on and off, like strict mode, then that is ok.  But people who intentionally restrict the capabilities of my tools deserves a special place in hell.  (Sorry, I got carried away there).


--

Brandon Benvie

unread,
Jan 21, 2012, 1:52:05 AM1/21/12
to nod...@googlegroups.com
What's wrong with globals when you can literally create, run in, and dispose your own entire JS contexts at will?

Jann Horn

unread,
Jan 21, 2012, 9:47:32 AM1/21/12
to nod...@googlegroups.com
2012/1/21 AJ ONeal <cool...@gmail.com>:

> 42% lazy (not wanting to learn or use the workarounds for the edge cases)

Not wanting workarounds isn't "lazy". I'm pretty sure that if you have
to replace well-written stuff that just works with "workarounds", this
is a huge -1 on that change.


> All you need to do to remove harmful and confusing features of the language
> is to start each file you right (browser or node) like this:
>
> (function () {
>   "use strict";

Without the indent. Please.


> Globals are EVIL. BAD. RUDE. INCONSIDERATE. NASTY.
>
> I can't believe I'm hearing support for globals!!

I think you're exaggerating a lot here. What about, for example,
"process"? Or what about logging?


> I'm being sincere. I thought that everyone in the programming communities
> had gotten the memo that globals and gotos are words you feel dirty inside
> for using (except in the kernel where you use gotos to implement the
> decorator pattern without the overhead of function calls - and the people
> there are hopefully disciplined enough to not make severe design mistakes).

Uh? So you're basically saying "globals aren't too bad, but they're
sharp tools that can be used for nasty stuff, so drop them and use
this wooden knife instead"? Yes, it sometimes is bad to use them, and
yes, it's not what we should put on top of tutorials, but we
definitely shouldn't discourage them that much.


> Browser
> ---
> You don't need globals either. A TON of effort has gone in to making sure
> that you can write modular JavaScript. Thanks to RequireJS, Pakmanager, and
> Ender, you can install straight from npm into packed browser-safe code.

What about JSONP? You need global functions for that, no?


> Octals
> ---
>
> This is another one that blows my mind.
>
> I guess since a lot of people on this list work with c++ for native node
> modules it makes sense.

Uh... and e.g. working with the filesystem, too.


> But JavaScript is a high-level language primarily used for interacting with
> users.
> If you want to use octals... USE C!

Ah, right, Javascript doesn't belong on the server or so. You're sooo
right.</scnr>


> Do you know how many times I've been bitten by parsing user input that had a
> leading '0' and have scratched my head for too long trying to figure out
> where the math had gone wrong? A lot! (but I'm getting better and
> remembering to check for corner cases that strict mode can't protect me
> from);

Well then, sounds like you're using the wrong tools to parse user
input. And like you're not reading documentation. E.g. parseInt only
tries to determine the radix based on the input if you don't
explicitely specify it.

Jann Horn

unread,
Jan 21, 2012, 9:49:08 AM1/21/12
to nod...@googlegroups.com
2012/1/21 Jann Horn <jann...@googlemail.com>:
> 2012/1/21 AJ ONeal <cool...@gmail.com>:

>> Globals are EVIL. BAD. RUDE. INCONSIDERATE. NASTY.
>>
>> I can't believe I'm hearing support for globals!!
>
> I think you're exaggerating a lot here. What about, for example,
> "process"? Or what about logging?

Oh, and yes, I don't think eval should be banned either. Yes, you
should think about whether you really need it three times before doing
it, but it can be extremely powerful and useful.

Bradley Meck

unread,
Jan 21, 2012, 10:41:14 AM1/21/12
to nod...@googlegroups.com
Perhaps I did not explain my points so well.

Bad things in strict mode:

Bitwise : 0666 & (0777 ^ 0001) is not pretty without octal
Globals : I use them in apps, not in libraries, if you are putting something in a package manager do not ever use globals.
Caller : Do not use Callee, name your functions. Caller can be used to check if a monkey patch is hooking your function, can be used for security in hostile environments when you have a secure variable in a closure (this can also be abused if you are not wary).
Delete/throwers for properties: imagine a naive clone function (simplified for effect):

(function clone(o){function foo() { o.apply(this, arguments) };/*loop over properties and copy*/ foo.name = o.name;)()

vs:

(function clone(o){"use strict"; function foo() { o.apply(this, arguments) };/*loop over properties and copy*/ foo.name = o.name;})()

One of these will blow up. You then must keep a skip list and / or run getPropertyDescriptor for every property copied. In my sandbox repo I have to use strict mode, this copy operation is becoming the bottleneck, skip list is faster than getPropertyDescriptor, but if someone passes in something that is locked in some way this will freak out (but getPropertyDescriptor makes slow even slower...). I agree with some of the fixes of strict mode, but some are just infuriating.

Marcel Laverdet

unread,
Jan 21, 2012, 11:10:14 AM1/21/12
to nod...@googlegroups.com
I am a user of strict mode and I have little to add to this discussion other than I am mad that they didn't fix the newline return problem:

function foo() {
  var bar = 1;
  return
    bar;
}
console.log(foo()); // undefined

Unacceptable!

--

Jake Verbaten

unread,
Jan 21, 2012, 11:57:27 AM1/21/12
to nod...@googlegroups.com
this. This is awesome, can we please have this. This means I can be lazy and not include `"use strict"` in my code, and just run with NODE_USE_STRICT on.

Jann Horn

unread,
Jan 21, 2012, 12:00:50 PM1/21/12
to nod...@googlegroups.com
2012/1/21 Marcel Laverdet <mar...@laverdet.com>:

> I am a user of strict mode and I have little to add to this discussion other
> than I am mad that they didn't fix the newline return problem:
>
> function foo() {
>   var bar = 1;
>   return
>     bar;
> }
> console.log(foo()); // undefined
>
> Unacceptable!

Have a look at this:

function foo() {
var bar = 1

if (bar > 5) return
foo(bar)
}

Do you want that to return the result of `foo(bar)` if bar>5? I don't.

Isaac Schlueter

unread,
Jan 21, 2012, 12:35:15 PM1/21/12
to nod...@googlegroups.com
The problem with use strict is that, really, it doesn't do much.

You *still* have to be aware of ASI on restricted productions (most
hazardously, "return"), being careful with user input, writing a
program that does what you want, and so on. The only real value, that
I can see, is that it doesn't allow you to accidentally leak a global.
If you're working on a project with a big enough group, you still
probably need some kind of linter to stay sane, so what does strict
mode get you that the linter doesn't?

If you are the type to choose to use eval or with, then you will just
*not* choose to "use strict". It's opt-in, and much less of an issue
in node (where all code is trusted) than in the browser sandbox, where
one frequently has less-trusted code (ads, plugins, etc.) running
right next to the application.

I think it'd be nice to add a switch for this maybe, but it's a
low-priority feature. If it improved performance we'd probably just
add it manually to all the internal modules.

Thomas Shinnick

unread,
Jan 21, 2012, 1:27:42 PM1/21/12
to nod...@googlegroups.com
On Friday, January 20, 2012 11:49:40 PM UTC-6, Matt Sergeant wrote:
Why 0b and not 0o? Surely 0b should be binary?

Argh, typo.  Yes,  0b101010  and  0o55.  They are talking about explicitly _not_ supporting 0O55 as too typographically confusing.

 

Brandon Benvie

unread,
Jan 21, 2012, 2:58:30 PM1/21/12
to nod...@googlegroups.com
Exactly what isaacs said. It doesn't provide a benefit outside of a handful of specific scenarios. It certainly doesn't increase performance and up until recently was harmful to performance. In return you will subtly change the functioning of existing code in ways that can be difficult to track down.

Certainly go ahead and use it for writing new stuff, but the idea of blanket applying it downright stupid and dangerous because it *will* often break code not specifically written with the differences in mind.

Marcel Laverdet

unread,
Jan 21, 2012, 3:44:26 PM1/21/12
to nod...@googlegroups.com
I feel omitting semicolons is hazardous as well, and as long as you aren't omitting them you won't run into this problem. I think optional semicolons are fine when a language is designed for it, but in JS they lead to ambiguities like this.

function foo() {}
var foo = foo()
foo ? bar() : etc()

The above is fine. But if you add an innocent paren the meaning of the program changes entirely:

function foo() {}
var foo = foo()
(foo) ? bar() : etc()

Anyway I've developed strict coding standards to avoid the pitfalls of semicolon insertion in JS, as I'm sure semicolon non-believers have had to do as well. It's just annoying because the way JS is designed, neither "never using semicolons" or "always using semicolons" is safe.

On Sat, Jan 21, 2012 at 11:00 AM, Jann Horn <jann...@googlemail.com> wrote:
Have a look at this:

function foo() {
 var bar = 1
 if (bar > 5) return
 foo(bar)
}

Do you want that to return the result of `foo(bar)` if bar>5? I don't.

Mark Miller

unread,
Jan 20, 2012, 3:20:26 PM1/20/12
to nod...@googlegroups.com
Hi Isaac, because of this octal impediment, we've decided to support 0o666 octal literals, and 0b10101 binary literals while we're at it, to ES6. However, in the meantime, I think this is a truly terrible reason to burden the community with the continued presence of non-strict server-side code. Think of non-strict code as toxic waste -- we can't deny its inevitable continued existence, but let's please keep it out of places where people are still living (active code being actively maintained). It isn't even lexically scoped. Going forward, its only remaining purpose should be to keep old websites working even when their sources are no longer being actively maintained, i.e., most of the web, but essentially none of NodeJS or other server-side code.

+1 to adding "use strict" to the module wrapper, so that all server side code is implicitly strict, whether it says so or not. Having uses of octal be a bit more awkward is a small price to pay for the increase in sanity.


On Fri, Jan 20, 2012 at 11:27 AM, Isaac Schlueter <i...@izs.me> wrote:
A while ago (0.5, I think?) I looked into adding a NODE_USE_STRICT
environment var that the module system could respond to, by putting
"use strict"; in the module wrapper.

It didn't seem to affect any of our benchmarks.  So, to claim speed
changes, we'll have to see proof.


Attributing 99% of non-strict JS use to laziness is a bit
presumptuous.  I don't use strict in my own code primarily because I
prefer my C-style languages to support octal literals.

On Fri, Jan 20, 2012 at 11:11, AJ ONeal <cool...@gmail.com> wrote:
> There seem to be few primary reasons that people aren't using strict mode:
>
> 99% Laziness (the inefficient kind)
> 0.9% FUD - They're new to JavaScript or otherwise don't know about /
> understand it
> 0.09% They forget to type it out
> 0.009% They wan't to pretend to be cool using `with`
> 0.0001% They have a deep hatred for other living creatures and purposefully
> and knowingly use `this` to access the global object
>
> Since node is all about speed and "use strict"; mode allows for significant
> performance enhancements, why doesn't it warn you when you forget or are
> lazy?
>
> I'm watching one of the Crockford videos right now as and just aching inside
> as I think of how many rookie mistakes make it in to npm that wouldn't have
> a chance with a simple "use strict";
>
> AJ ONeal
>
> --
> Job Board: http://jobs.nodejs.org/
> Posting guidelines:
> https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines
> You received this message because you are subscribed to the Google
> Groups "nodejs" group.
> To post to this group, send email to nod...@googlegroups.com
> To unsubscribe from this group, send email to
> nodejs+un...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/nodejs?hl=en?hl=en

--
Job Board: http://jobs.nodejs.org/
Posting guidelines: https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines
You received this message because you are subscribed to the Google
Groups "nodejs" group.
To post to this group, send email to nod...@googlegroups.com
To unsubscribe from this group, send email to
nodejs+un...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/nodejs?hl=en?hl=en



--
Text by me above is hereby placed in the public domain

  Cheers,
  --MarkM

Isaac Schlueter

unread,
Jan 21, 2012, 4:49:23 PM1/21/12
to nod...@googlegroups.com
Mark,

All the JavaScript in node-core gets linted. (We're not warning-free
yet, we're getting closer.) We do not have octal literals in the
node-core JavaScript. If you find any JavaScript in node that is not
strict-compliant already, please send a patch. That is a bug, and
would be highly surprising.

Past analysis (in node 0.5) showed that adding "use strict" made our
benchmarks relevantly worse. If that changes, we'll start adding "use
strict" in node's internal JavaScript. As long as the "toxic waste"
is faster, we'll keep using it. Winning is more important than being
right.


On Sat, Jan 21, 2012 at 12:44, Marcel Laverdet <mar...@laverdet.com> wrote:
> The above is fine. But if you add an innocent paren the meaning of the
> program changes entirely:
>
> function foo() {}
> var foo = foo()
> (foo) ? bar() : etc()
>
> Anyway I've developed strict coding standards to avoid the pitfalls of
> semicolon insertion in JS, as I'm sure semicolon non-believers have had to
> do as well. It's just annoying because the way JS is designed, neither
> "never using semicolons" or "always using semicolons" is safe.

Marcel, you know full well that responsible semicolon minimalists
would balk at the very notion of starting a line with ( and not
prefixing it with a semicolon.

This "always" "never" business is a strawman duel. No one who knows
what they're talking about endorses either.

Ryan Schmidt

unread,
Jan 21, 2012, 7:09:38 PM1/21/12
to nod...@googlegroups.com

On Jan 21, 2012, at 14:44, Marcel Laverdet wrote:

> Anyway I've developed strict coding standards to avoid the pitfalls of semicolon insertion in JS, as I'm sure semicolon non-believers have had to do as well. It's just annoying because the way JS is designed, neither "never using semicolons" or "always using semicolons" is safe.

I always use semicolons where they belong, or at least, that is my intention. In what way is this not safe?

Jann Horn

unread,
Jan 21, 2012, 8:27:10 PM1/21/12
to nod...@googlegroups.com
2012/1/20 Mark Miller <eri...@gmail.com>:

> +1 to adding "use strict" to the module wrapper, so that all server side
> code is implicitly strict, whether it says so or not. Having uses of octal
> be a bit more awkward is a small price to pay for the increase in sanity.

Would this also force REPL users to write strict JS?

Seva Adari

unread,
Jan 22, 2012, 1:27:18 AM1/22/12
to nod...@googlegroups.com
 It certainly doesn't increase performance and up until recently was harmful to performance. 

This is a bit counter intuitive, but I suppose the checks that it forces adds a cost to performance. One way to deal with it is to turn it on during the development and may be remove it during the deployment (or in production). If there is a single configuration option with which this can be achieved then it is all the better.
 
Certainly go ahead and use it for writing new stuff, but the idea of blanket applying it downright stupid and dangerous because it *will* often break code not specifically written with the differences in mind.

I can't imagine code breaking often for using 'use strict' in all use cases. Even if you can avoid it for now, isn't the JS language itself is going in that ( 'use strict') direction. Future versions will be far more less forgiving than the current.

Marcel Laverdet

unread,
Jan 22, 2012, 3:46:21 AM1/22/12
to nod...@googlegroups.com
@mark
+1 to adding "use strict" to the module wrapper, so that all server side code is implicitly strict, whether it says so or not. Having uses of octal be a bit more awkward is a small price to pay for the increase in sanity.

Bit surprised to hear this from you! It seems dangerous to introduce this.. Without "use strict" it's impossible to tell the toxic waste from otherwise, among other hazards.

@isaac

> Marcel, you know full well that responsible semicolon minimalists would balk at the very notion of starting a line with ( and not prefixing it with a semicolon.
>
> This "always" "never" business is a strawman duel.  No one who knows what they're talking about endorses either.

Dude I wasn't trying to turn this into a duel. I'm saying that neither solution is ideal because of the way the language is designed. Instead of 1 great way to do things we have 2 mediocre ways to do things. Semicolonites and minimalists alike have to adhere to extra-grammatical rules in order to write properly functioning applications.

@ryan

I always use semicolons where they belong, or at least, that is my intention. In what way is this not safe?

For the most part you should be fine. The only thing I could realistically imagine biting you is the example above.
function foo() {
  return
    'foo';
}

foo() returns undefined!

Bruno Jouhier

unread,
Jan 22, 2012, 8:28:03 AM1/22/12
to nodejs
What about a "stricter" option to get a warning or error whenever the
compiler automatically inserts a semi-colon. Looks like this would
make things safe for "semicolonites".

With:

return
foo;

you would get a warning about a semicolon being added at the end of
the return line.

But with:

return foo;

you would not get any warning.

Should not be too difficult to hack into a preprocessor.

Bruno

Mark Miller

unread,
Jan 22, 2012, 10:14:38 AM1/22/12
to nod...@googlegroups.com
On Sun, Jan 22, 2012 at 1:27 AM, Seva Adari <oddi...@gmail.com> wrote:
 It certainly doesn't increase performance and up until recently was harmful to performance. 

This is a bit counter intuitive, but I suppose the checks that it forces adds a cost to performance.

That's not it at all. When designing strict mode, we were very careful to ensure that any effect it had on performance would be positive. For an optimizing engine like v8, strict vs non-strict won't have much of a speed advantage, as most potential gains have already been achieved by harder analysis. But with the comparable engineering effort, there should certainly be no penalty for using strict.

Rather, the issue is "comparable enginerring effort". I just verified with one of the v8 people that problem is that none of the benchmarks say "use strict";. To get this situation repaired, I suggest that someone in the Node community should release, for example, "NodeSpider", a variant of SunSpider in which all the tests are run in strict mode. In addition, if you capture the particular cases that are causing node code to slow down and turn these into further NodeSpider tests, that would be great. If NodeSpider gets any prominence at all, any remaining penalty for strict mode would disappear quickly, and strict mode may even start to realize some advantages. The v8 team likes to drive their optimizations efforts by things they can measure.


 
One way to deal with it is to turn it on during the development and may be remove it during the deployment (or in production). If there is a single configuration option with which this can be achieved then it is all the better.

That would be an improvement on the status quo. But it reminds me of a comment by Tony Hoare about array bounds checking. Many people at the time wanted to have array bounds checking turned on during development to help catch bugs, but then turn it off in deployment for extra speed. Hoare described this as[1] "Like turning off all the safety devices on an airplane just before it is about to start carrying passengers".

[1] Paraphrasing, since I can't find it. If anyone knows the exact post or where to find it, please let me know. Thanks.

 
 
Certainly go ahead and use it for writing new stuff, but the idea of blanket applying it downright stupid and dangerous because it *will* often break code not specifically written with the differences in mind.

Because the browser has to remain compatible with a universe of legacy no one can change, we have no choice there. For node, any code that doesn't work in strict should already be considered broken. Going forward, no one new to JavaScript should ever be taught the non-strict language. And even today, very few who think they understand JavaScript really even understand the non-strict language. The illusion of understanding is mostly due to ignorance of the odd corners.


I can't imagine code breaking often for using 'use strict' in all use cases. Even if you can avoid it for now, isn't the JS language itself is going in that ( 'use strict') direction. Future versions will be far more less forgiving than the current.

It is indeed. But for the sake of maintaining backward compatibility with ES5-strict, future versions will likely be no more nor less forgiving that current strict mode is.

-- 
    Cheers,
    --MarkM

Mark Miller

unread,
Jan 22, 2012, 10:48:08 AM1/22/12
to nod...@googlegroups.com
On Sun, Jan 22, 2012 at 3:46 AM, Marcel Laverdet <mar...@laverdet.com> wrote:
@mark
+1 to adding "use strict" to the module wrapper, so that all server side code is implicitly strict, whether it says so or not. Having uses of octal be a bit more awkward is a small price to pay for the increase in sanity.

Bit surprised to hear this from you! It seems dangerous to introduce this.. Without "use strict" it's impossible to tell the toxic waste from otherwise, among other hazards.

I suppose another possibility would be to reject all code that doesn't begin with "use strict";, but I expect this wouldn't go over well.

Node is a new platform. It isn't a browser. It can define what variant of JS it accepts. I see little reason for node to continue to support ES5-non-strict and much reason not to.
 
-- 

  Cheers,
  --MarkM

Mikeal Rogers

unread,
Jan 22, 2012, 1:31:36 PM1/22/12
to nod...@googlegroups.com
Let me just shut down this thread, hopefully.

node.js does not have an opinion about the JavaScript language.

never has. never will.

That includes strict mode, and ES.next features in case anyone was wondering.

node.js takes v8 "vanilla", no changes, no tweaks. If v8 doesn't warn w/o strict mode, neither does node.js.

This is less a technology decision and more of a community/focus decision. We succeed by limiting the surface area of the problem we are trying to solve and the language isn't part of that.

If you want node.js to warn on strict, tell the v8 people :)

-Mikeal

Dick Hardt

unread,
Jan 22, 2012, 1:38:21 PM1/22/12
to nod...@googlegroups.com
+1

Isaac Schlueter

unread,
Jan 22, 2012, 4:31:04 PM1/22/12
to nod...@googlegroups.com
Mikeal, did you ever know that you're my hero?

On Sun, Jan 22, 2012 at 10:38, Dick Hardt <dick....@gmail.com> wrote:
> If you want node.js to warn on strict, tell the v8 people :)

I wouldn't be opposed to an env/cmdline/compile-time flag to make Node
add "use strict" to all modules it loads. But it'd have to be clean,
and introduce no other hazards, or break anything that already works.
And if it's not demonstrably faster, it won't be the default.

Ryan Schmidt

unread,
Jan 22, 2012, 4:38:59 PM1/22/12
to nod...@googlegroups.com

On Jan 22, 2012, at 02:46, Marcel Laverdet wrote:

>> I always use semicolons where they belong, or at least, that is my intention. In what way is this not safe?
>
> For the most part you should be fine. The only thing I could realistically imagine biting you is the example above.
> function foo() {
> return
> 'foo';
> }
>
> foo() returns undefined!

Of course it does. I wouldn't expect it to do anything different. :)

It would also never occur to me to write the above code. If I wanted to return 'foo' I would write:

return 'foo';

If I wanted to return undefined I would write:

return;


AJ ONeal

unread,
Jan 22, 2012, 10:57:48 PM1/22/12
to nod...@googlegroups.com
The Lose-Lose Case
===

I'm not saying that, if there is absolutely no possible way to work around the flaws inherent in the system, that you should not get the work done.

Rather, what I'm saying is that you should adhere to the rules first and cater to the exceptions on a case by case basis.

I realize that test-driven development kind of trains your brain to consider every possible edge-case (and a lot of people have that pre-optimization mentality anyway), but...


This is a 90 / 10 problem.
===


What percentage of NodeJS developers use Octal?
What percentage of JavaScript users use Octal?

What percentage of JavaScript users don't realize that if they forget `var` their variable becomes a global?


The question here isn't about the 1% that use these features, it's about 80% that get tripped up by simple newbie mistakes.

With more power comes more responsibility
===

I would rather cause disciplined devs like you and me a little grief here and there than every single newbie that comes into JavaScript and NodeJS suffer completely unintuitive silent errors and such.

If Octal is so important for the NodeJS devs, then add a core module for the basic operations. But what about the users?

It's about the user
===

Do you see what I'm saying? Application languages - JavaScript, ruby, python, etc - are about abstraction. That is their purpose!





Not wanting workarounds isn't "lazy". I'm pretty sure that if you have
to replace well-written stuff that just works with "workarounds", this
is a huge -1 on that change.

If it were well-written, it shouldn't have any issues in strict mode other than the octal change.
 
> (function () {
>   "use strict";

Without the indent. Please.

I'm okay with that. It just looks weird without the indent to me.
If I had seen some sort of precedent without the indent, I would have used it that way.
 

> Globals are EVIL. BAD. RUDE. INCONSIDERATE. NASTY.
>
> I can't believe I'm hearing support for globals!!

I think you're exaggerating a lot here. What about, for example,
"process"? Or what about logging?

I wish so bad that it were required instead.

It has caused me extra work (albeit minimal) to get some node / npm modules to run in the browser because `process` is used.

 
> I'm being sincere. I thought that everyone in the programming communities
> had gotten the memo that globals and gotos are words you feel dirty inside
> for using (except in the kernel where you use gotos to implement the
> decorator pattern without the overhead of function calls - and the people
> there are hopefully disciplined enough to not make severe design mistakes).

Uh? So you're basically saying "globals aren't too bad, but they're
sharp tools that can be used for nasty stuff, so drop them and use
this wooden knife instead"? Yes, it sometimes is bad to use them, and
yes, it's not what we should put on top of tutorials, but we
definitely shouldn't discourage them that much.

I was saying that `goto` takes the place of the decorator pattern in C, since C is a hardware language with a limited feature set, not an application language with wonderful abstractions.

The kernel isn't an application. It has a different set of design patterns than applications do.

Applications should not use globals.
 

> Browser
> ---
> You don't need globals either. A TON of effort has gone in to making sure
> that you can write modular JavaScript. Thanks to RequireJS, Pakmanager, and
> Ender, you can install straight from npm into packed browser-safe code.

What about JSONP? You need global functions for that, no?

Actually, for all modern browsers (including MSIE), JSONP is no longer necessary.
Welcome CORS and XHR2. :-D

I'm not saying that, if there is absolutely no possible way to work around the flaws inherent in the system, that you should not get the work done, but that you should adhere to the rule first and cater to the exceptions on a case by case basis.

(And actually, I've been considering writing a `window` module for the browser that copies the properties that are actually part of `window`)
 
> Octals
> ---

> I guess since a lot of people on this list work with c++ for native node
> modules it makes sense.

Uh... and e.g. working with the filesystem, too.

> But JavaScript is a high-level language primarily used for interacting with
> users.
> If you want to use octals... USE C!

Ah, right, Javascript doesn't belong on the server or so. You're sooo
right.</scnr>

JavaScript is an application laguage. It works just as well on the server as ruby or python - just a bit better because it handles JSON natively and has a built-in event system.
 
> Do you know how many times I've been bitten by parsing user input that had a
> leading '0' and have scratched my head for too long trying to figure out
> where the math had gone wrong? A lot! (but I'm getting better and
> remembering to check for corner cases that strict mode can't protect me
> from);

Well then, sounds like you're using the wrong tools to parse user
input. And like you're not reading documentation. E.g. parseInt only
tries to determine the radix based on the input if you don't
explicitely specify it.

That's exactly my point. I *want* an application language to hold my hand a little (or at least be intuitive - there should be a parseOct and parseHex - or do you have an argument or using a radix of 3 and 7 as well?).

If I wanted to have absolute full control I'd use C.

AJ ONeal

unread,
Jan 22, 2012, 11:08:30 PM1/22/12
to nod...@googlegroups.com
In return you will subtly change the functioning of existing code in ways that can be difficult to track down.

I don't believe so. All of the changes to strict mode throw errors.

this = null -- throws an error
using octal -- throws an error
not declaring a variable -- throws an error
using with -- throws an error

in which case would the problem be subtle?

Exactly what isaacs said. It doesn't provide a benefit outside of a handful of specific scenarios. It certainly doesn't increase performance and up until recently was harmful to performance.

Those handful of scenarios are the things that newbies trip up on most (I remember being a newbie, do you?)

I'm part of the training process new hires, some of which are new to JS.
There's a reason that strict mode exists. It IS to help.


Youth and Beauty
===

I'm not saying to enable strict mode by default, 
I'm saying to add a warning when it isn't used in the app which is being run.
(perhaps not when included with `require`, that would be annoying).

I don't believe that The changes to strict mode throw errors

Node is so young. So many newbies are getting interested in JavaScript because of Node.

Let Node be a force of positive change.

Speed
===

Just as with binary arrays, strict mode won't gain the speed improvements until the implementation is complete (there are still a few things lacking in v8 last time I explicitly tested).

But as sure as Google wants v8 to be the fastest engine, the optimizations will come, just as they have with binary arrays.

Mikeal Rogers

unread,
Jan 22, 2012, 11:14:58 PM1/22/12
to nod...@googlegroups.com
On Jan 22, 2012, at January 22, 20121:31 PM, Isaac Schlueter wrote:

Mikeal, did you ever know that you're my hero?


node's lib/* files are pre-compiled so if we want this to pertain to lib/* files it'll have to be a compile time flag.

i'm opposed to compile flags that change the behavior of node, especially in ways that you can't determine by just checking the version.

Mark Miller

unread,
Jan 22, 2012, 11:25:54 PM1/22/12
to nod...@googlegroups.com
On Sun, Jan 22, 2012 at 11:08 PM, AJ ONeal <cool...@gmail.com> wrote:
In return you will subtly change the functioning of existing code in ways that can be difficult to track down.

I don't believe so. All of the changes to strict mode throw errors.

this = null -- throws an error
using octal -- throws an error
not declaring a variable -- throws an error
using with -- throws an error

in which case would the problem be subtle?

The following actually happened to a friend of mine. A brilliant Smalltalk programmer who has done many impressive things, but had not yet immersed himself in JavaScript arcana for years. In order to use various primitives in a more object-like way, he added (among other things) the following method:

    Boolean.prototype.not = function() { return !this; };

After this, true.not() returns false as expected. Guess what false.not() returns. Making this be instead

    Boolean.prototype.not = function() { "use strict"; return !this; };

or if this code occurs in a strict context, solves the problem. No nasty hidden coercion surprise.

How about

    function foo(str) {
      var x = 8;
      eval(str);
      return function bar() { return x; };
    }

When bar is later called, what x variable does it read?

For both of these, the difference is not an easy to diagnose error. It is silent confusion.
 
--
  Cheers,
  --MarkM

AJ ONeal

unread,
Jan 23, 2012, 12:09:58 AM1/23/12
to nod...@googlegroups.com
The following actually happened to a friend of mine. A brilliant Smalltalk programmer who has done many impressive things, but had not yet immersed himself in JavaScript arcana for years. In order to use various primitives in a more object-like way, he added (among other things) the following method:

    Boolean.prototype.not = function() { return !this; };

After this, true.not() returns false as expected. Guess what false.not() returns. Making this be instead

    Boolean.prototype.not = function() { "use strict"; return !this; };

or if this code occurs in a strict context, solves the problem. No nasty hidden coercion surprise.

Interesting. That's just weird.

 
How about

    function foo(str) {
      var x = 8;
      eval(str);
      return function bar() { return x; };
    }

When bar is later called, what x variable does it read?

For both of these, the difference is not an easy to diagnose error. It is silent confusion.

Okay, interesting point made.
I suppose which is expected would depend on what you would expect.

Intuitively I would expect that `str` executes in it's own context and that `x` would always return 8.
So in not-strict mode perhaps it's possible to access `x` in `str`?

AJ ONeal 

Mark S. Miller

unread,
Jan 23, 2012, 8:12:18 AM1/23/12
to nod...@googlegroups.com
On Mon, Jan 23, 2012 at 12:09 AM, AJ ONeal <cool...@gmail.com> wrote:
The following actually happened to a friend of mine. A brilliant Smalltalk programmer who has done many impressive things, but had not yet immersed himself in JavaScript arcana for years. In order to use various primitives in a more object-like way, he added (among other things) the following method:

    Boolean.prototype.not = function() { return !this; };

After this, true.not() returns false as expected. Guess what false.not() returns. Making this be instead

    Boolean.prototype.not = function() { "use strict"; return !this; };

or if this code occurs in a strict context, solves the problem. No nasty hidden coercion surprise.

Interesting. That's just weird.

Which behavior do you find weird:

    false.not() ==> false
or
    false.not() ==> true
?

If (as I hope) you find the first weird and surprising and would have expected the second, it supports my case that even most experienced JS programmers do not really understand non-strict mode. It is filled with subtle minefields which most programs survive mostly by accident.

 

 
How about

    function foo(str) {
      var x = 8;
      eval(str);
      return function bar() { return x; };
    }

When bar is later called, what x variable does it read?

For both of these, the difference is not an easy to diagnose error. It is silent confusion.

Okay, interesting point made.
I suppose which is expected would depend on what you would expect.

Intuitively I would expect that `str` executes in it's own context and that `x` would always return 8.
So in not-strict mode perhaps it's possible to access `x` in `str`?

Actually, in both strict and non-strict mode, str can access the 'x' variable shown here, since the eval "call" shown here is a "direct eval", which is really a special form rather than a function call. However, in trying to clarify, I realize that my example was flawed. The following code correctly raises the riddle I was trying to raise above:

  function makeFoo() {
    var x = 8;
    function foo(str) {
      eval(str);
      return function bar() { return x; };
    }
  }

Again, in both strict and non-strict mode, str can access (both read and write) the 'x' variable shown here, since the eval "call" shown here is a "direct eval", which is really a special form rather than a function call. So the question is not "What value does bar() return?", which could be any value that str decides to store into the above "x" variable. The riddle is "What x variable does bar() read?". 

Once you know the answer, if you find that answer surprising, this further supports my case. Although the strict language is still tricky, the non-strict language is hopeless. Almost no one who programs in it actually understands it.
 
--
    Cheers,
    --MarkM

Brandon Benvie

unread,
Jan 23, 2012, 5:00:21 PM1/23/12
to nod...@googlegroups.com
In getting Narcissus to work in Node I had to change chunks of it to use strict because V8's --harmony won't let you use `let` outside of strict mode. When I did this it caused errors that I traced back to Narcissus's use of const in eval. Instead of defining the consts in the local function scope, they were defined globally. After finally tracking down the cause I had to wrap the code such that the eval was done in a non-strict wrapper function.



Adam Crabtree

unread,
Jan 23, 2012, 6:13:26 PM1/23/12
to nod...@googlegroups.com
Globals
---

Globals are EVIL. BAD. RUDE. INCONSIDERATE. NASTY.

I can't believe I'm hearing support for globals!!

Seriously, that blows my mind.

I'm being sincere. I thought that everyone in the programming communities had gotten the memo that globals and gotos are words you feel dirty inside for using (except in the kernel where you use gotos to implement the decorator pattern without the overhead of function calls - and the people there are hopefully disciplined enough to not make severe design mistakes).

This is mostly tangential, but usually indirect global references are used when wanting to interact with host objects or natives, maybe not necessarily to create globals. For some reason I can't think of any off the top of my head, so obviously it's not THAT common, but I recall having seen it multiple times in respected modules. Again, off the top of my head I THINK it's usually used in the case of pollyfills, which are language specific, environment agnostic and global in nature where the implementation does not care about the name of the global object (window?) so much as merely obtaining a reference to it.

Again though, if you've never encountered this issue, it's probably of little concern to you. =)

Cheers,
Adam Crabtree

--
Better a little with righteousness
       than much gain with injustice.
Proverbs 16:8

Adam Crabtree

unread,
Jan 26, 2012, 2:08:23 PM1/26/12
to nod...@googlegroups.com
FWIW, arguments.callee is used often when passing around arguments objects.

Ben Combee pointed me to the following Mozilla ES discussion on arguments.callee:

In short, it's deprecated to remove incidental granting of permission to execute a function by passing its arguments object. This requires that API consumers must now explicitly name and pass the function instead.

While I understand the security implications and reasoning for this, it makes for a far uglier API for consumers. So in lieu of a more compelling incentive than protection from yourself (globals) and the merit badge of using strict mode, I don't see this as either FUD or laziness, but merely a complication with a currently insufficient value proposition that will necessarily and unavoidably break various APIs.
Reply all
Reply to author
Forward
0 new messages