6 ms·
Why I sometimes hate JavaScript
- bceagle 12y agoSure, this is annoying, but the reality is that this type of stuff is very easily avoided through the use of linters. IMO, you should never work on a dynamic scripted language like JavaScript without constantly running a linter in the background to pick up stuff like this.
- deleted 12y ago[deleted]
- oweiler 12y agoExactly my thoughts. Just ran the snippet through JSHINT and while it doesn't recognize the exact error it shows you the location where it happens. http://jsfiddle.net/hnxjxyte/ http://jsfiddle.net/hnxjxyte/
- pixelman32 12y agoPlus, with a text editor plugin like https://packagecontrol.io/packages/SublimeLinter-jshint https://packagecontrol.io/packages/SublimeLinter-jshint it becomes a no-brainer.
- tshadwell 12y agoHonestly, there should have been a loop there. The author introduced un-necessary complexity and a bug appeared. Not that Javascript is a great language.
- tinco 12y agoIf you only hate Javascript sometimes, you are definitely new to the language. That said even in a proper language like Ruby this particular bug can happen, that's why communities around these languages strongly encourage proper discipline, enforced by tools. This bug most definitely should've made your tests go red, your linter give a warning and your code metrics suite should have a thing or two to about the huge expressions and 10+ line function they are in.
- mschoebel 12y agoThankfully the bug DID make my tests go red.
- unwind 12y agoIs a function longer than 10 lines considered a problem by JavaScript analysis tools (or their users)? Surely you jest?
- tinco 12y agoNo, by Ruby analysis tools like Rubocop. For my Javascript I use CoffeeScript, and I rarely go over 10 lines for a function. Javascript obviously is a bit weird in this because many Javascript programmers wrap whole prototypes in closures. If your function is over 10 lines, it's probably bad, just look at your functions. Every 10+ line function I've ever written was only that long because of laziness and reducing them has always resulted in better legibility.
- kristiandupont 12y agoI remember Code Complete giving a different recommendation, googled and found this: http://stackoverflow.com/a/670039 http://stackoverflow.com/a/670039 >I recently wrote some code for Class::Sniff which would detect "long methods" and report them as a code smell. I even wrote a blog post about how I did this (quelle surprise, eh?). That's when Ben Tilly asked an embarrassingly obvious question: how do I know that long methods are a code smell? >I threw out the usual justifications, but he wouldn't let up. He wanted information and he cited the excellent book Code Complete as a counter-argument. I got down my copy of this book and started reading "How Long Should A Routine Be" (page 175, second edition). The author, Steve McConnell, argues that routines should not be longer than 200 lines. Holy crud! That's waaaaaay to long. If a routine is longer than about 20 or 30 lines, I reckon it's time to break it up. >Regrettably, McConnell has the cheek to cite six separate studies, all of which found that longer routines were not only not correlated with a greater defect rate, but were also often cheaper to develop and easier to comprehend. As a result, the latest version of Class::Sniff on github now documents that longer routines may not be a code smell after all. Ben was right. I was wrong.
- savanaly 12y agoWhenever you can't find the bug in javascript, I beg you to run the code through jslint. It would have caught this right away.
- savanaly 12y agoWhenever you can't find the bug in javascript, I beg you to run the code through jslint. It would have caught this right away.
- garretraziel 12y agoWhat Node.js taught me is that JavaScript is language like any other. It has good parts, it has quirks and you have to know what are its strenghts and what are its weaknesses to use it properly. And you can say that about any other language.
- nothrabannosir 12y agoEhm, yes. Sorry to ask this, but what is your point? I don't understand why you are saying this thing, which nobody here would disagree with. Does what you just said mean that we shouldn't talk about JS's weaknesses? Or do you mean that we can, but that the points the author brings up have been beaten to death time and time again here on HN and this post + the inevitable comments it will attract have nothing to offer? Those are the only two options I can think of for now. Or did you mean something else?
- nkozyra 12y agoAs I mentioned in another comment, whether this is inherently a weakness is up for debate. Valid code that fails can happen in any language. The problem here is Javascript can be very, very forgiving, which allows one to make mistakes like this. There are many totally lucid, on-point criticisms of Javascript and at least once a day the language ticks me off, but this one is not so black-and-white.
- agumonkey 12y agoNew learning philosophy: starts with the corner cases, papercuts and deadends, then enjoy the ride.
- falcolas 12y agoLots of comments here, and on the blog, essentially stating "It's not Javascript, it's that you forgot to [lint|test|format|.+]" There are tools to make up for these language deficiencies, but our attitude to those bitten by the language deficiencies it's truly unfortunate. Even Python, everyone's second favorite dead horse for dynamically typed language problems, would throw an error here.
- lostcolony 12y agoAgreed. "It's not the language's fault; it's your fault for not using all the tools and best practices that make the language tolerable!" That, to me, sounds like the language has some deficiencies.
- jerf 12y agoThese two things are not exclusive. The language can be deficient, and you can be irresponsible not for using well-known, long-established tools for addressing those deficiencies. Normally I'd toss in a jab about deficiencies in choosing your language, too, but Javascript gets a bit of a free pass here on the browser.
- lostcolony 12y agoOh, certainly I'm not saying that a developer gets a pass for not using everything at their disposal (especially if it's something the developer had a choice on). But the implicit requirements in tooling, the fact people are blaming a developer for using the language without also relying on third party tools, tells me a lot about the language's deficiencies. Also a bit about the language's community.
- nkozyra 12y agoThe real issue here is it's not an error. In another language the compiler/parser may have thrown a warning, but the issue here is actually that this is valid Javascript. Poorly composed Javascript, but completely valid. Of course, jslint will complain about it (and a dozen other style things), so the more people utilize tools like that, the better. More than anything, it's yet another reason to employ unit testing. Valid code that fails is very hard to debug without unit testing.
- tomphoolery 12y agoHaving JSLint and a test framework in my toolchain when developing with JS is so essential...it's like trying to write Ruby without using unit tests.
- nailer 12y agoFirst thing I did was paste this into an an editor, hit ctrl J, and see if jshint sprang up anything: 12,40: Expected an assignment or function call and instead saw an expression. Adding the missing + (and hence removing the expression which doesn't do anything) fixes it.
- nkozyra 12y agoIf everything is defined beforehand, jshint will show two warnings. The code is still valid. The OP is talking about catastrophic errors as a means for surfacing problems in code. That's a pretty old-school (and I don't mean to pick on the OP, he mentions his background in the post) methodology for quality control in code. It worked a lot of the time in compiled languages because they're far more syntactically strict than languages like Javascript. And that's why we need tools like jslint/jshint. Whether that's a good thing or not depends on your comfort with the language - having the flexibility to structure code differently can be seen as a positive, but you do open yourself up for these types of errors.
- vcarl 12y agoThis is like the if (x = true) {} kind of error. Yeah it sucks, but it's not really the language's fault. Not to mention that that large a block of addition is bad code smell to me.
- dukky 12y agoI really don't see why this isn't a syntax error What is actually being done with the calls after the chain of +'s? Edit: Something to do with semicolons being optional in js?
- afandian 12y agoThis is valid JS: 1; 2; alert("returns undefined"); confirm("return true or false?") (function() {return 3})(); (function() {})(); What's being done with the values of 1, 2, undefined, true/false, 3 and undefined? Nothing if they're not assigned. But as every function returns a value and invocations are therefore an expression, it would be impossible to disallow expressions to be evaluated but not assigned.
- d4n3 12y agoJavascript has "semicolon insertion". It tries to parse a newline with no semicolon as continuing the current expression, if it can't, it inserts a semicolon. It's a 'feature' that's caused too many bugs and is a warning in most linters.
- d4n3 12y agoJshint catches this with 2 warnings: missing semicolon and expected assingment or function call. In Sublime text 3, you can have inline warnings and as-you-type linting with the sublimelinter jshint plugin: https://github.com/SublimeLinter/SublimeLinter-jshint https://github.com/SublimeLinter/SublimeLinter-jshint
- taytus 12y agoI saw the error in 30 secs. Advice: try to use dislike instead of Hate.
- david-given 12y agoOptional semicolons is my biggest hate with Javascript --- combined with expression statements silently discarding their result, it makes this kind of mistake far too easy to make. Personally I've never understood with Javascript strict mode doesn't make semicolons mandatory.
- nothrabannosir 12y agoIsn't strict mode purely semantical? IIRC you can implement a use strict pass purely on the AST, after the parser. It's not an excuse, of course.
- david-given 12y agoBah. You're absolutely right, of course, that's why strict mode won't help. Now I find myself wishing there was a stricter mode. <script type="text/sensible-javascript">, perhaps...
- shaunrussell 12y agoJSHint is a thing. Also, I think you are looking for typescript.
- axeldelmas 12y agoYou'd spot that right away if you had a visual jshint/jslint plugin in your IDE. It's a real time saver to have one: there are dozens of cases like your example that are valid JS, although it's not what you intended to write.
- nothrabannosir 12y agoThe "JSlint catches this" argument is valid, but not to defend JS. When you say: "with a linter this doesn't happen," you're defending (Javascript + linter), not Javascript. Just as when someone says: Typescript would not allow this, or that. Or use strict mode would not allow that. Yes! True. They would not. But they are not JS: they are Typescript, or JS strict mode, or... There was an article here a while back about "tabooing your words"[0], and I think it applies very well here. Instead of talking about just "Javascript", let's try to not mention it. Say "Ecmascript 5 without any tooling," or "ES 6 with 6to5", or "Ecmascript 5 with a linter", or "Ecmascript 5 in strict mode with a linter." Suddenly, you will find that everyone in this thread agrees: "Ecmascript 5 in non-strict mode, without special tooling" is a shitty language for humans to write because mistakes so easily go unnoticed. And humans make mistakes. And if you do use linting, or whatever, no need to feel offended: we're not talking about that language! In essence, saying "the linter would have caught this" is like saying "Typescript doesn't allow that". It's completely true, but it's a different language. The author was not talking about "Javscript", but about "Ecmascript 5 in strict mode without tooling." And I think we can all agree: that language is problematic. [0] https://news.ycombinator.com/item?id=6855568 https://news.ycombinator.com/item?id=6855568 EDIT: Author was talking about strict mode. Still problematic.
- mschoebel 12y ago> Or use strict mode would not allow that. It was in strict mode. It allows that.
- nothrabannosir 12y agoTrue, bad example. I was talking in general: the "yes, X has this problem, but if you tweak it to be X', then it doesn't." argument. You're not talking about X but X'. But you're totally right, use strict is not syntactical. (I think?)
- d4n3 12y agoIt's way better to use [values].join('') here... It's probably faster and it coerces all values to string. If the first couple of results were numbers or booleans, they would be summed: > true + 10 + " result" 11 result > [true,10," result"].join('') true10 result
- mschoebel 12y agoAll the functions in that code return numbers.
- d4n3 12y agoAh ok. At first glance it looked like he was putting together something like an url.
- alexsop2 12y agoMaking [`.reduce`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...) a significantly better choice.
- deleted 12y ago[deleted]
- thebouv 12y agoGood programmer, bad programmer. Good code, bad code. Let's not all pretend we don't have stupid bugs in our code regardless of editor, linting or language. JS is a mediocre language. It is popular because it is ubiquitous, not because it is good. It really does have bad error handling, weird optional rules, problems determining type when adding/concatenating with +, and the list goes on. His was a syntax error that could have been caught with linting, sure. But there is plenty of well-formed JS that passes linting but still behaves badly due to the language itself.
- Mithaldu 12y agoSpecifically the mistake Javascript is making here is one designed into the language itself: When there are no semicolons between statements, it will automatically and silently insert them. Without this behavior his mistake would've been a compile-time error and easily caught. (Of course, this leads to the bigger bug that sometimes Javascript will insert them in the wrong place.) He doesn't know exactly what the bug in Javascript is and how to point it out accurately, but he is absolutely correct that there is a bug in Javascript's design.
- ttty 12y ago>JS is a mediocre language. It is popular because it is ubiquitous, not because it is good. JS is a popular because runs on browser by default.
- thebouv 12y agoYes, which is why it is so ubiquitous.
- TheOtherHobbes 12y agoAs someone pointed out, the implied semicolon isn't the problem. The problem is that the code is written in a way that makes it vulnerable to an implied semicolon. The core syntax of JavaScript won't be changing any time soon, so it's important to teach beginners how to write code that minimises mistakes like these. I haven't seen many books and tutorials attempt this. So it's unfair to blame beginners when there's so little encouragement to learn a strong defensive coding style. jshint is nice for basic sanity checks, but it can't deal with bigger structural or stylistic mistakes. You can only fix those by learning from strong examples of good, clean code. I think this applies to all languages. Being able to solve a problem and write a solution in code symbols isn't enough. I wonder if it would help everyone if there was a store of established best practices with examples for every language.
- emehrkay 12y agoMy approach, in any language, would be to collect it in an array and sum (or concatenate) it at once. var values = []; values.push(phraseValue( result, queryData )); ... var value = values.reduce(function(prev, next) { return pre + next; }); I understand that COLLECTION.reduce may not be in all javascript implementations (or even in all languages), but that would be my first thought on how to handle that mess. Id probably even make it a function addAllOfTheseValues(result, queryData); I also dislike direct string concatenation, I always try to use print type functions because it is easier to separate variables from text and spot potential errors. I'm happy that JS is getting this.
- tempodox 12y agoThat title looks rather backwards to me. You don't need a reason to hate JS. You do need a reason to not hate it.
- QuantumRoar 12y agoI think this is a general problem for people used to the comfort of compiled languages. I also struggle with languages like JavaScript. I always have the feeling that I'm actually doing something wrong or non-standard but the webbrowser is smart enough to understand it anyway. This feels to me like I'm constantly operating in some kind of gray area where everything is "correct enough". But as others have already pointed out, this can be ameliorated by using the right tools. So the problem is actually purely about taste, I guess.
- ttty 12y agoI've spotted the error in less than 5 seconds... + I personally don't like the way you write code.
- collyw 12y agoDoesn't JS have a join function? I realize that problems like this are the reason that my coding is going in a more functional direction (I would still say I write imperative code), but I avoid "doing things manually" like this, as its easy to overlook such errors.
- bpg_92 12y agoI agree that JSlint would catch this, but then againg that doesn't seem like a valid argument to defend JS in this specific subject.
- thaumaturgy 12y agoI had a similar-ish problem just last night. Spent over an hour crawling through some code trying to figure out why it wasn't working like it was supposed to. I ended up doing the divide-and-conquer approach with "console debugging". I was cursing wildly by the end of it. All to find in the end that I had used ( ) instead of [ ] (or maybe it was the other way 'round?) in a thick spot of code, and Javascript was happy to try to do that without throwing any kind of error. That sort of thing happens in all languages to some extent, but debugging in Javascript is unmitigated hell.