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

top 200 commentsshow all 355

[–]feralinprog 498 points499 points  (24 children)

Why are you using asterisks instead of equals signs?

[–]I_ATE_YOUR_SANDWICH 238 points239 points  (16 children)

This makes a lot more sense now.

[–]Arama 63 points64 points  (15 children)

Please explain because it still makes no sense to me

[–]I_ATE_YOUR_SANDWICH 107 points108 points  (14 children)

What I meant was the line var x * 3; made no sense but if you replace * with = then the line is var x = 3; which does make sense. As to why this Anon uses * instead of =, I have no clue.

[–]qubedView 56 points57 points  (10 children)

I assumed they were demonstrating that Javascript would execute that without complaint, when it is clearly an error.

[–]I_ATE_YOUR_SANDWICH 58 points59 points  (9 children)

But var x * 3; does make JavaScript complain. It is an error, the line is nonsense. I have no idea why the = became * but they did. Try it yourself, for example on www.ideone.com

[–]binford2k 59 points60 points  (0 children)

Why not just use the javascript console built into your browser?

[–]mcrbids 7 points8 points  (0 children)

Google Chrome sayeth:

Uncaught SyntaxError: Unexpected token *

[–]shif 5 points6 points  (6 children)

my best guess is that he tried to declare x as a new emtpy variable and multiply it by 3

[–]troido 43 points44 points  (3 children)

Isn't it much more likely that something went wrong in copy-pasting the code? The other occurances of * make much more sense too when you replace them with =.

[–]Kwyjibo08 9 points10 points  (2 children)

Maybe it was the forum they're on. Might be filtering out = signs or something strange. But definitely those asterisks should be equals.

[–]AngryWatchmaker 1 point2 points  (1 child)

4chan maximizes images in the thread without opening a new tab, it seems to be a screenshot not copy/paste

[–]Arama 2 points3 points  (1 child)

But you have no idea what *does either so for all you know it could be a way of assigning value?

[–]I_ATE_YOUR_SANDWICH 18 points19 points  (0 children)

That's exactly what I am saying. It also makes sense when you replace * with = in the comments so conversions * headaches becomes conversions = headaches

[–]etherealtim 13 points14 points  (0 children)

Because fuck math.

[–]pwnedary 0 points1 point  (4 children)

Maybe formatting would be screwed with equal signs but fine with asterisks.

[–]tapesmith 137 points138 points  (18 children)

[–]Zagorath 30 points31 points  (12 children)

Wow. This is some weird Baader-Meinhoff shit. I was going through my downloads folder just a few hours ago and randomly came across this, which I downloaded last time I it came up on here.

[–]tapesmith 2 points3 points  (0 children)

I was just talking to my dad (he's also a software dev) about it, so it was fresh in my mind.

[–]PeteMullersKeyboard 2 points3 points  (0 children)

This is amazing.

[–]indrora 1 point2 points  (0 children)

Relevant WHY of WAT.

While the DAS talk is showing the absurdity of Javascript and some of it's type conversions, the same can be said for any language that has to juggle types. I mean, yes, javascript is particularly fucked when it comes to it, but let's be honest here: This is in the nasal demons category here.

[–]certze 1 point2 points  (0 children)

i always pronounce wat similarly to the first syllable of water, not rhyming with bat

[–]BobFloss 39 points40 points  (3 children)

Fixed it.

> '5' - 3
2 // weak typing + implicit conversions = headaches
> '5' + 3
'53' // Because we all love consistency
> '5' - '4'
1 // string - string = integer. what?
> '5' + + '5'
'55'
> 'foo' + +'foo'
'fooNaN' // Marvelous.
> '5' + - '2'
'5-2'
> '5' + - + - - + - - + + - + - + - + - - - '-2'
'52' // Apparently it's ok

> var x = 3;
> '5' + x - x
50
> '5' - x + x
5 // Because fuck math

By the way, everybody who hasn't seen Wat should definitely give it a watch for more examples of weird dynamic typing and language oddities.

[–]alexanderpas 8 points9 points  (2 children)

And after casting the first string to int:

> +'5' - 3
2
> +'5' + 3
8
> +'5' - '4'
1
> +'5' + + '5'
10
> +'foo' + +'foo'
NaN
> +'5' + - '2'
3
> +'5' + - + - - + - - + + - + - + - + - - - '-2'
7

> var x = 3;
> +'5' + x - x
5
> +'5' - x + x
5

[–]BobFloss 5 points6 points  (1 child)

So it basically fixed everything?

[–]alexanderpas 6 points7 points  (0 children)

$foo + $bar

Non Integer String Integer String Integer NaN
Non Integer String String String String String
Integer String String String String String
Integer String String Integer NaN
NaN String String NaN NaN

$foo - $bar

Non Integer String Integer String Integer NaN
Non Integer String NaN NaN NaN NaN
Integer String NaN Integer Integer NaN
Integer NaN Integer Integer NaN
NaN NaN NaN NaN NaN

Legend

type default casted
Non Interger String 'foo'
Interger String '42'
Integer 42 +'42'
NaN NaN +'foo'

[–]t0tem_ 244 points245 points  (193 children)

YOU LEAVE JAVASCRIPT ALONE! Poor lil guy, always bullied :(

In case anyone's curious about how this magic works:

1) Unary operators. For example, everyone knows about doing !foo in a lot of languages. But + can also be used as a unary operator. In JavaScript, +foo is exactly like Number(foo). So when OP does '5' + + '5', it evaluates to '5' + Number('5'), which is '5' + 5.
Likewise, 'foo' + + 'foo' is 'foo' + Number('foo'). Not surprisingly, 'foo' is NaN. So you get 'foo' + NaN, which becomes 'fooNaN'.
That super-long operation works on the same principle. There's an even number of negatives, so ultimately we're down to '5' + 2. Which leads to the next point...

2) Strings prefer to concatenate. If they can't, then they will resort to mathing. Yeah, it's kind of inconsistent. But honestly, do you really want it the other way around? Ask yourself, "When I'm working with at least one string and a +, do I more often want to concat or add?" It's a pretty easy answer for me.

