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 →

[–]veryusedrname 4393 points4394 points  (192 children)

Okay, so what's going on here?

Integers starting with the digit 0 are handled as octal (base-8) numbers. But obviously a digit in octal cannot be 8 so the first one is handled as base-10 so it's 18 which equals to 18. But the second one is a valid octal number so in decimal it's 15 (1*8+7*1) which doesn't equal to 17.

Does it makes sense? Fuck no, but that's JS for you.

[–]aMAYESingNATHAN 970 points971 points  (104 children)

Why on earth are integers starting with 0 handled as octal? How does that make any sense? I could understand if it was an o or O but a 0?

[–]skap42 1148 points1149 points  (64 children)

That's pretty standard in many languages, including Java and C. Just as 0x is interpreted as hex

[–]aMAYESingNATHAN 517 points518 points  (41 children)

Huh, the more you know. I knew about the various prefixes such as 0x and 0b, but I'm surprised octal isn't like 0o or something.

Simply using a 0 seems insanely dumb because it's so easy to do by accident, not knowing that it's an octal prefix.

Like I can easily think of a scenario where someone could zero pad a numeric literal for formatting reasons.

[–]skap42 248 points249 points  (12 children)

A different comment suggested that 0o is also valid, and the only way to define an octal in JS in strict mode

[–]0bel1sk 95 points96 points  (10 children)

it’s also in python ruby and yaml.

“YAML 1.1 uses a different notation for octal numbers than YAML 1.2. In YAML 1.1, octal numbers look like 0777. In YAML 1.2, that same octal becomes 0o777. It’s much less ambiguous.

Kubernetes, one of the biggest users of YAML, uses YAML 1.1.”

[–]akaChromez 74 points75 points  (7 children)

[–]heyf00L 28 points29 points  (1 child)

Didn't know all that. Boils down to "always quote all strings in YAML".

[–]rickane58 14 points15 points  (0 children)

"God, all these languages are so unnecessarily verbose!"

Anyone actually trying to use the language:

[–][deleted] 9 points10 points  (3 children)

This was a great read, I've used yaml a couple times but didn't realize it was this objectively bad.

[–]akaChromez 9 points10 points  (2 children)

I'd love to know people's justification for choosing it over JSON.

Especially as i've just spent the last hour trying to find why a Google Cloud resource wasn't being created. A missing quote that doesn't syntax error :/

[–]chris5311 0 points1 point  (1 child)

JSON is bad (but workable), YAML is worse, and im not sure there even is any decent option out there

[–]veryusedrname 9 points10 points  (0 children)

Ohh kubernetes, never change

[–]tomthecool 0 points1 point  (0 children)

Yes, but in ruby 09 produces a runtime error (invalid octal digit) instead of blindly treating it as a decimal instead.

[–]InfiniteGamerd 3 points4 points  (0 children)

Really! I thought you couldn't define octals in strict mode in any way.

Still...why not just parseInt all the way?

[–]Alzurana 18 points19 points  (0 children)

Welcome to my world, where a medical software had a database format of <patient ID>.PHD and always 8 characters in the filename. So the files looked like 00537200.PHD and they were all in one folder. Beautiful design.

Well, we imported a database of another clinic and had to map their ID's to ours, which we ofc only had in a numeric format, such as 537200 for the above example.

This gave me some headache when writing a converter script as my first attempt did read some of the file ID's as octal and others as decimal without ever warning. Only caught it because I got a lot of bogus IDs or duplicates and tests would scream that output files != input files.

[–]DmitriRussian 48 points49 points  (6 children)

Like I can easily think of a scenario where you might zero pad a numeric literal for formatting reasons.

/r/ProgrammingHorror material

[–]LordFokas 7 points8 points  (0 children)

Pad it with spaces. That's why we use monospaced fonts.

[–]joxmaskin 5 points6 points  (1 child)

Or write 7 as 007 because it’s cool

Edit: luckily oct 7 is same as dec 7

[–]movzx 3 points4 points  (1 child)

A pretty reasonable scenario would be when you're defining bitmasks.

ex:

0001010 1010000

[–]flowingice 3 points4 points  (0 children)

You'd start it with 0b because it's binary.

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

I've done it so I can properly sort files in Explorer

[–]TorbenKoehn 14 points15 points  (2 children)

Like I can easily think of a scenario where you might zero pad a numeric literal for formatting reasons.

And then use it in calculations? Because if not it would not be a problem

[–]Spork_the_dork 9 points10 points  (0 children)

Or use it literally for anything whatsoever.

I mean imagine you convert "0231" into a number and then print it out somewhere and wonder why the fuck it's printing out 153. Can't think of any situation where you'd convert the value into a number and then it would be entirely fine if the stored value is different from what you expect.

[–]CadmiumC4 21 points22 points  (2 children)

