11 ms·
How necessary are var, let, and const?
- bmeck 11y agoconst can be used to denote that a reference to the variable is being passed around and should not change for the lifetime of a scope. function f() { const queue = []; consumer(queue); return queue; } It could be important to note that removing const has benign effect, but that it is there to ensure a programmer does not change the value of queue between `consumer(queue)` and `return queue`. Easily reasoned about, but extra safeguards from introducing bugs is always nice.
- digi_owl 11y agoI guess you can say that they are there to allow the compiler to check the intent of the programmer.
- EugeneOZ 11y agoIronically enough, but your example shows where const is shouldn't be used as guarantee of immutability: https://t.co/JIQozGe7Md https://t.co/JIQozGe7Md
- agumonkey 11y agoIsn't that a typical "corner case" in the understanding of dynamic languages bindings ? I think I've seen the same question pop about python. The array binding is constant, its content isn't.
- EugeneOZ 11y agoif value of constant can be changed, it's not constant. In my understanding. And by Wikipedia: http://en.wikipedia.org/wiki/Constant_(computer_programming) http://en.wikipedia.org/wiki/Constant_(computer_programming)
- agumonkey 11y agoThat's typical computer lingo / semantic issue. the `const` mean shallow/pointer constant, not deep/structurally constant.
- bmeck 11y agoconst is not about immutability in JS.
- thomasfoster96 11y agoI'm not sure I quite understand your point - while it's true that the variable called queue won't be reassigned, const would still allow elements and properties to be added to queue.
- bmeck 11y agoconst is not about immutability in JS.
- thomasfoster96 11y agoI know that - but the previous comment made it sound as though it did mean immutability.
- rbalicki 11y agoIf we use the approach of converting var's to named parameters, we also have to give up on passing variable numbers of arguments to functions. That is, unless we do something silly like: function silly(x, y, z, args) { args = Array.prototype.slice.call(arguments); args.shift(); args.shift(); args.shift(); args.shift(); x = y = z = undefined; // regular function goes here }
- shawndumas 11y agoThe replacement of var or let was a thought experiment to show the actual value--in code--of using them.
- shawndumas 11y agoTo be fair; getting the benefit of const would require code too though: function constUseful () { var guarded = 1; (function loop (orgGuarded) { setTimeout(function () { if (guarded !== orgGuarded) { throw 'guarded reassigned!'; } loop(orgGuarded); }, 0); })(guarded); guarded = 2; } constUseful(); That's an approximation of const's value as delineated in code.
- bshimmin 11y agoOK, I'll bite: what does De Stijl (http://en.wikipedia.org/wiki/De_Stijl http://en.wikipedia.org/wiki/De_Stijl) have to do with any of this?
- deleted 11y ago[deleted]
- braythwayt 11y agoPerhaps the question of whether `const` in a language that doesn't do much static type checking/analysis is a question of style, and not a clear across-the-board win.
- gjm11 11y agoIt was a movement that attempted to achieve clarity and elegance by omitting the unnecessary -- and the article discusses whether omitting formally-unnecessary features like var or const makes for more clarity and elegance, or less. (Having said which, I notice that there's a reply from the person who actually wrote the article, and it doesn't say that. But that's why he should have made the reference :-).)
- braythwayt 11y agoI might have said that, but then I would be omitting the fact that not everyone finds my reproduction of the red-=blue chair comfortable. Scheme vs. Common Lisp, and all that.
- pm24601 11y agoconst IS valuable and necessary. 1) It means that every place the const appears it can be replaced with the const's value. Type checking can be streamlined, less indirection. 2) It communicates the developer's INTENT in an enforced manner. No later code change can accidentally make the const suddenly non-const. 3) const + deep Object.freeze() makes for a complete const. Sure a human could hypothetically scan the code to see that the value has not been reassigned. This falls apart in practice. As soon as the company has a few dozen developers the code is constantly changing and such manual analysis would have to be constantly done.
- titzer 11y ago1.) is simply wrong. Const variables have a live-range hole where access to the variable either throws or returns undefined, depending on the language mode (and the VM!). In either case it not legal to just smash in the constant. 2.) That's nice but JS semantics do not actually hold up. The intent is for a constant, the reality is there is a small window where the wrong results can be observed. Engines don't actually do any more optimizations than for var or let; in fact, your code may actually be slower due to the live-range hole checks.
- pm24601 11y agoSo you are saying that there are race conditions currently? Are any of this race conditions actually required by the language spec? If not, I suspect that those race conditions will be eliminated.
- david-given 11y agoI believe that what the parent meant was that this: function f() { console.log(a); const a = 1; console.log(a); } ...actually returns this: undefined 1 So you get partially compile-time semantics (you can't assign to a) but partially run-time semantics (a only gets its value when initialised). Simply propagating the value of a's initialiser to all places where the variable is used is wrong, as this behaviour's required by the spec.
- ylg 11y agoInteresting and well written; if it were me, I might only change the ending a bit: "Whereas, const […]. It is not nearly as useful as immutable data, because the problem it solves is easy, not hard." To something like: "const may be more useful than adding something like immutable data to an imperative language with mutability deep in its DNA might be because it helps with one of the hardest problems; long-term, correct re-reading by humans doing maintenance or extension." But, the OP covers that well earlier in, so I'm not sure a third take on it would add much. Thanks for doing the exploration!
- protonfish 11y agoA better question is how useful is let at all? Having two different variable scoping rules with no way to know which one a variable is using without backtracing sounds like a maintenance nightmare. I understand what is it good for, but it seems like we are replacing a small problem with a bigger problem. An even better question is why not get rid of var and make every variable local to its parent function? To alter globals, use the window object explicitly.
- serve_yay 11y ago> better question is how useful is let at all? Having two different variable scoping rules with no way to know which one a variable is using with backtracing sounds like a maintenance nightmare. I agree, but I think the solution is to stop using `var`, the question is how useful `var` really is. `let`'s scoping is what it appears to be, `var`'s is not. So `let` is the better choice.
- protonfish 11y agoI disagree. Maybe you think this because you are used to another language, but once you get how var works, it's quite clear. Just because some other language does it, does not mean it is unquestionably good.
- serve_yay 11y agoOn the contrary, I pretty much only write JS and have for years now. And I think `var` has warped our brains, not the other way around.
- tangent128 11y agoIf Javascript didn't have closures, then var's scoping rules would largely be academic. But in practice, there are many cases when I have to create multiple callbacks in a loop; half the time I forget that, in Javascript, declaring a variable inside a loop does not actually create a variable local to the loop, and so have to keep debugging why all my callbacks are behaving exactly the same. The let statement appears to adopt Lua-style lexical scoping, which will be a breath of fresh air once I can rely on browser support.
- serve_yay 11y agoCan you eliminate `var` by introducing an unnecessary function, declaring the `var`s as parameters, and then invoking? Yes you can. Why you would ever do that, however...
- tperson 11y agoThis was my thoughts exactly. I stopped reading after that section. I don't understand what the author is trying to do.
- moogly 11y agoI found this article's premises and findings rather pointless, and kept on wanting the author to instead verify the premise "are there actually valid uses of 'var' now that 'let' exists?" (I haven't found any yet, and I'd like to know if I'm wrong). But maybe I'm too much of a pragmatist rather than an academic, so I suppose it wasn't written for me.
- serve_yay 11y agoYes! Thank you. I agree the question is as you pose it -- why use `var`, ever?
- deleted 11y ago[deleted]
- benaiah 11y agoI believe the parent comment was referring to using “let” instead of “var” - “let” supports reassignment.
- Animats 11y ago"let", of course, is a retrofit to Javascript. So was "var". In the early days of Javascript, before "strict mode", few people declared anything and most variables had global scope. It's really hard to get a declaration-free language right. Python was the biggest success to date.
- serve_yay 11y agoSorry, what I meant was more that since we have let, there isn't any good reason to use var anymore. I definitely don't advocate the thing in this article where he eliminates var usage by littering the code with IIFEs.
- chc 11y agoHuh? `var` was not retrofitted. I distinctly remember it being there since I started learning JavaScript, like around '96. It is true that a lot of people were slack about using it, but that's just laziness, not that it wasn't there.
- aikah 11y agolet is obviously needed(devs like lexical scoping) but I found the whole var + let in the same language thing a bit confusing. The temptation to introduce yet another strict mode(to forbid var,and a few other constructs) is strong on this one.
- braythwayt 11y agovar vs. let in the same language is a consequence of designing the language by committee, requiring 100% backwards-compatibility, and forbidding the addition of new modes (which is a back-door way to introduce breaking changes, while requiring browser vendors to essentially support multiple versions).
- sebleblanc 11y agoThat behaviour is not exclusive to standards committees. The government and private companies do it all the time.
- CrossEye 11y ago"governments and private companies" certainly do not preclude committees. Quite to the contrary, in fact.
- sesutton 11y ago>The temptation to introduce yet another strict mode(to forbid var,and a few other constructs) is strong on this one. There is a proposal for that, coincidentally called "strong mode". https://docs.google.com/document/d/1Qk0qC4s_XNCLemj42FqfsRLp49nDQMZ1y7fwf5YjaI4/view https://docs.google.com/document/d/1Qk0qC4s_XNCLemj42FqfsRLp...
- seasoup 11y agoThat is not at all obvious to many long time JavaScript engineers. Having a variable scoped by block or by function works for me, having both in the language is a pain. I have seen some neat tricks that you can do with let in for loops, but nothing that has convinced me it's worth the cognitive overhead of figuring out is this variable a var or a let. My opinion is that if you use let, don't use var, and if you use var, don't use let. Either one on its own is fine, together they are just a mess.
- rashkov 11y agoCould anyone please explain to me why the author chose those functions for his examples? I got as far as callFirst() and repeat() and found it hard enough to wrap my mind around the functional / meta programming within. Are those actually good examples? It seems like there are simpler ways to illustrate the point.
- fenomas 11y agoIf you check out Javascript Allonge (linked on the page, web version is free) you'll find out. The author has written a lot about functional programming, combinators and so on in JS. I think his point was simply that examining how to emulate let/var with closures, it shows you explicitly what is different/similar about them. He's not suggesting anyone use those transforms.
- pc2g4d 11y agoDoes anyone else out there think Javascript `const` should really be called `final`? It more closely mimics Java's `final` keyword by preventing reassignment ("rebinding") of the variable, whereas `const` makes me think of full immutability as in C++.
- btbuildem 11y agoThat disclaimer is a bit of a cop-out, given the subject matter..
- magice 11y agoHmm, posts like this make me want to make Lisp mandatory for all programmers. Given that LISPers have argued for "lambda the ultimate kitchen utensil/sinks/cooks" for the last few decades, it's slightly annoying that people from other languages repeat the point now. That said, congratulation for learning value of syntactical sugar. I hope you like it. That said, can somebody implement hygienic macros in JavaScript. They will probably help will people having to explain basics knowledge over and over.
- braythwayt 11y agoFWIW, I learned Scheme in the mid 1980s, loooooong before I'd ever heard of JavaScript.
- Aloisius 11y agoGiven that LISPers have argued for "lambda the ultimate kitchen utensil/sinks/cooks" for the last few decades, it's slightly annoying that people from other languages repeat the point now. Personally I find excessive use of lamdas create unmaintainable and incredibly difficult to debug spaghetti code. The idea that JS developers should make their code even more LISP-like is enough to give me nightmares.
- braythwayt 11y ago"I used to brag that I could 'write Lisp in any language.' But Lispers doubted that I could, and everyone else feared that I would."
- JadeNB 11y ago> Given that LISPers have argued for "lambda the ultimate kitchen utensil/sinks/cooks" for the last few decades, it's slightly annoying that people from other languages repeat the point now. Why? Are you also annoyed by calculus students who learn ideas today that have been known for hundreds of years? > That said, congratulation for learning value of syntactical sugar. I hope you like it. Maybe I am misreading this (it could mean simply what it literally says), but I read it as unconstructive snark.
- riffraff 11y ago> You can see every single rebinding of a variable within the lexical scope of the function, I do not think that is true, a called function can side effect the caller environment via `arguments` if that is passed around.
- braythwayt 11y agoMy understanding is that arguments caller has been removed, and Function.prototype.caller is non-standard: > The obsolete `arguments.caller` property used to provide the > function that invoked the currently executing function. This > property has been removed and no longer works. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/arguments/caller https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe... Can you provide an example of modifying a declared variable in a calling environment? I'm very interested!
- riffraff 11y agoI meant this: function sidEffecting(ary) { ary[0] = ary[2]; } function bar(a,b,c) { c = 10 sidEffecting(arguments); return a + b + c; } bar(1,1,1) // I expect 12, but is 21 I now realize this could actually be not allowed anymore in recent ES, I am not sure, but copy & paste in chrome console still prints 21.