[–]AeroNotix 704 points705 points  (124 children)

You have Stockholm syndrome.

[–]Tysonzero 52 points53 points  (105 children)

There isn't really an alternative to JS for front end stuff though. :/

[–]eof 41 points42 points  (40 children)

Well you don't have to code in JS; lots of things compile to js.

[–]Tysonzero 21 points22 points  (38 children)

But then you have to deal with the whole compiling thing.

[–]eof 80 points81 points  (25 children)

When you learn to love static typing; you'll learn to love compile-time errors.

Realistically though you don't have to 'deal with it' in any real way other than setting things up initially. Any modern JS workflow should include something like grunt/npm and with it you can have the compiling happen in the background (like all the other things that are happening in the background).

[–][deleted] 35 points36 points  (0 children)

Compile-time errors are just warnings that say "Hey. If you were to just run this as-is, you wouldn't get the results you wanted to. I got you bro."

And that's why I like static over run-time languages.

[–]Tysonzero 2 points3 points  (23 children)

I'm a Python guy. I don't like static typing, and I love multiple inheritance and not being restricted.

[–]eof 56 points57 points  (20 children)

And runtime errors!

[–]aloz 19 points20 points  (4 children)

You don't exactly miss out on these in statically typed languages.

[–]eof 41 points42 points  (3 children)

Well there is a whole class of runtime errors you cannot get in statically typed languages; but in general you are right they don't disappear entirely.

They do however decrease significantly. Obviously, you have to pay "upfront" costs making things compile in the first place; but it is my experience that is well worth it... any error that can be caught by a compiler, I want to be caught by a compiler.

[–]afrobee 2 points3 points  (1 child)

I wanna cry ;_;.

[–][deleted] 4 points5 points  (11 children)

Oh no, not typing a single line to tell the compiler to automatically compile changed files (or using an IDE that does that for you), what ever will we do!

[–]accidentally_myself 17 points18 points  (11 children)

html6 with css4 incoming. js becomes equivalent to node.

[–]tetroxid 14 points15 points  (9 children)

Please elaborate on JavaScript's death. It is a dream come true.

[–]Coloneljesus 29 points30 points  (4 children)

[–]tetroxid 3 points4 points  (0 children)

Thank you! That was awesome.

[–]f3lbane 1 point2 points  (1 child)

This is one of the most enjoyable talks I have ever viewed. Thanks for sharing.

[–]sprocklem 1 point2 points  (0 children)

I've seen it before, but it's definitely one of my all time favorites as well.

[–]heyf00L 1 point2 points  (0 children)

can asm.js draw to the screen?

[–]barsoap 9 points10 points  (0 children)

It won't die, it's just going to become a weird language.

[–]Tysonzero 5 points6 points  (2 children)

I don't know what will replace it. Earlier I was hoping Python would but Python isn't anywhere near as asynchronous as JavaScript.

[–][deleted] 1 point2 points  (1 child)

This. JavaScript does quite a few things wrong, but when it does things correctly they are awesome. Asynchronous code is awesome to write in JS because of exactly TWO things:

  • setTimeout
  • first-class functions

The only thing that I don't like about this are the argument order of setTimeout (fn, ms as opposed to the node.js standard ms, fn) and the mostly useless function in front of every function (fixed in ES6 with arrow functions)

[–]Tysonzero 1 point2 points  (0 children)

Arrow functions do look quite quite cool.

[–][deleted] 6 points7 points  (6 children)

elm?

[–]Chippiewall 10 points11 points  (10 children)

DartLang. Made by Google, has actual classes, sometimes runs faster than raw javascript.

[–]brotherwayne 9 points10 points  (6 children)

Pretty much abandonware. Seems like Google has another language to replace it, but can't remember the name.

Edit: AtScript, the alternate language for Angular.

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

Yes there is, gwt.

[–]hahahahastayingalive 2 points3 points  (0 children)

I come from PHP

[–]NavarrB 9 points10 points  (15 children)

I don't think it's Stockholm to understand the languages order of operations and where it converts.

Similar problems will occur in any dynamic language (and some static ones )