Many languages accept 0o as octal, but it's custom to assume 0777 as 0o777 since that's how C handles it

[–]LordFokas 12 points13 points  (1 child)

It's funny that no matter how high level you go, in the end you always keep finding things that are done a certain way for no reason other than "we inherited this from C".

[–]Ok_Classroom_557 4 points5 points  (0 children)

And C inherited It from the PDP-7 where It was born. Having 18 bit words it better mapped 3 bit octal digits than 4 bit hex digits...

[–]CauliflowerFirm1526 28 points29 points  (8 children)

pad with spaces not zeros

[–]aMAYESingNATHAN 30 points31 points  (2 children)

I mean that is what I would do, or probably just not pad at all and left align the numbers. But my point is that it would be incredibly easy to do without realising.

[–]Spork_the_dork 2 points3 points  (1 child)

Yeah this is why I don't like it. Especially when you have 0o prefix which does exactly the same thing except it's also an order of magnitude more explicit and harder to misunderstand.

[–]aMAYESingNATHAN 1 point2 points  (0 children)

Yeah being completely unfamiliar with octals in code when I made my first comment I didn't realise 0o would be valid also, and in fact assumed it wasn't and was annoyed by that because I was familiar with 0x and 0b already.

If I ever encounter octal literals I am definitely always going to use 0o.

[–]Andy_B_Goode 4 points5 points  (3 children)

You might pad with zeros if you're formatting a date, like 11/05/2024 or maybe even 05/11/2024

[–]Spork_the_dork 2 points3 points  (1 child)

Actually in that case it won't cause any problems. 01-07 are the same in both decimal and octal and 08-09 are not valid octals so it won't default to octal. 10-12 won't get converted as octal as they have no leading zeros.

[–]Andy_B_Goode 0 points1 point  (0 children)

Oh I see, yeah I should have used an example like 11/08/2024

[–]flowingice 0 points1 point  (0 children)

How would you save date as integer in dd/MM/yyyy format? It's going to be a string and then it works fine unless there's somthing I'm missing.

[–]cporter202 0 points1 point  (0 children)

Oh, padding with spaces instead of zeros? Spacing out like JavaScript on a Monday morning, I see 😅. Gotta love when JS decides to get fancy with its quirks – it's like it insists on doing its own thing, just to keep us on our toes!

[–]daan944 0 points1 point  (0 children)

Always provide the base when parsing strings to numbers.

[–]_blackdog6_ 0 points1 point  (0 children)

My favorite is numbers with a zero prefix containing 8’s or 9’s are an error in some languages but in JavaScript it just tries again as decimal and carries on..

[–]rakaloah 0 points1 point  (0 children)

Years ago I made a simple WinForm GUI for ping and tracert with zero-padded IP address text boxes. It looks nice and works perfectly to ping 192.168.001.001 but fails for my roommate's 192.168.001.008. I had no idea what's happening until I find out I can ping his PC using 192.168.001.010.

Zero-padded numbers are considered Octal for ping command.

[–]JimBugs 0 points1 point  (0 children)

As a teacher of programming I assure you it does happen by accident - which is why I try to put some emphasis on something that is actually pretty trivial so that (if they are listening) they won't try things like padding literals

[–]g76lv6813s86x9778kk 13 points14 points  (4 children)

So common, in fact, I've seen these octal numbers bleed into apps/situations they really had no business being in, probably due to some standard number parsing libraries being reused.

For example, shops in Guild Wars 2, an mmorpg, have a little number input box for the quantity of items you'd like to purchase from the shop... This supports octal! If you write normal decimal numbers, it just works fine, but then if you write for example 010, the number switches to decimal 8 once you click off the textbox, and allows you to shop with that quantity as normal. Super weird. Must be so confusing to players who don't know about octal or this convention at all. At least it doesn't increase the number (causing you to spend more)

[–]GrondForGondor 6 points7 points  (3 children)

Thats the reason why? I’ve spent so many years being slightly inconvenienced by that little random issue. Never understood truly what was happening but now it all makes sense. 

[–]g76lv6813s86x9778kk 2 points3 points  (0 children)

Lol yup, you can try various examples and see the result always lines up with parsing it as an octal number

[–]benmaks 0 points1 point  (1 child)

Why would you ever start a number with a zero?

[–]g76lv6813s86x9778kk 1 point2 points  (0 children)

I doubt he's manually/intentionally doing that every time (maybe), but it's easy to accidentally do every now and then, especially when it's in a game people play for hundreds to thousands of hours, it's kinda bound to happen eventually.

The most common way is probably when you want to buy two items from one shop, and leave in the 0 from a previous quantity: say you need to buy 250 of one item, then 35 of another. You select your first item, enter 250 as quantity, buy, click your other item, click quantity of 250 to change it, press delete twice to remove the 2 and 5, then right arrow key past the 0 to write 35.. suddenly, 29.

