

Why I sometimes hate JavaScript - mschoebel
http://geekregator.com/2015-02-27-why_i_sometimes_hate_javascript.html

======
nothrabannosir
The "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
> Or use strict mode would not allow that.

It was in strict mode. It allows that.

~~~
nothrabannosir
True, 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?)

------
nkozyra
The 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.

~~~
vcarl
This 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.

~~~
Flimm
Yes, it is the language's fault. The language could have been better designed,
here are some solutions:

1\. Assignments in conditions could be required to be surrounded with an
additional pair of parentheses, like this: `if ((x = true)) {}`. GCC with
warnings already requires this for C.

2\. The assignment operator could be something other than the equal signs, for
example, it could be `:=`. Assignment is so different from mathematical
equality and beginners to programming trip up on this all the time, it's a
shame programming languages copy each other for familiarity and keep this bad
design.

3\. Assignments in conditions could be banned out right, like Python does.

~~~
ufo
Sure, but detecting assignments inside conditionals is very easy and every
compiler worth its salt gives warnings for them.

IMO, the really annoying language faults are the sort of thing that can't be
fixed by a simple linter: object keys being converted to strings, the wonky
pseudo-classy prototypal inheritance, dealing with libraries that abuse
Function.toString or eval, etc.

------
d4n3
Jshint 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)

------
thebouv
Good 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.

~~~
TheOtherHobbes
As 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.

~~~
Mithaldu
You know that kind of bullying where someone grabs someone else's arm and uses
it to hit them in the head with their own hand, while yelling "Stop hitting
yourself! Why are you hitting yourself?"?

Javascript's automagic semicolon is that, and you're the kind of person who
condones it.

Yes, at the end of the day one has to learn how to deal with the automagic
semicolon, if one doesn't just give up on Javascript wholesale and finds a way
to write better languages. However the very presence and behavior of that code
in every javascript interpreter is still a cruel misbehavior whose
implementation was a mistake. It is just as cruel and as much of a mistake to
imply even in the slightest way that it isn't.

The correct response is to not blame the coder who stumbles over that, but to
gently let them know that yes, Javascript is a bad language, and to gracefully
show them how to not fall into that trap.

~~~
TheOtherHobbes
Actually _that 's what I said_.

I wasn't blaming the coder _or_ the language.

I was saying that it would help everyone if there was top quality online help
explaining how to code around language deficiencies - the kind of deficiencies
that _everyone_ has to deal with it, because no language is perfect, and most
languages are quite a lot less than perfect in at least some respects.

Be realistic. js isn't suddenly going to be rewritten with a proper semicolon
patch. It's too established, and it would break too much code.

So complaining about it is a waste of everyone's time. It's like complaining
about the fact that sometimes it gets cold in the winter.

It's more productive to do something practical about producing quality code
that minimise possible problems, surely?

~~~
Mithaldu
I want to make sure that you understand why i wrote that post. I saw you
mentioning that the docs need to be better. I actually KNOW the problem, since
we have it in Perl too, and i made a site for it. ( perl-tutorial.org )

However, your first two lines were still:

> the implied semicolon isn't the problem.

> The problem is [...] the code [...]

Which is simply not an acceptable thing to say. The first thing to do is
admitting that the language is the problem, not the coders or their code. The
second thing is, now they're listening instead of being disgusted at you, to
tell them solutions.

------
falcolas
Lots 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
Agreed.

"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
These 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
Oh, 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.

------
david-given
Optional 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
Isn'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
Bah. 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...

------
QuantumRoar
I 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.

------
tshadwell
Honestly, there should have been a loop there. The author introduced un-
necessary complexity and a bug appeared. Not that Javascript is a great
language.

------
bceagle
Sure, 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.

~~~
oweiler
Exactly 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
Plus, with a text editor plugin like
[https://packagecontrol.io/packages/SublimeLinter-
jshint](https://packagecontrol.io/packages/SublimeLinter-jshint) it becomes a
no-brainer.

------
tinco
If 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.

~~~
unwind
Is a function longer than 10 lines considered a problem by JavaScript analysis
tools (or their users)? Surely you jest?

~~~
tinco
No, 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
I 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.

~~~
mschoebel
Great. So I could have just left that 100-line function as it was and been
spared that 30-minute bug-hunt for the missing "+".

Of course I wouldn't have written that blog-article then, and wouldn't have
gotten onto the HN homepage... Oh, well... :)

------
dukky
I 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?

~~~
d4n3
Javascript 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.

------
savanaly
Whenever you can't find the bug in javascript, I beg you to run the code
through jslint. It would have caught this right away.

------
d4n3
It'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
All the functions in that code return numbers.

~~~
alexsop2
Making [`.reduce`]([https://developer.mozilla.org/en-
US/docs/Web/JavaScript/Refe...](https://developer.mozilla.org/en-
US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce)) a significantly
better choice.

------
emehrkay
My 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.

------
thaumaturgy
I 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.

------
collyw
Doesn'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.

------
axeldelmas
You'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.

------
garretraziel
What 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
Ehm, 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
As 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.

------
bpg_92
I agree that JSlint would catch this, but then againg that doesn't seem like a
valid argument to defend JS in this specific subject.

------
shaunrussell
JSHint is a thing.

Also, I think you are looking for typescript.

------
tempodox
That title looks rather backwards to me. You don't need a reason to hate JS.
You do need a reason to not hate it.

------
ttty
I've spotted the error in less than 5 seconds... \+ I personally don't like
the way you write code.

------
taytus
I saw the error in 30 secs. Advice: try to use dislike instead of Hate.