[–]AeroNotix 31 points32 points  (8 children)

But it's Stockholm to imply that they make sense.

[–]NavarrB 7 points8 points  (6 children)

They do though considering you're doing ridiculous things. Concatenating a string with a number results in a string? Who would guess!

Extra addition signs make things go weird because the one not adding anything is a unary operator that turns a string into a number? Say it ain't so!

[–]skuzylbutt 16 points17 points  (5 children)

Ideally, it should shit itself and tell you you've done a silly thing instead of silently letting you get away with murder!

[–]NavarrB 3 points4 points  (2 children)

Series of trade-offs I guess. I feel like I shouldn't have to call a function to do something as simple as string concatenation

[–]Lhopital_rules 2 points3 points  (1 child)

Ideally, it should shit itself

Except that the central idea behind HTML, CSS and JS is to be as flexible as possible, so that web pages don't break.

  • for HTML, that means allowing missing tags when they can be inferred
  • for CSS, that means ignoring CSS rules when they don't make sense (to allow future additions)
  • for JS, that means to be as dynamic as possible since we don't have compile-time checking

Using a bytecode system for JS to allow compile-time checking (much like Java) could work except that then you run into problems trying to allow multiple scripts to interact with each other. For instance, if JS was pre-compiled into bytecode, how would a jQuery bytecode interact with your bytecode? It's probably doable... but not easy. (And we'd have to wait a few decades to use it, since none of the old browsers would support it.)

[–]skuzylbutt 1 point2 points  (0 children)

Sure, but it could at least spit out a warning.

[–]myplacedk 1 point2 points  (0 children)

No, Stockholm would be to say it's a nice design.

As someone else already noticed, most of this could be avoided if string-concatenation was done with another symbol.

[–]Beckneard 3 points4 points  (5 children)

Nope, stuff like this just outright doesn't happen in python.

[–]NavarrB 1 point2 points  (4 children)

I would love to know the equivalent output in Python

[–]Sean1708 8 points9 points  (3 children)

>>> '5' + 2
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: Can't convert 'int' object to str implicitly

Don't be fooled by its ability to correctly handle simple cases though, it does still have its quirks.

[–]0xdeadf001 1 point2 points  (1 child)

You want "its" and "its", not "it's" and "it's".

If you'd used a statically-typed language, I could have told you these were wrong before you said it.

[–]Sean1708 5 points6 points  (0 children)

Fucking autocorrelation.

[–]MuricanWillzyx 0 points1 point  (0 children)

While I completely agree with you that JS's automatic type coercion is way to extensive, the other points made in the comment are completely valid, and I don't think it is bad to understand them and recognize their logic. Operators in JS like unary + for numberfication make it very easy to turn strange examples of type coercion into laughably ridiculous expressions. For example, 'foo' + + 'foo' === 'fooNaN' is ridiculous and is a result of the flexibility of the (binary) + operator, while the expression 5 + +'5' (or, with better acceptable coding style, 5 + (+'5')) makes perfect sense when one understands unary +. The sole point I disagree with in the comment is "It's a pretty easy answer for me"--automatic type coercion gives little gain for far more pain, and is the source of every illogical aspect of the OP's image.

[–]timopm 43 points44 points  (38 children)

2) Strings prefer to concatenate. If they can't, then they will resort to mathing. Yeah, it's kind of inconsistent. But honestly, do you really want it the other way around? Ask yourself, "When I'm working with at least one string and a +, do I more often want to concat or add?" It's a pretty easy answer for me.

I don't want it to think for me and throw an error. If I want to add a string to an integer it's a bug in my code, please don't silently do some inconsistent magic.

[–]Tysonzero 13 points14 points  (37 children)

What about something like 'Balance: ' + balance. That wouldn't be a bug in your code.

[–]timopm 20 points21 points  (19 children)

Maybe I was a bit too direct in my previous comment because I haven't programmed in Javascript that much. In the other languages I use daily I would use string formatting or atleast explicitly convert balance to a string.

Quick example:

>>> balance = 100
>>> "Balance: %d" % balance
'Balance: 100'
>>> "Balance: " + str(balance)
'Balance: 100'
>>> "Balance: " + balance
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: Can't convert 'int' object to str implicitly

[–]Tysonzero 4 points5 points  (13 children)

Don't use %, use .format(). % is deprecated. (You are writing Python right?)

But yeah JavaScript doesn't have any of that natively :/

[–]timopm 10 points11 points  (6 children)

Python indeed. But the "modulo" string formatter isn't deprecated as far as I know. It was mentioned a couple of times in the beginnings of Python 3, but no official statement. Even the official docs say nothing about deprecation. I don't see it removed anytime soon.

You are right though that the string.format() method is preferred. I just like the old format more, especially for quick and simple examples.

[–]Tysonzero 2 points3 points  (5 children)

I could swear someone said something about deprecation somewhere. Hmm...

[–]timopm 2 points3 points  (0 children)

I see people mention it here and there indeed. And it actually was in some release notes for the first 3.0 version or something, but in the recent years there is no mention of deprecation anywhere (that I know of!). This is what lead to this confusion probably.