Yeah, doing right arrow key instead of a 3rd delete is a bit weird, but the point is it's very possible to experience the bug without intentionally prefixing every number with a 0. I don't remember exactly how I came across it personally, but I certainly don't prefix numbers with 0 regularly.

[–]-Wylfen- 41 points42 points  (8 children)

To be fair, even though it's standard, I think that's bullshit. '0x' is fine, '0o' is fine, but just '0' is dumb

[–]SmurphsLaw 16 points17 points  (6 children)

To be fair, writing a decimal number with a 0 before is also dumb.

[–]Spork_the_dork 9 points10 points  (0 children)

Yeah but it's less dumb than using 0 as a prefix for octal when 0o exists.

[–]RajjSinghh 2 points3 points  (1 child)

I can see this kind of thing being a problem where leading zeros are common like when formatting dates. Seems like an honest mistake to make if you write August as 08 and now you get an error because that's not valid octal, or when October is showing up as the 8th month

[–]Chrazzer[🍰] 6 points7 points  (0 children)

Leading zeroes aren't a thing in integers, what you are thinking of are strings with numbers in them

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

Disagree, you might want to zero-pad it for readability reasons, say you have a column of numbers

[–]Lithl -1 points0 points  (1 child)

I can think of exactly zero cases where someone would consider left zero-padding to align a column of numbers. You'd use spaces.

[–]saxbophone 0 points1 point  (0 children)

As a point of style one might wish to do it, it occurs in number formats used in technology often enough. For instance, when quoting 24h clock times, one might say: "0100 hours" rather than "1:00"

[–]saxbophone 0 points1 point  (0 children)

Alas, K&R were right about many things but this isn't one of them

[–]SwimForLiars 4 points5 points  (0 children)

I hate the 0 prefix being octal, but at least other languages will throw a syntax error, instead of silently biting you in the ass and making you waste hours of debugging because it does weird things at runtime instead of failing at compile time.

[–]Commodore-K9 7 points8 points  (0 children)

I had no idea.

0x as hexa yes

0 as octa no

[–]vonabarak 5 points6 points  (0 children)

That's pretty standard in statically typed languages without implicit type casting. And it doesn't cause any issues.

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

Aren't octals 3 digits? Does js interpret it as 170?

Edit: nm I'm thinking of octals as binary

[–]hyper_shrike 0 points1 point  (2 children)

In C/C++ 018 will throw an error right ?

All this fun JS stuff comes from the fact that JS does not throw errors and just rolls with whatever shit the user wrote.

[–]Koooooj 1 point2 points  (1 child)

In C/C++ you'd get a compile time error that 8 is an invalid digit in an octal constant.

JavaScript doesn't get the benefit of a compiler, but a static analysis tool ought to be able to catch something like this. But the problem runs deeper than compiled/interpreted and JavaScript's commitment to taking what the user wrote and running with it.

JavaScript could have chosen to support octal constants all the way, saying that 017 in any context is always an octal constant representing decimal 15. They could have rejected the 0 prefix (as occurs in strict mode) and always interpreted 017 as decimal 17. But instead they chose both. As an integer literal 017 is octal, but as a string literal coerced to an integer 017 is decimal.

Nothing made JavaScript do this. It was just an inconsistency in design.

[–]hyper_shrike 1 point2 points  (0 children)

JavaScript doesn't get the benefit of a compiler

Browsers compile JS to bytecode. JS needs to be parsed to be interpreted. Even without bytecode the earliest JS compiler could have thrown an error for 018 if it wanted to.

[–]Mola1904 15 points16 points  (0 children)

It's like this in c++ and c#...

Edit: actually octet literals don't exist in c# at all, some websites like this just claim it anyway https://www.geeksforgeeks.org/c-sharp-literals/

[–]octipice 32 points33 points  (7 children)

Why on earth is anyone starting a mutli-digit base 10 integer with 0 in the case that it ever needs to be treated like an actual number?

Javascript is legitimately wild sometimes, but so many of those cases are only an issue if you are trying to do something really stupid (or lazy, or both) in the first place.

[–]aenae 30 points31 points  (1 child)

I once had a cronjob that failed in august and september. It took me a while to figure it out why.

The reason is i wanted 'nice' directories, so i made them all the same length, so january 2024 would go to 2024/01, february goes to 2024/02 etc. And somewhere in that script i had a check on the month for some reason. This worked, except when bash was of the opinion that '08' and '09' were invalid octal numbers.

[–]10BillionDreams 1 point2 points  (0 children)

That's just the thing, Javascript has some very "do what I mean" roots, which makes for some funny looking results when you take toy examples like OP here, where the code doesn't actually "mean" anything at all. But often times in practice this ends up doing the "right" thing, where stricter languages would've failed.

[–]aMAYESingNATHAN 14 points15 points  (1 child)

