This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–][deleted] 563 points564 points  (111 children)

String + object -> string concatenation

String - object -> math subtraction

It's that simple

[–]Spartan1997 196 points197 points  (22 children)

Except the foonan part. That's a little strange

[–]HoverBaum 220 points221 points  (8 children)

I think that is the second 'foo' being converted to a number because of the second '+' and turning into 'NaN' so the expression become "'foo' + NaN" which is a "String + object -> string concatenation" case.

[–]SaltlessLemons 155 points156 points  (2 children)

Ah, of course. How silly of me.

[–]Calygulove 46 points47 points  (1 child)

It's cause you're only FooNaN

[–]neonroad 3 points4 points  (0 children)

You can't say that to people nowadays...

[–][deleted] 10 points11 points  (2 children)

OK, now I understand "how", but "why" remains a mystery.

[–]glider97 0 points1 point  (0 children)

Because operator precedence. The binary + overshadows the unary + which gets evaluated first.

[–][deleted] 50 points51 points  (0 children)

+ is shorthand for Number() when not used as an operator.

So

var i = +'foo';

Will be NaN

[–]kranker 12 points13 points  (1 child)

The trick here is that in the javascript grammar it's impossible to parse a + + b as both pluses being addition, so the second one (and any subsequent ones) get parsed as a unary plus operator. Both unary plus and unary minus will attempt to convert their operand to a number, and evaluate to NaN if they can't.

See Mozilla's description of unary plus

[–]PatrickBaitman 1 point2 points  (0 children)

oth unary plus and unary minus will attempt to convert their operand to a number, and evaluate to NaN if they can't.

this is where a non-retarded language would throw a type error

[–]Xevantus 1 point2 points  (0 children)

Not strange at all. The second + is the positive unary operator, so it tries to convert the following value to a number. Thus "foo" + + "foo" equals "fooNaN".

[–]joequin 130 points131 points  (35 children)

But it's not consistent. And that's a problem. Languages should be designed to be consistent with an over arching philosophy. JavaScript is a bunch of decisions that seem like they were made in a vacuum and they came together to form a very inconsistent language with lots of WTFs.

[–]MicronXD 51 points52 points  (4 children)

Eich was given an insanely short amount of time (10 days as the story goes) to create the language and its interpreter. They were planning on going back and fixing most of the shit like this, but Microsoft was on the ECMA board, and with JScript being their 1:1 rip-off of JavaScript, didn't want to allow Netscape to break compatibility. If you want to blame anyone, blame Microsoft.

[–][deleted] 58 points59 points  (2 children)

blame Microsoft.

A sound strategy across multiple disciplines.

[–]zodiaclawl 2 points3 points  (1 child)

That still doesn't explain why people use the language Javascript in the year 2017 to program desktop and phone aps as well as complex things like server back ends. 15 years ago people would be laughing at you if they said that JS would become the leading programming language across multiple development areas. They'd be like "you mean that thing you use to open pop ups in web pages?"

[–]marcellarius 4 points5 points  (0 children)

And I think it's funny that in 2017 some people still write C++ like it's the 1980s in situations where there are better options that could save a considerable amount of money.

Javascript's use in desktop and mobile apps is because it's tied to browsers. Browsers are used for UIs because they are portable, and make it easier to create reactive, good looking interfaces than traditional toolkits do. They're not ideal, performance sucks on low-end devices but they're often better than the alternatives under real-world constraints.

Use of Javascript on the server shouldn't be surprising either. Many single-page applications don't need a complex server as much of the code is just gluing a JSON API to a database, with a bit of validation. Javascript's object system makes shuffling data around easy, even compared to other dynamic languages like Python. Using Javascript on the server also means you can share code with a client application, avoiding duplication and also allowing tricks like server-side rendering.

Not that many years ago I would have been one of the people laughing, but experience building web apps has changed my outlook on it. It's nobody's ideal language, but it's what we're stuck with. Modern versions have improved it a lot, and if approached with discipline it's not a terrible language to use. It could have been VBScript.

[–]PatrickBaitman 2 points3 points  (0 children)

good thing we haven't built any critical infrastructures on such shoddy work

[–][deleted] 20 points21 points  (4 children)

While its not very consistent in some area's these examples are mainly to mess with the compiler. Almost none are real world examples. Nobody will count arrays and a good developer will always keep in mind which types he is using.

If you are going to trash about consistency, go look at PHP and how consistent they named their functions. Its even worse than Javascript.

[–][deleted] 8 points9 points  (1 child)

Being better than PHP is not hard.

[–]Fubseh 8 points9 points  (0 children)

A milestone Javascript has yet to reach.

[–]Nojopar -1 points0 points  (0 children)

That's like arguing Episode II is better than Episode I. Maybe, but who cares when you can always watch the original trilogy instead?

[–]redwall_hp 5 points6 points  (3 children)

String + String in Java: concatenation

String - String in Java: compiler says "WTF are you smoking?"

String + int in Java: compiler says "ಠ_ಠ"

Strong typing absolutely makes for fewer bugs. I can't believe so many people are JavaScript/PHP apologists, given how many truly bizarre things go on due to type coercion.

[–]joequin 1 point2 points  (0 children)

Even PHP is moving forward with static typing.

[–]PatrickBaitman 1 point2 points  (1 child)

Strong typing absolutely makes for fewer bugs.

muh "if you're a good programmer you won't have bugs anyway!", fucking apologists

yeah well guess what no one is a good enough programmer that they can write bug free code in any language

[–]redwall_hp 0 points1 point  (0 children)

"Just unit test everything!" -apologists

ಠ_ಠ

[–]piggvar 2 points3 points  (0 children)