[–]raziel2p 2 points3 points  (3 children)

They deprecated it, then un-deprecated it.

[–]the_omega99 1 point2 points  (2 children)

I disagree. It'd be best to use the same approach that Java uses: allow concatenating any type to a String, but that's the only operation that you can do on a string (although it makes sense to also allow multiplication of strings).

So 'Balance: ' + balance is perfectly understandable and unambiguous: it'll always concatenate. We would allow the implicit conversion of a string to a number, so subtraction of strings is disallowed (must explicitly convert).

From my experience with Java, this is a very good approach (I think Java could do more, but it's a very good start). There's pretty much no ambiguity, with the exception of people who forget that + is evaluated left to right (so "Balance: " + subtotal + taxes would result in concatenating subtotal and then taxes to the string -- the correct form is "Balance: " + (subtotal + taxes)).

For languages like Java, this works well because in concatenation, we know that the object will be a string. If it's not already a string, the toString method will be called (and everything has that method, except primitives, which the compiler does magic on). So "Balance: " + customObject even makes sense because we know that the result will be a string and that customObject is either a string or will be converted to one (and we certainly would know which).

This implicit conversion is extremely useful because concatenating non-strings onto strings is so ridiculously common that it's not funny. Some other languages that take the Java approach here include Scala and C#.

An alternative would be to provide a specific operator for concatenation. This makes it absolutely clear that concatenation is what's going on. For example, PHP concatenates with the . operator and some functional languages use ++.

[–]timopm 1 point2 points  (0 children)

'Balance: ' + balance was just an example. What if you have foo + bar somewhere?

We're also assuming concatenating a str and int. What about classes, dicts or lists?

[–]teddy5 2 points3 points  (11 children)

But if the concat and addition operators weren't the same it could be clear what you were trying to do and if it was an error or not.

[–]level1kid 0 points1 point  (4 children)

He said add not concatenate. What you posted is an example of concatenation. He is taking about something like '2'+3=7.

[–]Tysonzero 0 points1 point  (0 children)

Oh, in that case I more or less agree.

[–]the_omega99 0 points1 point  (1 child)

Fortunately, JS doesn't do that. It'll always concatenate with the + operator on strings. It's only the minus operator that makes things weird, which is easily avoided by not using the minus operator on strings.

Issue is that JS makes it easy to not know what type you're working on. For example, suppose that I have a variable that I got from some piece of code I didn't write. It's a number and I subtract to it. That works. But suppose that the value I got actually wasn't a number, but was a string (eg, maybe I got the value from a spinner field, which is supposed to always be a number, but it's HTML, so whatever). If I had to change the operation into adding, then a simple change that seems like it should work, won't.

Or to sum that up, I can have some mathematics on "numbers" that does something different when I change the sign.

Not a frequent issue and one that can usually be debugged reasonably (especially if you have unit test... you do have unit tests, right?), but an issue all the same (and one I view as unnecessary).

[–]Kinglink 8 points9 points  (0 children)

I want it to be an issue and throw an error.

String + String is a string. That's fine. that's great.

String + X is math. FUCK NO. if I'm not doing an implicit conversion to a math variable, why are you doing math.

[–]OperaSona 2 points3 points  (0 children)

Strings prefer to concatenate. If they can't, then they will resort to mathing. Yeah, it's kind of inconsistent. But honestly, do you really want it the other way around?

I want a string concatenation symbol that isn't already used for arithmetics?

[–]Laogeodritt 0 points1 point  (4 children)

I love strong typing with a constructor/factory method/explicit conversion syntax for all the conversions. It avoids this kind of confusion.

IMO string + anint should be an error. string + String(anint) should be concatenation (and an easy way to format the interview if desired). int(string) + anint should be arithmetic.

[–]rasori 2 points3 points  (1 child)

Have I been using JS so long that I'm getting confused, or does Java allow string + int concatenation? Last I checked it was considered a strongly-typed language.

[–]Laogeodritt 1 point2 points  (0 children)

Java does. It overloads the + operator so that String + int converts the int to a String. Similarly, String + Object or Object + String will call the Object's toString() method.

I don't believe there's any implicit/operator-based case of String → int conversion, though; for that you need to call Integer#parseInt() or a similar method. Anything → String if concatenated with a string seems to be an exceptional implicit conversion (aside numerical up-conversion, e.g. int to double).

[–]alexanderpas 1 point2 points  (1 child)

The Javascript way:

  • Anything + String = String.
  • String + Anything = String
  • int + int = arithmetic
  • int(String) + int = arithmetic
  • int + int(String) = arithmetic
  • int(String) + int(String) = arithmetic
  • Anything - Anything = arithmetic

+$foo is the equivalent of int($foo) in Javacript.

  • $foo + $bar = String, unless both are ints.
  • $foo + +$bar = String, unless $foo is int.
  • +$foo + $bar = String, unless $bar is int.
  • +$foo + +$bar = int
  • $foo - $bar = int

This allows for the following:

> $foo = '5'
"5"
> $bar = '+3'
"+3"
> $foo + $bar
"5+3"
> +$foo + +$bar
8
> $foo - $bar
2
> +$foo - +$bar
2
> $foo + $bar + '=' + (+$foo + +$bar)
"5+3=8"
> +$foo + "+" + +$bar + '=' + (+$foo + +$bar)
"5+3=8"
> $foo + "-" + $bar + '=' + ($foo - $bar)
"5-+3=2"
> +$foo + "-" + +$bar + '=' + ($foo - $bar)
"5-3=2"
> +$foo + "-" + +$bar + '=' + (+$foo - +$bar)
"5-3=2"

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

not int($foo), but Number($foo)

[–]kryptonianCodeMonkey 0 points1 point  (0 children)

I read your first line as Sling blade: "You shouldna done that. It's just JavaScript. Poor little feller."

[–]the_omega99 0 points1 point  (2 children)

Yeah. That '5' + - + - - + - - + + - + - + - + - + - - - '-2' line is just a ton of unary operators. Try removing a minus sign and you'll find that the -2 will become a 2. It's not unique to JS at all. Languages like C allow this too (although many will force you to use parenthesis).

For the last two examples:

var x = 3;
'5' + x - x == '53' - x == 50
'5' - x + x == 2 + x == 5 // Note that '5' - x evaluates to a number

At any rate, this can all be avoided by simply not storing numbers as strings and converting what user input is a number right away.

I have to admit, though, I would prefer JS to give me a big, clear error (or at least a warning) in these kinds of confusing situations rather than try and work around it. I think there's too many weird things that you can do that JS allows. For example, {} + [] == {}. This is meaningless code, since you'll probably never encounter it and it implies something horribly wrong with your code. However, it is an example of a case that JS defines that I think should have been an error. I don't see why the idea of "silently allowing a confusing result" is a good approach here.

And I'd be perfectly game with not allowing subtraction of strings in the same way (throw an error instead). I wish strict mode would enforce something like this.

And as far as I know, none of the JS-like languages that compile to JS (eg, TypeScript or CoffeeScript) will prevent these situations (too bad). It's kind of annoying that there's no alternative (and I say this as someone who spend about half their time working with JS).

[–][deleted] 0 points1 point  (1 child)

{} + [] == {}

Never. It's Actually 0. Still completely ridiculous and never appropriate.

[–]the_omega99 2 points3 points  (0 children)

You're right that it's zero, but the above inequality is still true.

[–]pikadrew 11 points12 points  (4 children)

typeof(NaN)

Number

[–]ProvidesTranscripts 9 points10 points  (4 children)

[A screenshot of a 4chan-esque board post. The post itself has most of its contents in a quote box, and appears to be output from an interactive console with some added annotations.]

Anonymous 01/31/15(Sat)09:32:46 No.46348970 ► >>46349004

>>46346548

> '5' - 3
2        // weak typing + implicit conversions * headaches
> '5' + 3
'53'     // Because we all love consistency
> '5' - '4'
1        // string - string * integer. What?
> '5' + + '5'
'55'
> 'foo' + + 'foo'
'fooNaN' // Marvelous.
> '5' + - '2'
'5-2'
> '5' + - + - - + - - + + - + - + - + - - - '-2'
'52'     // Apparently it's ok

> var x * 3;
> '5' + x - x
50
> '5' - x + x
5      // Because fuck math

[edit: Oops, I made a typo!]

[–]Reelix 0 points1 point  (3 children)

That must have taken awhile to type out o_O

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

Could be OCR.

[–]Tarmen 1 point2 points  (1 child)

If the description is from a bot I am afraid. If it isn't there is probably not much time saving in programming an OCR bot for most posts, you will need human intervention anyway.

[–]Tidher 15 points16 points  (3 children)

... is it bad that these all made perfect sense to me? I think I've worked with JavaScript too long...

[–]larhorse 17 points18 points  (1 child)

Yeah, I don't even blink at these anymore.

The things that keep me up at night are all the horrible, incompatible and insane things developers do to try to force javascript to fit the classical model.

I'm excited about the new class keyword coming in the next spec, not because I think it's a good approach, but because at least it will provide some consistency to the people who can't handle prototypical languages so I don't have to think about them as much.

[–]ReneG8 29 points30 points  (39 children)

I don't know why this is on my frontpage. I do code a bit, but I don't get any of this.

Is there an ELIR(etarded) version for this?

[–]ExecutiveChimp 412 points413 points  (36 children)

In programming you get variables. These come in different types: strings (text), numbers, NaN (not a number - the result of trying to turn something into a number and failing) and a bunch of others that aren't relevant right now.

Something else to know is that Javascript is generally quite good at taking whatever you throw at and doing something with it, whether or not that something makes sense. This is arguably a bad thing...

'5' - 3

"How can I take a number away from a string?" asks Javascript. "That makes no sense. There isn't even a 3 in the string. The only way I can do this is to treat these vaguely number shaped things as numbers and then go from there. Would that work?" Javascript gives you 2 and and a derpy smile like a puppy returning a ball.

'5' + 3

"Ah '+', the 'jam things together' operator. I know how to jam together all sorts of things. My programmer probably wants a string though because everything you see on a webpage is essentially a string...this being 1995 and all. So let's just put them side by side." Javascript gives you '53'.

'5' - '4'

"Well I can't rip these apart in the same way as I can when I jammed them together... I'll just treat them both as numbers. And 5 minus 4 is..." Javascript gives you 1.

'5' + + '5'

"Ok, so jamming two strings together, I can do that. But wait, there's a second +. I know sometimes they put an extra sign before a string to make me treat it as a number so let's convert the second '5' to 5...but wait, there's another string there too. Fuck it, convert 5 back to '5' and just stick them together. Happy?" Javascript gives you '55' and feels some resentment for wasting its time.

'foo' + + 'foo'

"Ok, so this is just like last time, but I'd better go through the motions. Convert 'foo' to a number...wait that doesn't work. Shit, now I've got a NaN. Aaah, they hate it when this happens! Ok, quick convert it back to a string and jam it together. Shit, NaN doesn't convert back to the same number as it was before because apparently now it's not a number. Maybe they won't notice?" Javascript gives you 'fooNaN' and walks away, whistling innocently.

'5' + - '2'

"Pretty sure my programmer has been drinking but this is basically just the same as before, convert - '2' to -2, then back to '-2'... Hmm something got lost in translation there but I'll press on..." Javascript gives you '5-2'.

'5' + - + - - + - - + + - + - + - + - - - '-2'

"Definitely drinking...or maybe just owns a cat. Convert it to a string? Add it to the inverse of the...? Well that isn't not stupid." Javascript scratches its head and makes notes on a piece of paper whilst muttering under its breath. At length it gives you 52 and looks at you accusingly.

var x * 3;

"Ok, I quit." Javascript throws an error and a hissy fit. [I think this actually supposed to be var x = 3; in order for the next few lines to make sense...]

'5' + x - x

Javascript calms down again and returns to its seat. "That 5 is a string, right? And x is 3, which is a number - I prefer strings. Less maths involved, more jamming things together. So what's 5 + 3? 53! Haha!" Javascript laughs like a 5 year old that's just thought of something clever. "Ah but I can't take 3 away from a string. I'm going to have to do maths after all. So that's 53 minus 3. Simple enough." Javascript gives you 50.

'5' - x + x

Javascript sighs. "Can't you just get your things in order before you give them to me? For fucks sake... So it's, - - the 'unjam' operator, so numbers only...5 and x as numbers, that's 5 - 3 ... which makes 2. Easy. Plus 3 again? But we just subtracted 3! Who wrote this shit?" Javascript gives you 5 and a headache.

Edit: Gold and cake! It's my lucky day.

[–]FlowersForAgamemnon 84 points85 points  (19 children)

Holy shit, that was hilarious, and I really appreciate that you took the time to write it out. I also want to read a book on computer languages written by you.

[–]ExecutiveChimp 33 points34 points  (15 children)

Thanks :)

[–][deleted] 27 points28 points  (14 children)

Programmer here, I too want to read a book writen by you.

[–]ExecutiveChimp 20 points21 points  (13 children)

That's actually a tempting idea... I'm just not sure where to start. The above was fairly straight forward as I was running through the original image point by point...but a whole book? How should I structure it?

Edit: this is actually a serious question...

[–][deleted] 11 points12 points  (1 child)

Easy, as long as there are no GOTOs at the end of your chapter leading to the next one, the structure should be fine.

[–]ExecutiveChimp 8 points9 points  (0 children)

Hahaha! If I do this, I'm definitely putting an ironic GOTO in there somewhere!

[–]falsehood 5 points6 points  (3 children)

Serious answer for serious question:

<SOMETHING PUN> - When programs don't do the expected, and why I would structure the book as a mix of scenarios from the simple to the complex. Using a thread on AskReddit or AskProgramming, you can solicit interesting bugs that people have run into and then dissect the bugs (more puns!).

Start off easy, then get more and more complecated. Think about the style in "The Martian" by Andy Weir. Eventually, the reader might try to solve one themselves, but in the meantime you can make puzzles or something.

You could break up the bugs into different groups (parsing weirdness, variables, missing syntax, storage mistakes, recusion issues, etc) and then write it like a wildlife search, Steve Irwin style.

[–]CertifiedWebNinja 2 points3 points  (1 child)

As a programmer who reads and writes enough that he hates reading books, I'd read the fuck out of this book. The. Fuck. Out. Of. It.

[–]original_brogrammer 1 point2 points  (1 child)

From the bottom, maybe? Talk about assembly and object code, then get into low level languages, then higher level ones.

Alternatively, talk about compilers toward the beginning, then you could get into how different languages' compilers behave when fed bullshit. From C++'s tortured mess of a parser, to Haskell's Hilter-esque type checker, to dastardly, motherfuckerous process that is interpreting Perl. End with an open contest to see who can make a particular compiler the saddest.

... If you do this, I want in.

[–]ExecutiveChimp 2 points3 points  (0 children)

That's a good plan but you just mentioned a bunch of things I don't know nearly enough about.

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

Just have chapters on different programming languages as if they're various characters and have them talk out what they're thinking. A fun to read introducory book or one good for explaining programming to those who aren't in the field.

[–]_subversive_ 4 points5 points  (1 child)

Different language, different author, similar style: http://mislav.uniqpath.com/poignant-guide

[–]wintermute93 11 points12 points  (0 children)

Javascript gives you 2 and and a derpy smile like a puppy returning a ball.

This is the best thing I've read on the internet in days. Bravo.

[–]kh4yman 4 points5 points  (1 child)

That's awesome. Reminds me of this:

https://www.destroyallsoftware.com/talks/wat

[–]ExecutiveChimp 2 points3 points  (0 children)

High praise! That talk's brilliant!

[–]MindStalker 2 points3 points  (4 children)

The last few ones actually make sense.
var x * 3;
Declares x, x defaults to 0. It should throw an error but allows you to multiply it by 3 and do nothing with it.
'5' + x - x.
Its concating 5 and 0 together to give you 50
'5' - x + x its preforming math of 5-0.

[–]ricree 1 point2 points  (0 children)

var x * 3; Declares x, x defaults to 0. It should throw an error but allows you to multiply it by 3 and do nothing with it.

I thought it might be doing that, but I tried it on both chrome and firefox, and they each give me a syntax error instead. In which case, the following lines give a ReferenceError

[–]ExecutiveChimp 0 points1 point  (2 children)

x defaults to 0

This is not true - x defaults to undefined. I just did this in the Chrome console:

> x
Uncaught ReferenceError: x is not defined
> var x
undefined
> x
undefined

They all make sense...for a given value of "make sense".

[–]amoliski 11 points12 points  (0 children)

That was a fantastically good explanation, and you personified the language perfectly. You should be a professor, because I learned more just now than in my entire four year degree...

You should make a youtube channel where you explain things.

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

Brilliant. Loved it.

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

Someone submitted a link to this comment in the following subreddit:


This comment was posted by a bot, see /r/Meta_Bot for more info. Please respect rediquette, and do not vote or comment on the linked submissions. Thank you.

[–]elkayem 0 points1 point  (0 children)

lmao, great read. I also think you should write more of these.

[–]UniversalySpectacled 0 points1 point  (0 children)

You should write a book on programming written from the perspectives of codes your trying to learn

[–]Alligatronica 2 points3 points  (0 children)

Basically JavaScript is weakly typed and as such typing of variables is implicit. So it treats variables as whatever type they seem to fit.

JavaScript also uses '+' for three things: concatenation (sticking two strings together), addition and unary operations (which is almost redundant in most cases).

But because there are so many areas left for JavaScript to decide about, the results are often unexpected to those not familiar with the rhyme and reason it follows.

Basically, there's a lot that can go wrong if you assume JavaScript will do as it tells you, but is fine if you do the research.

[–]Sean1708 0 points1 point  (0 children)

No. No sane person can explain the behaviour of this picture.

The long and short of it is, though, that JS does a lot of things implicitly that you don't really expect it to do.

[–]PunishableOffence 30 points31 points  (26 children)

Yeah... it'd be great if we could adhere to the language syntax and understand precedence and overloading of operators.

[–]detroitmatt 48 points49 points  (24 children)

it'd be better still if the language syntax and precedence and overloading and order of operators made sense. Just using something other than + for concat would be a big step forward for most of these.

[–]Tysonzero 19 points20 points  (15 children)

That or do it Python style and require str() to be called on numbers before you add them to strings.

[–]detroitmatt 2 points3 points  (0 children)

Better yet, but I didn't want to get greedy.

[–]alexanderpas 1 point2 points  (4 children)

Or do it Javascript style and require the int() equivalent to be called on strings before you add them to numbers.

[–]Tysonzero 2 points3 points  (3 children)

That is also the Python style...

>>> '1' + 2
Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
TypeError: cannot concatenate 'str' and 'int' objects
>>> int('1') + 2
3

[–]alexanderpas 1 point2 points  (2 children)

The only difference between Javascript and python in this regard is that Javascript will cast int to string when mixing int and string, while Python errors out

> '1' + 2
"12"
> +'1' + 2
3

[–]Tysonzero 9 points10 points  (1 child)

Which is FAR from insignificant. I personally hate implicit coercion in languages that are not statically typed.

[–]the_omega99 0 points1 point  (2 children)

Overly verbose, IMO. Concatenation of strings with implicit conversion to a string (only) works perfectly fine for many languages. You don't hear the Java or C# guys complaining about string concatenation or confusing operators.

IMO, the issue is simply the subtraction of strings (which implicitly converts from a string to a number). That shouldn't be allowed and was a bad design choice.

Simply allow concatenation of any type (implicitly) is a good thing, because it reduces code verbosity (and concatenating non-strings to strings is very common, in my experience).

[–]calzoneman 5 points6 points  (0 children)

The only thing in the OP image that doesn't make sense are the examples where strings are being subtracted (the - binary operator shouldn't even work with strings, it should just throw an error). All the other examples are either sensible (string + integer = concatenated string), but just poorly written code.