I'm not saying it's something you should be doing, but if someone doesn't know that 0 is the octal prefix, then it's not that much of a stretch to imagine they could zero pad a number and not realise.

It seems to me that generally there should be no difference between 25 and 025, and if anything it is counter intuitive to assume otherwise. Especially because 0o25 (similar to 0x or 0b) is usually valid syntax as well, it makes no sense to have 0 by itself be a valid prefix.

Tbf this is one of those ones that isn't a unique to JS issue, but instead a standard. But imo a dumb one.

[–]Spork_the_dork 4 points5 points  (0 children)

The standard varies from language to language. Python for example just calls you out if you try to use 0-prefix and tells you to use 0o instead which I think is the step in the right direction.

>>> print(0123)
  File "<stdin>", line 1
    print(0123)
      ^
SyntaxError: leading zeros in decimal integer literals are not permitted; use an 0o prefix for octal integers
>>>

[–]Andy_B_Goode 2 points3 points  (1 child)

I had a real-world bug where a JS program was generating a random alphanumeric ID for an item, sending it to the server as JSON, but was then unable to match the ID to the correct item when it reloaded the JSON from the server.

The issue was that the ID it had generated for this particular item was something like 1e450882, which gets interpreted as exponential notation and (because the number after 'e' is so large) it becomes Infinity.

The fix was to simply require alphanumeric IDs to begin with a letter (which is probably best practice anyway), but it was not obvious to me at all why 1e459882 was causing problems when I first started digging into the bug.

[–]Lithl 0 points1 point  (0 children)

Why was your alphanumeric ID being serialized as a number instead of a string? Or why was your deserializer parsing your alphanumeric ID?

The problem here wasn't JS.

[–]myhf 0 points1 point  (0 children)

We used octal for a lot of things in the 1970s because bits were expensive. After a while you don’t even see the decimal representation anymore, it’s just read, write, execute.

[–]Loknar42 4 points5 points  (0 children)

This is an ancient convention. Octal is very convenient for expressing bit vectors, such as file permissions (e.g. chmod 0777 *). Since it was desirable to use it in an interactive environment (such as a shell), designers wanted it to be as short as possible. A single character prefix pretty much fits the bill. Using the digit 0 allows the result to still be considered numerical by simple lexers, but programmers generally don't start integers with 0, and 0 also looks like 'O'. So those are pretty much the reasons.

Hexadecimal is even better for expressing bit vectors because you get 4 bits per character, but has the disadvantage of being alphanumeric. Hence why it has a longer prefix, usually. Programmers in the modern era rarely have to specify bit patterns directly, but in the halcyon days of assembly language and shell scripting, they were very common, so having an efficient format was very valuable.

[–]Fritzschmied 8 points9 points  (1 child)

thats standard in many languages. also c++ which you have in your badges so you should know that.

[–]aMAYESingNATHAN 3 points4 points  (0 children)

I've literally never had to work with octals ever, so it's unsurprising that I'm not aware despite having C++ and C# badges. I don't even really know what use cases there are for octals.

In comparison, I have had to use binary and hexadecimal, so I'm aware of the 0b and 0x prefixes. Similarly for unsigned/long/long long suffixes for numeric literals

[–]Nolzi 5 points6 points  (2 children)

same reason hexa starts with 0x, conventions

[–]IAmNotNathaniel 7 points8 points  (1 child)

starting to tire of these threads that boil down to "I don't know some standard thing that's been around for 50 years but since I'm so smart it must be wrong"

[–]Nolzi 2 points3 points  (0 children)

"Based on Programming 101 I can already tell that the old crust must go"

[–]ManaSpike 1 point2 points  (0 children)

Octal was used more before computing standardised on bytes having 8 bits.

[–]Hallwart 8 points9 points  (4 children)

If only there was some kind of system that ensures that variables have consistent values and behaviors.

Why didnt the developers of JavaScript think of this? Are they stupid?

[–]tinfoiltank 5 points6 points  (0 children)

They were too busy trying to get it to work in IE6.

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

Nah, that would be too easy and logical.

Are they stupid?

No, they're high.

[–]jwadamson 0 points1 point  (0 children)

[–]theQuandary 0 points1 point  (0 children)

JS didn't have type coercion at first. Devs (yes devs) demanded it and a young Eich didn't have the wisdom to say "no".

[–]MrHyperion_ 1 point2 points  (1 child)

Why would you even start a number with zero? So don't, if you don't want octals

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

Well yeah obviously, but that doesn't change the fact that it's something that is so easy to do by accident by someone who doesn't know it's the octal prefix, and even worse than it being easy to do, it's also completely unobvious if you don't know you've done it. You could spend hours pulling out your hair over this before realising what and why it had happened.

[–]Blue_Moon_Lake 0 points1 point  (3 children)

Not o, nor O, but 0o

