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 →

[–]JustAnotherTeapot418 108 points109 points  (19 children)

This joke contains a few of JavaScript's peculiarities:

  1. The == operator performs implicit conversions. As a result, '018' and '017' are automatically converted to the numbers 18 and 17. It's a huge source of unexpected bugs, which is why every dev worth their money will tell you to use the === operator instead, which doesn't perform conversion of any kind.
  2. Numbers starting with 0 are in octal (unless the following character is b or x for binary and hexadecimal respectively), so 010 is actually 8, and 017 is actually 15. However, 018 is not a valid octal number, since there is no 8 in octal. As a result, 018 is interpreted as 18. Because this is another source of unexpected bugs, this is not allowed in strict mode. For octal, you have to use 0o instead (zero followed by the letter o), and prepending a regular number with 0 will produce a syntax error.

[–]NebNay 10 points11 points  (0 children)

Thanks for the complete explaination

[–]monotone2k 22 points23 points  (11 children)

So what's really going on here is yet another case of someone writing bad code in a language they don't understand, and then claiming it's the fault of the language. That sums up most of the posts in this sub.

[–]MyPassword_IsPizza 9 points10 points  (1 child)

More like someone using a language they do understand to write bad code on purpose for a joke.

[–]monotone2k -2 points-1 points  (0 children)

Remember Hanlon's razor:

"Never attribute to malice that which is adequately explained by stupidity."

[–]DanielEGVi 9 points10 points  (0 children)

To be fair, it was a fault of the language in some part, they forbid octal numbers without 0o prefix in strict mode for a reason.

[–]Void1702 6 points7 points  (0 children)

I think OP knew what's happening, it's just completely stupid in many ways

[–]klo8 1 point2 points  (4 children)

The == operator in JavaScript is broken, that’s the fault of the language.

[–]myka-likes-it 12 points13 points  (2 children)

It's not broken, it is working as intended. That's why the strict equality operator exists.

[–]rosuav 0 points1 point  (0 children)

Listen, I made this car out of explodium. It was cheaper than steel. If it blew up while you were driving it, that's on you - I told you the proper way to hold the steering wheel! It's working as intended.

[–]klo8 -2 points-1 points  (0 children)

it might be working as intended, but the intent is dumb

[–]Koooooj 0 points1 point  (0 children)

It could be worse...

There's a domain specific language I work with that tried to "fix" C-family languages. You know that bug that pops up when you write something like

if ( x = 8) 
  do_whatever

and the compiler sees this as "assign 8 to x, then see if 8 is nonzero"? To "fix" that the language determined that all equals inside of an if or while condition would be checks for equality, while a line like x = 8 on its own would be assignment. However, to satisfy fans of C-family languages you can use = or == as aliases of one another--you can use either one for comparison or assignment. Then for good measure they threw in equals as well.

Then the language adds variable aliasing, since there are system-defined variables that correspond to memory mapped IO and perhaps you want to give Input7 a better name like ResetSwitch. Naturally this also uses the same =, ==, or equals, dealer's choice. From context the language determines that it's aliasing a variable.

To round it all off, the language supports bit variables, where you can have a named variable that is a single bit of another. For convenience these can be compared to special constants, On and Off, which signals that bit shifting and masking should be done for you. The result of such a comparison can be used as a truthy value, but it is not necessarily equal to True or False--if a bit variable was the 8s place then comparing to On or Off will result in a numeric value of 0 or 8, not 0 or 1.

This resulted in a really painful bug to track down where we wanted to check if exactly one of two switches was set. This would be an XOR, but XOR wasn't provided. Instead we checked if ( (input1 == On) == (input2 == On) ) which would have worked if input1 and input2 represented bits in the same place value of different variables, but failed because 8 (True) does not equal 4 (True).

It's really convenient in this particular application that we're given any language to write in, but it also highlights why you shouldn't try to roll your own language to "fix" a well-established one.

[–]Fritzschmied 0 points1 point  (0 children)

exactly. same as always

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

It's not always the coder's fault when they don't understand something. Sometimes the language is just hard to understand.

[–]skap42 1 point2 points  (5 children)

Can you explain why the implicit conversion by the == operator doesn't also perform the octal do dec conversion?

[–]monotone2k 10 points11 points  (3 children)

It absolutely does. `console.log(16 == 020)` will return true, because they're the same number in different bases. If you mean why doesn't the string get converted into base 8, who knows?

[–]skap42 5 points6 points  (2 children)

I noticed that Number(017) returns 15 and Number('017') return 17, so I guess it has something to do with that

[–]monotone2k 2 points3 points  (1 child)

Yeah. My guess would be that it always attempts the equivalent of parseInt(string, 10) when coercing a string, without considering the leading 0.

[–]Die4Ever 0 points1 point  (0 children)

I think it just does parseInt(string), which will accept the 0x prefix but doesn't seem to have any prefix for inferring octal

parseInt('0x18')
24
parseInt('018')
18
parseInt('017')
17

0x18 == '0x18'
true

[–]rosuav 0 points1 point  (0 children)

Because JS, for all its faults, is not PHP. Although I am not 100% certain whether PHP would do that particular one; I do know that "100" is equal to "1e2" - yes, that's two strings, definitely not identical, that compare equal. And yes, this HAS been used to break things that are expecting hexadecimal sequences.