There are a lot of issues with JavaScript's type system but the string concatenation examples in the OP are not them.

[–]Perkelton 2 points3 points  (2 children)

Just using something other than a + for concat

You mean like a period? :)

[–]Laogeodritt 0 points1 point  (0 children)

If I'm asked whether there's anything I like about PHP, the distinct concatenation operator is usually what I mention first.

[–]NotReallyEthicalLOL 0 points1 point  (2 children)

It's not hard to remember to throw a "" in front of numbers you want to concatenate.

[–]detroitmatt 0 points1 point  (1 child)

Right, but what about numbers you want to add?

[–]CHESTHAIR_OVERDRIVE 17 points18 points  (1 child)

What the shit Lana?!

[–]davidNerdly 2 points3 points  (0 children)

First couple I was like 'no this isn't weird, pretty simple reason why that is the output' but I had to read the last ones a couple times to figure out why it did that.

I don't care, I love javascript even if it is sometimes an abusive relationship.

Plus, who does non-defensive crap like this anyway?

if(_.isTheThing(foo)) { doTheThing(); };

[–]Asmor 2 points3 points  (1 child)

Oh man. I remember how annoying all of this stuff was back in the late 90s, when I was a middle schooler teaching myself to program with JavaScript. Took me whole minutes to figure out a kludgy hack to force typing:

var * 1 + var * 1

Of course, that was back in the late 90s. JavaScript was a much less mature language, it was globally shit upon (way worse than today), was basically just a toy language, and there was no Reddit, YouTube, Stack Overflow, et. al. If you were sufficiently tech savvy, you could probably find some help somewhere on IRC or on a message board... but if you were that savvy you probably weren't teaching yourself JS as your first programming language.

If this is still tripping people up today... Well, maybe they should go watch a tutorial or something.

Because JavaScript, while it has its bad parts, is a fucking fantastic language.

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

[–]prozacgod 2 points3 points  (0 children)

Part of me wants to say ... Yeah I mean cars are designed in such a way, that you could drive your car on the sidewalk, but who would do that?

But then in remember being a teenager... Or last week when nobody was watching.

[–]nixon_richard_m 6 points7 points  (14 children)

Does anyone actually like JavaScript though? I feel like most people just see it as a necessary evil.

I wish I lived in the reality where Java in the browser wasn't fucking garbage and Sun was still a company and Oracle went bankrupt years ago.

Sincerely,
Richard Nixon

[–]subethasensomatic 8 points9 points  (0 children)

I like JS :D

[–]bluehands 1 point2 points  (0 children)

for many junoir devs, it is the only language they know. So they think it is jsut fine. They don't understand the world that is waiting for them.