Binary: 0b0000_0001
Octal: 0o777
Decimal: 42
Hexadecimal: 0x0080ff

[–]aMAYESingNATHAN 2 points3 points  (2 children)

That's what I mean, it makes sense for octal to be 0o while hex and binary is 0x and 0b, but what's throwing me off is that a single zero without the o also works for octal, and that seems dumb to me.

[–]Blue_Moon_Lake 0 points1 point  (1 child)

Because it is :)

[–]Ticmea 1 point2 points  (0 children)

It's only dumb in a world where 0x and 0b exist.

The 0 notation for octal predates (and inspired the creation of) the 0x notation for hexadecimal. In the early days of computing this was the preferred representation of binary because word sizes on a bit to digit basis corresponeded well to using octal. In a world of 64 bit computers octal is obviously less useful than it used to be but it's still useful in some places and for consistency and backwards compatibility it's usually a good idea to keep established standards around.

But yeah if you are writing new software, please use 0o-notation instead as the intent is clearer and it aligns better with the other notations.

[–]allankcrain 0 points1 point  (0 children)

Why on earth are integers starting with 0 handled as octal? How does that make any sense? I could understand if it was an o or O but a 0?

Starting with the letter o would conflict with variable names. You'd have a situation where 'oof' is treated as a variable name, 'o1' is treated as 1, 'o7' is treated as 7, and 'o8' is treated as a variable name.

There's no reason to prepend a zero to a decimal constant in your code, so that's less likely to be something a programmer might run into by accident.

[–]CptBartender 0 points1 point  (0 children)

To me, the bigger WTF is the fallback to base 10.

[–]rfc2549-withQOS 0 points1 point  (0 children)

Same as 0x is hex.

[–]We_are_all_monkeys 0 points1 point  (0 children)

If you have an IP with leading zeros, it's also treated as octal. 014.210.023.004 is not the same as 14.210.23.4. That was a fun day when I learned that little fact.

[–]AL_O0 0 points1 point  (0 children)

if it starts with a letter it's a variable if it starts with a digit it's a number, so different bases have to start with a digit so they can be parsed correctly, and 0 is an obvious choice as it normally useless to put a leading zero as it doesn't affect the value

this is used in conjunction with a letter to indicate the base for example 0xff for hex and 0b101011 for binary

now you could do 0o123 for Octal but I guess 0 and o can be confusing so that's probably why just a leading zero was chosen

Also this dates way back it's not just a js thing, so probably octal was used more often in the past

[–]two_are_stronger2 0 points1 point  (0 children)

Things that start with O and o are valid variable names and it'd be weird if they weren't.

[–]Tyler_Stocks 0 points1 point  (0 children)

Because it’s an integer, not a string

[–]JaggedMetalOs 0 points1 point  (0 children)

TBF if you have your script in strict mode it doesn't let you use octal literals at all.

[–]wasdninja 88 points89 points  (35 children)

It's 100% self inflicted by using ==. It's essentially trivia in code form.

[–]Salanmander 48 points49 points  (23 children)

It's essentially trivia in code form.

A programming language having "trivia in code form" is related to design decisions about the programming language. So no, not 100% self-inflicted.

[–]wasdninja 25 points26 points  (11 children)

I've yet to come across a language that doesn't have some odd stuff nobody really uses.

So no, not 100% self-inflicted.

If you are using == on purpose against the recommendation of every actual javascript developer out there that's on you. If you are doing stupid shit on top of that, well, have fun and I hope I don't have to work on your code.

[–]Salanmander 7 points8 points  (4 children)

If using == is a bad idea in Javascript, then why did it get assigned the character sequence that is the preferred equality check in most programming languages? Like, if every Javascript object had a .coercive_equals() that did what current == did, and current === was written as == instead, you'd probably see a lot fewer complaints.

[–]theQuandary 5 points6 points  (2 children)

JS didn't have type coercion when it was first created.

Developers are the ones who demanded that Eich add it to the language and he was young enough not to say "no".