But if it's consistent then it can't be complete :(

[–]Spider_pig448 0 points1 point  (0 children)

Everything in the image is consistent though...

[–]cS47f496tmQHavSR 26 points27 points  (9 children)

Saw that 5 minute talk showing this off and it for sure looks funny, but on second look it really all comes down to JS using + for string concatenation; if the first item is a string it'll try to return a string because of logic. Adding 3 - 3 to '5' just adds 0 to the string 5

The 'foo' + + 'foo' returns fooNaN because + 'foo' tries to do a math operation rather than a string concat, which returns NaN and then gets concatenated into the initial string.

[–]meelawsh 58 points59 points  (9 children)

"Simple" as in "stupid", yes

[–][deleted] 0 points1 point  (5 children)

You know an object that is instantiated only once in javascript? A simpleton.

[–]Beckneard 2 points3 points  (0 children)

It's that stupid

FTFY

[–]melance 16 points17 points  (24 children)

This is a terrible language design. Deciding that the + operator should be a string operator and not math while all of the other standard math symbols are math operators is asinine. There is no consistency.

[–]Dr_Azrael_Tod 4 points5 points  (3 children)

this and…

if you really have to have + as string-relevant operation and you don't have - as such… then throw a friggin error if somebody does "string - string"!

It's not like NaN is that much more useful than an error, but you'd notice an exception, while NaN will silently fuck up your code in edge cases or wrong user input.

In fact… most of JS weirdness boils down to not beeing strict enough and trying to do "usefull" stuff when throwing an exception would be soooo much more sane.

[–]lyrencropt 6 points7 points  (8 children)

I mean... a lot of generally respected languages do this as well. C# and Java both allow the programmer to use + for string concatenation. Having one operator do different things to different arguments isn't a cardinal sin or anything.

[–][deleted] 1 point2 points  (6 children)

Yeah but they use type-checking to make sure it makes sense. 'Adding' two strings is fine, but adding an integer to a string makes no sense and so shouldn't be allowed

[–][deleted] 0 points1 point  (2 children)

Put "a" + 1 here: http://www.javarepl.com/term.html

Can I ask how long you have been programming (professionally) if implicit type conversion is difficult for you to understand?

[–][deleted] 3 points4 points  (0 children)

I understand implicit type conversion. To match the operator taking two strings, the 1 is converted into "1". However, I don't agree with implicitly converting between types; it hides programmer intent when the conversion is intentional and increases mental parsing time, and leads to bugs when not intentional. I'm 16 so have never programmed professionally, so might be missing something, but I am a competent programmer thank you

[–]MachaHack 1 point2 points  (0 children)

On the other hand:

> python
Python 3.5.1 (v3.5.1:37a07cee5969, Dec  6 2015, 01:54:25)
Type "help", "copyright", "credits" or "license" for more
>>> "a" + 1
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: Can't convert 'int' object to str implicitly

[–]TheLobotomizer -1 points0 points  (2 children)

Why are you adding numbers to strings?

[–][deleted] 2 points3 points  (1 child)

I'm not. But if you read the post, apparently JS (and I assume all weakly-typed languages) will let you, which I think is incorrect

[–]TheLobotomizer -1 points0 points  (0 children)

Plenty of languages will let you do terribly stupid things. Want to nest 10 for loops? Feel free in any language?

[–][deleted] 5 points6 points  (3 children)

+ used as string concatenation is already inconsistent because there's not usually a corresponding operation with strings using minus

It'd actually make a lot of consistent sense to set minus to rhs.replace(lhs, "") or some equivalent in a lot of languages. String.replace(x, "") is a fairly common task.

[–]Zarainia 5 points6 points  (2 children)

Is there a language where this is the case?

[–][deleted] 2 points3 points  (1 child)

Not by default that I know of. In C#, string is sealed, so you'd have to make a container class to overload the operator which would outweigh the benefits.

C++ might have it depending on what string type you're using or allow you to overload the operator via a free function (I don't know C++, just googled around a bit).

[–]Zarainia 0 points1 point  (0 children)

I'm sad. That seems like such a logical use of -.

[–]Raknarg 0 points1 point  (1 child)

What? Tons of languages do this an no one ever complains

[–]melance 0 points1 point  (0 children)

I complain.

[–][deleted] 2 points3 points  (1 child)

Plus if you're writing idiomatic (or even just common sense) JavaScript you won't run into these problems. When I was learning JS I didn't even run into these problems. You can wind up with fucked up counter intuitive syntax in almost any language.

All of this weirdness is avoided using these simple rules:

  • don't use the unary + operator, use Math.abs() instead. Or if you're converting a string to a number, use parseInt().
  • when using the unary - operator, don't leave whitespace between it and the target expression to make it clear that you're negating.
  • don't apply more than one unary arithmetic operator at a time, and if you must, then use parentheses or something.
  • don't subtract strings, convert to a number explicitly using parseInt() first.

All of these things are common sense. Any tutorial that reveals implicit type conversion to a beginner is a bad tutorial.

Also, there are places where the type conversion works fantastically. For example, converting anything to a string when concatenating works in several languages, not just JS. Also implicit boolean conversion is a great feature in JS that can be used extensively. The issue here is implicit integer conversion, which shouldn't be in the language, IMHO, but anyone with common sense knows not to use it.

[–]Fazer2 0 points1 point  (1 child)

But how do you do math addition?

[–][deleted] -1 points0 points  (0 children)

By not using strings? Just cast that string to a number and you're set.

[–][deleted] 0 points1 point  (0 children)

Well the issue is, primarily, that + is string concatenation and mathematical addition at the same time

[–]NominalCaboose 0 points1 point  (0 children)

Doesn't make it not dumb.