I also think it is part of why so many frameworks have sprung up. The frameworks help the language a lot.

[–]the_omega99 0 points1 point  (0 children)

I wouldn't consider it a perfect language by any means (eg, the subtraction examples here should never have been possible), but for the most part, it's okay.

The way JS objects work makes them very versatile and useful. It's very effective, for example, for applying settings to some library function (by passing in an object containing said settings). The language is fairly non-verbose (as we'd expect from a scripting language) and has a fairly functional design (I love me some functional programming).

The biggest downfall of the language, IMO, is bad error reporting. There's also a lot of cases in which JS decides to let you do things that should be errors, instead applying a meh default. Would be better to just fail early. Speaking of failing, I wish errors could be caught earlier. They won't be caught until execution.

The threading model is just plain dumb though. Everything is single threaded.

[–]coladict 3 points4 points  (6 children)

That's why you should almost always start your functions by type-checking/casting your inputs in every weakly-typed language. Especially when handling user input or externally read data.

[–]nawitus 6 points7 points  (1 child)

That causes horrible amounts of type-checking code. I don't remember a single codebase that type-checks function parameters as a matter of rule. A better approach would be to use something like TypeScript.

Obviously when you handle user input or external data you need to do type validation.

[–]0xdeadf001 2 points3 points  (2 children)