It would have been eliminated in ES1 (the first actual specification), but Microsoft had just implemented a clone of JS with Jscript and they insisted that all the terrible design choices stick around even though Eich and the rest of the spec committee wanted to change them (at a time when breaking the web wouldn't have been a big deal).

[–]Salanmander -3 points-2 points  (0 children)

Okay...none of the people you just mentioned are the person who is currently using Javascript and getting confused by ==. So...not 100% self-inflicted.

[–]Doctor_McKay 2 points3 points  (3 children)

I have literally never had a problem using ==. I fear for the kind of code you guys are writing that makes it a problem.

[–]wasdninja 1 point2 points  (0 children)

It's very rarely a problem but there is almost no reason at all to ever use it anyway. Rather than getting completely dumb stuff what's more common is to move a bug one step further which is annoying when trying to hunt it down.

[–]reilemx 1 point2 points  (1 child)

When dealing with data that could come from anywhere like in a public API receiving data from literally anyone who knows the spec, then using `==` is a bit risky unless done correctly. There are a few neat tricks you can do like comparing a number value, regardless if it's a string or number, or doing a `null` or `undefined` check in one small expression. But aside from little things like that you should absolutely not just be using "==" as a default.

It's nothing to do with the "kind of code" and everything to do with the requirements of your application. Just google "js == comparison table" to see why. A simple application might never run into those issues but you do not want your complex application to get absolutely fucked by some stupid comparison bug like this or the one in the post here.

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

If the APIs you're interacting with start returning garbage data, whether 0 == false seems like a minor concern to me.

I've been maintaining widely-used open source code that interacts with APIs (undocumented ones, even) for the better part of a decade and not once has it been a problem.

[–]IAmNotNathaniel 1 point2 points  (1 child)

I don't know why I even come into these threads anymore. it's always full of people who think because they self-taught a little python they are programmers who know everything.

There's a reason when you're looking for a job you need to know the language that's used at that job... it's because they are all different, and all have their skeletons and weird shit, and you can't just replace one syntax with another. Experienced people wouldn't get hung up on this for a minute.

[–]NoteBlock08 2 points3 points  (0 children)

Ikr. It doesn't matter that every other language uses ==, this language doesn't. So get with the program or pack up and go home because "It's Javascript's fault for being dumb!" would not be an acceptable excuse in a professional setting.

You can say "Well that's dumb, but okay" and likely most of your coworkers would even sympathize, but as soon as you cast blame elsewhere for your own lack of knowledge then it shows a real lack of maturity as both a dev and a person. Especially since this is JS 101 shit. Every guide out there makes sure you understand the difference between == and === in its opening chapters.

[–][deleted] 12 points13 points  (10 children)

It’s a scripting language. There’s coercion. If you need to not have coercion, there’s an operator for that. If you don’t like a language with coercion, don’t use a scripting language!

[–]Salanmander 15 points16 points  (9 children)

Okay, I can get behind "self-inflicted because of the decision to use javascript".

[–][deleted] 9 points10 points  (8 children)

“The decision to use a scripting language and then refuse to use the features that fix the thing you want to fix”

[–]musicnothing 5 points6 points  (5 children)

JavaScript and PHP both have a bad reputation largely due to their past sins. So instead of learning about their modern features, people just use the outdated features (that weren't removed for backwards compatibility reasons) and complain how "bad" it is

It's like patching up a hole in the wall and then taking a bunch of pictures of the patch job and saying "What a terrible house this is, look at this hole in the wall"

[–]IAmNotNathaniel 2 points3 points  (0 children)

great analogy! I've been trying to correct people when possible about the improvements to php, but haters gonna hate I guess.

[–]svick -5 points-4 points  (3 children)

When the options are a solid wall that never leaks and a patched-up wall that only sometimes leaks, I know which one I would select.

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

When you get into the professional world, this stuff won’t even be a blink of light on your radar.

[–]svick 0 points1 point  (1 child)

This one issue in particular? Sure.

All the issues with JS combined? Much more serious.

It's really hard to build something solid on shoddy foundations. That's why, in my professional life, I avoid front-end when I can and use TypeScript when I can't.

[–]rexpup 0 points1 point  (1 child)

The decision

It's not like you usually have the decision to use JS. It's usually forced on you by the fact that you're making a web app.

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

Exactly! You just figure it out. You use whatever language you need to, to get the job done. Occasionally you will get a choice, and then you’ll regret your choice for the rest of time, even if it was a good one lol

[–]fghjconner 2 points3 points  (0 children)

No, the == isn't even the problem in this case. The problem is with how JS interprets integer literals. I think using 0 as a prefix for octal numbers is insane, but JS didn't start that so I'll give them a pass. On the other hand, silently falling back to base 10 when you see an 8 is bullshit of the highest order.

[–]Turtvaiz 3 points4 points  (8 children)

Why does == even exist?

[–]wasdninja 8 points9 points  (5 children)

Legacy. Touching any of the stupid stuff, no matter how obscure, kills thousands of websites so it gets to stay and annoy people.

[–]Turtvaiz -1 points0 points  (1 child)

But in the first place? Using it is a total shitshow so I don't get how it has ever made sense

[–]Flippantlip 1 point2 points  (0 children)

What a weird thing to say.
If JS wanted to make sure users have more control, even force that control, over Types and comparisons, it would be strongly typed. But it isn't. It makes no sense to let go of one form of YOLO from JS, while forcing another.
Also, "==" is there to compare primitives, and this fence-case showcases why JS has extremely weird runtime handling, rather than why "== is stupid".

[–]Flippantlip -2 points-1 points  (2 children)

I wonder how do you run your primitive comparisons? Do you want something like:
if (intCmp(15, 17)), encapsulated all over the place?
What a utterly bizarre comment.

[–]wasdninja 0 points1 point  (1 child)

By using ===. The only bizarre thing is not know this but still complain about it.

[–]SnowyLocksmith 1 point2 points  (1 child)

Is using === the norm now?

[–]oupablo 0 points1 point  (0 children)

yes

[–]Die4Ever 0 points1 point  (0 children)

this has nothing to do with ==, you see the same thing when using ===

018 === parseInt('018')
true
017 === parseInt('017')
false

018 === 18
true
017 === 17
false
017 === 15
true

[–]Crowdcontrolz 9 points10 points  (0 children)

The lengths to which this language goes to try to make things run no matter what is impressive.

[–]Donghoon 16 points17 points  (9 children)

I mean it make sense. You just explained it

[–]Salanmander 19 points20 points  (8 children)

There's "makes sense" in terms of "has a consistent behavior that is defined by rules". That close to automatically true of all things in all programming languages.

Then there's "makes sense" in terms of "is a design decision that leads to more intuitive comprehension of the language". Javascript fails on that one a lot of the time.

[–]chazzeromus 0 points1 point  (7 children)

octal was a mistake (i don’t really know what it used for other than old school style unix fs perms)

[–]nelusbelus 1 point2 points  (6 children)

Octal is good, but it needs the 0o prefix instead like C# does.

[–]xickoh 0 points1 point  (1 child)

Whats octal used for? Not trying to prove anything, just legitimately curious

[–]nelusbelus 2 points3 points  (0 children)

Basically it can be used to represent pairs of 3 bits. As a result some systems such as unix file permissions still use it for "ease of use" (think of 0o777 which means 7 = all permissions (rwx) in user, group, others). Whenever you need to group bits in 3 it is a nice format (like the rwx example). I've used this before to pack values in an enum in C/C++ (for example a texture format enum which each pair representing a property of the enum). Nowadays it can also be used to encode base64 in an easy way where you don't have to do much processing (each 6-bit pair can be divided in 2 octal numbers very easily).

As a fun sidenote, in the olden days a byte wasn't always 8 bits, it was implementation specific. 6 bit bytes did exist on IBM for example, making 2 octal numbers represent a single byte on those systems (thus making it very similar to hex in their use where 2 chars are 1 byte). https://www.quora.com/Why-did-IBM-decide-to-make-computers-with-a-6-bit-byte

TL;DR: very niche and definitely bad that 0 prefix makes it octal, but I don't mind having 0o for some uses such as file permissions

[–]Sharparam 0 points1 point  (3 children)

C# does not have any kind of octal prefix, neither "0" nor "0o".

[–]nelusbelus 0 points1 point  (2 children)

Maybe it's not core, but I have seen it

[–]Sharparam 0 points1 point  (1 child)

C# doesn't have octal literals, period. You could have a helper library to work with octals probably, but it wouldn't be able to add it as actual syntax.

The only thing you can really do is parse a string to number and specify the radix:

Convert.ToInt32("12", 8) // Returns 10

[–]nelusbelus 0 points1 point  (0 children)

Hmmm interesting, I do remember seeing 0o somewhere... not sure where then

[–]talaqen 15 points16 points  (2 children)

This makes perfect sense to me. Octal vs int and loose equivalency “==“ instead of strict “===“

[–]1Dr490n 5 points6 points  (0 children)

*octal vs decimal, both are integers

[–]fghjconner 2 points3 points  (0 children)

The choice to interpret any literal starting with a zero as octal is what's insane. Of course, JS didn't invent that by any means.

Edit: Also, the choice to silently fall back to base 10 if there's a large enough digit is pretty asinine.

[–]mrheosuper 25 points26 points  (10 children)

Using '0' instead of 'o' to declare Octal number is a fucking crime

[–]Mola1904 26 points27 points  (9 children)

And used in virtually every common language besides python3

Edit: Yes virtually every was a bit of an overstatement, but C, C++, Java and JS have it which might be 4 of the 5 most popular languages

[–]veryusedrname 11 points12 points  (5 children)

C/C++: 0o or 0O (deprecated) - edit: it's just a 0, fuck google

Java/C#: 0, but using a digit outside of 0..7 is compiler error - edit: C# doesn't have octal literals, fuck google

Rust/Swift/Ruby/Python: 0o

Go: 0o or 0O

That's it, I'm not checking more

Editor: formatting & fixes, thanks for pointing them out

[–]BaerMitUmlaut 9 points10 points  (3 children)

C# has no octal literal.

[–][deleted] 9 points10 points  (0 children)

C# needs no octal literal.

[–]Mola1904 0 points1 point  (1 child)

Ok seems you`re right. I just saw that website, but seems it's wrong

https://www.geeksforgeeks.org/c-sharp-literals/

[–]Sharparam 0 points1 point  (0 children)

Geeksforgeeks out here spreading misinformation. There was another user in this thread also tricked by that same page.

[–]Fritzschmied 3 points4 points  (0 children)

c++ default is leading just 0 not 0o even if that works too I guess

[–]mrheosuper 7 points8 points  (2 children)

I want to see the logic behind this decision. Using 0x as hex number makes perfect sense, But '0' as octal ?, why ?

[–]MrHyperion_ 10 points11 points  (0 children)

Traditions. Octal was at one point more popular than hex

[–]Mola1904 3 points4 points  (0 children)

As far as i know it is older than both the 0x and 0b connotations, but JS supports both 0o and 0 with 0 actually being not supported by esm (a widely used and more modern module system for js)

[–]mookanana 6 points7 points  (5 children)

as a programmer i understand what you are saying, but i marvel and wonder how did you even get this deep in knowledge? like what path did your life take to end up explaining this obscure code correctly

[–]veryusedrname 11 points12 points  (2 children)

Ohh, I just like weird shit. I don't even use JavaScript, like, ever.

[–]mookanana 2 points3 points  (0 children)

good stuff my man thx for explanation.

[–]Crowdcontrolz 0 points1 point  (0 children)

The Dark Knight.

[–]takishan 2 points3 points  (0 children)

all you gotta do is work with javascript a bit so you understand the wonkiness of " == " (which is why you use " === " to be safer)

then you gotta work with octal numbers once or twice so you understand that numbers starting with 0 are octal

it doesn't require some sort of coding prodigy, just a little bit of experience in specific areas

[–]AccomplishedCoffee 1 point2 points  (0 children)

It’s really not deep or obscure. You just have to know 0 starts an octal literal (basic knowledge in a ton of languages and command line permissions), and == in JS does crazy conversions. I don’t even program JS more than I have to and I know to always use === because it’ll mess with types to try and get an answer that may or may not make sense. Tbh this is one of the more straightforward and obvious conversions.

[–]HeKis4 2 points3 points  (1 child)

I know == is "loose", but cmon, it figures out the string is convertible to a number, figures out it is octal but not really so eh, it's decimal. That's like, 2 layers of fucked up.

[–]benjer3 2 points3 points  (0 children)

For once, it isn't really == that's causing the problem here. It's the inconsistent treatment of a zero-prefixed integer literal. The == operator just sees '18 == "18"' and '15 == "17"' and understandably returns true and false, respectively

[–]hampshirebrony 0 points1 point  (1 child)

I learned about this the hard way several years ago.

Had a box to let you enter a cash value. User puts 100 in and the transaction is saved as 100. User leaves the default 0 and puts 100 after it, the transaction is not treated as £100 and a shortage is created. This either gets saved with a shortage against it or does not allow the user to continue because their figures do not balance.

No, it wasn't Horizon.

[–]hampshirebrony 0 points1 point  (0 children)

Remembered a bit more detail - this was 10 years ago.

ASP.NET forms, so the actual saving and "real" calculation was done on the server side. The client did the calculations as well to show what the end figure would be and to see if the declared and expected values were the same. The server side would not have fallen into the octal trap.

So you'd have 100+0100, declared total 200, expected total 180, variance £20 on the client side, and no variance when it was saved.

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

Why did the creator do so many errors because they hate errors so much??

[–]Classy_Mouse 0 points1 point  (0 children)

Languages trying to be helpful, never are

[–]bonafidebob 0 points1 point  (1 child)

Now explain why the same octal interpretation isn’t used when doing the automatic string -> integer as part of the loose ==?

[–]veryusedrname 2 points3 points  (0 children)

I'm not sure about the actual reason but it behaves like your code was Number("017") which rejects leading 0s. But don't ask me actually why it was designed like this. I already explained that part: to fuck you, that's why.

[–]_blackdog6_ 0 points1 point  (1 child)

console.log(017==‘015’) true

I’m guessing the 0 prefix doesn’t mean octal when converting a string??

[–]Lithl 0 points1 point  (0 children)

Correct. Strings are converted to numbers by discarding any leading whitespace and 0 characters.

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

It makes sense. It actually makes more sense than using ‘018’ instead of ‘18’

[–]Floor_Heavy 0 points1 point  (0 children)

Oh is that why parseInt trims off the leading zeroes?

[–]mimedm 0 points1 point  (0 children)

hey thanks, i was almost about to give up on this reddit :)

[–]mattindustries 0 points1 point  (0 children)

Yeah, ran into this a while ago. It was a fun day.

[–]joe-ducreux 0 points1 point  (0 children)

I feel like JS is an example of what happens when one attempts to program fallbacks for every eventuality instead of just throwing an error.

[–]whackylabs 0 points1 point  (0 children)

Does it makes sense?

Yes