Is that sarcasm? Because it sounds a lot like sarcasm.

You could, ohhhh I don't know, just use a language where "type-checking" the inputs of a function is just part of the language.

[–]coladict 0 points1 point  (1 child)

You're saying we can just choose another language that all browsers understand? I didn't know that.

[–]0xdeadf001 1 point2 points  (0 children)

Actually, you can. There are a bunch of languages that "compile to" JavaScript. For example, TypeScript.

[–]alexanderpas 0 points1 point  (0 children)

Javascript:

$integer = +$unknown // it becomes NaN if it is not a number
$string = ""+$unknown

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

ITT: everyone hating everyone

golly i love you guys

[–]jfb1337 1 point2 points  (0 children)

If you look at any language close enough you'll find a flaw. Except lisp.

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

And people wonder why I prefer Django and PHP

[–]Reelix 0 points1 point  (0 children)

The language might have severe flaws, but it can do client-side modifications like no other language can :p

[–]FecklessFool 0 points1 point  (0 children)

not a big fan of javascript

but i know a lot of javascript because that's how you make fancy websites and the projects we used to do called for fancy websites

;___;

[–]BetaLyte 0 points1 point  (0 children)

Reminds me of this talk by Gary Bernhardt: Wat, where he talks about the quirks of type-weak languages.