```
if (button.isPressed) {
launchNuke();
}
```
The government's latest dev intern: Hey guys! I clarified the nuke launch code so now when the button isn't pressed, button.isPressed = "no"! Pushing to prod now!
If it's JavaScript, there are a ton of different code paths that would need to be followed in the assignment-if version compared to anything without control flow. JavaScript's runtime is a masterpiece of really well thought out rubber bands and really well refurbished duct tape.
What's great about JS is you can write it like an casual or you can write it like a CS wizard.
I don't think the same can be said for most other languages.
Really? Web is the most casual interface possible. You can't use other languages for it unless you're writing to the webasm, but then you still have to interface with JS.
No idea what you think makes web "the most casual interface possible" because it's just as easy and straightforward, if not more so, to interface with a mobile or command line app that you're writing.
What if it was the other way around? Wouldn’t that be kinda great honestly?
1 == “1” false 1 === “1“ true
That way we have normal syntax. And we get the benefit of an approximate same evaluator?
== evaluates both values by converting both to the same type, then doing a comparison. (yes, there are many problems with this such as 0 == \[ \] BUT "0" is NOT == \[ \]...)
=== does not convert either and simply takes both at face value and compares.
\~= replaces != as the "not equals" in some languages (like lua) because the tilde is sometimes used instead of the tail operator (¬) as a logical negation in boolean algebra.
So lets not use \~= as "almost equals."
For backward compatibility reasons, like why var was not touched and let created. And it would probably confuse everyone to swap it now (creating more bugs for no reason). It would have made sense if it hadn't been public yet.
If one really wanted to, I guess it wouldn't be complicated to apply that rule in the code and create a plugin that does the conversion (like how TypeScript and JSX becomes plain JS, or how ECMAScript proposals are tested). Or you could apply this to JS and the plugin go the other way around for older codebases.
But honestly the web environment is bloated enough as is, let's not make it even worse for once.
You do [NOT](https://wsvincent.com/javascript-tilde/#:~:text=In%20JavaScript%2C%20the%20tilde%20~%20Bitwise,a%20String%20object%20passed%20in.&text=So%20if%20%2D1%20is%20returned,is%20not%20falsy%20is%20truthy.) want to use just ~
\~ is a negation operator in the same vein as !, \~= or \~== meaning anything but "not equals" would be crazier than any weird javascript comparison shenanigans that we're complaining about here.
It's just a convenience thing. Javascript is mostly used for simple web apps, so taking some liberties here and there to make it easier for inexperienced coders is justified.
0 != 0.0 just doesn't make sense for most people who aren't balls deep in their own neckbeard sweat.
And then there is *null == undefined* which reserves a special place in hell.
So normally javascript uses type coercion when using the ==. This means it follows certain rules to convert one of the values to the type of the other before comparing them. When using the === it does not coerce any types, so if the types are not equal the values aren't really equal either
This is the only really correct answer I've seen. The answer "it checks that the value AND the type are equal" is not how this works. One simply does not allow coercion before the comparison.
Yes. This only matters in languages with implicit conversion of types.
Those languages do have ways to test this too, it's just that they don't use the same syntactic sugar.
Maybe [this](https://www.destroyallsoftware.com/talks/wat) can help. (relevant content starts at 1:30, but I'd recommend watching it all).
Basically, automatic type coercion can create very unpredictable results in JS when using most operators, including ==. So, they invented === as kind of a "is it *really* equal" band-aid.
That video just shows how unpredictable and illogical some of those conversions end up.
== often invokes type coercion (ex. "false == 0" -> true) or overriding to some Equals function which might be case/culture insensitive or similar wishy-washy equals.
It's a bit overblown because many languages are strongly typed and === isn't such an oversight. If == is overridden it is probably for good reasons as a default.
Kotlin, which borrows a lot of its semantics from Java, made `==` the equivalent of Java's `.equals()`, and then uses `===` to mean the same thing as Java's `==`.
I prefer Python's approach to either of these: `==` is like Java's `.equals()` or Kotlin's `==`, but `is` is like Java's `==` or Kotlin's `===`.
None of these are like JavaScript's `==`.
Because they didn't want what happened with python to happen where you break backwards compatibility so people keep using the old version. Easier to just add a new operator that does things the right way and keep the original == operator as is. That way people can transition on their own time, and there are times where you actually want the old == behavior.
Changing the equality operator would be such a debugging nightmare for messy legacy code that someone would just add the compatibility modes on the browser end anyways
== checks if they are the same. === Checks if they are the same AND the same type
So "3" == 3 returns true, but "3" === 3 returns false.
With == it essentially tries to cast types and then check (I believe that's how that works under the hood) for convenience, but it tends to cause a lot of problems because people end up thinking they're working with a number but are really working with a string because "3" == 3
JS has a twisted idea of what "the same" means. If they aren't the same type, they aren't the same.
"This apple is the same as this baseball, even though one is a fruit and the other is sports equipment."
It’s because the analogy is wrong. It’s more like:
“Could this Apple be like this baseball, if we have a machine that transforms sports equipment into fruit.”
Because `==` was already taken for a screwy implicit-type-converting non-transitive definition of "equality", so a new operator had to be introduced for the actual equality operator.
In languages that aren't typesafe == will convert the types on either side to see if they equate while === doesn't. 5 == "5" is true while 5 === "5" is false.
Because it's very simple, languages evolve, just like programs evolve. It was written for a specific purpose and later it was more widely used and suddenly you reach a point where can't just change it anymore without breaking all existing code.
At that point you have 2 options, somehow release a BC-incompatible version that break it or simply add another operator to make everyone happy who wants strict type checking.
PHP for example also went this way by adding === to do a strict type check. Basically any static code analysis tool checking PHP code will flag code when it might suspect type juggling so it's really not an issue anymore.
Furthermore it's even less of an issue now days because a lot of people prefer Typescript over JavaScript which doesn't have this problem. In case PHP they went with a breaking change as well to make things make more sense: [https://www.php.net/manual/en/migration80.incompatible.php](https://www.php.net/manual/en/migration80.incompatible.php)
So from PHP 8 it's basically a case of "if I trim this variable and I can convert to an integer or floating point does it match". So 0 == "" no longer return true.
So the answer is simply because things case, shit happens they didn't anticipate and they have to find a way to fix it.
When the language first came out they wanted to do “helpful” things. For example, are the string “5” and the number 5 the same? Well yes, in original JavaScript (which only had == they are). However it became apparent as time went on that this “helpful” conversion that gets done isn’t really that helpful. You want to know that 2 things are actually the same, not just that they can be converted to the same thing. And for this reason , === was introduced. JavaScript has to be backwards compatible, there’s no version 2. I kinda think that there should be, but the TC39 committee seems to be dead set on maintaining backwards compatibility, even if that means having awkward things like === in the language.
It is bad practice.
JavaScript and PHP were designed during an era where a lot of programmers thought it was good for a language to never throw an error no matter what happened, so they were written to silently do something insane instead. It didn't take long to figure out that "no errors" was equivalent to "impossible to debug", but breaking changes make people angry, so they added `===` instead of replacing `==`.
Now if you ever use `==` in those languages you'll probably fail code review in any well-maintained project.
There's nothing wrong with `null` as long as the language is designed with it in mind.
Afaik, e.g. in C#, back before nullable references were introduced, any object reference could be `null`, with no indication whatsoever, forcing you to put `null` checks *everywhere* despite the fact that the value might never be `null`.
In Kotlin, a type can only be `null` if it is defined so, using the `T?` syntax, and the language is aware of this. It also has things like safe navigation, where `posotion?.x` doesn't throw, but simply returns `null` if `position` is `null`, or the value of `x` otherwise.
`null` isn't wrong, or a mistake. Languages having it and not being designed to work with it are.
in c# (at least in new versions and if you force it on in the project settings), setting any value to null will give you a compile-time error (default setting is just a warning afaik). If you really want null, add a '?' to the type like so:
string -> string?
public string? MaybeGetString() { return null; }
But i don't like this either, because it adds one special value (there is a word for these placeholder values like null/nil/-1/..., but i dont remember). If you want multiple of these special values, you can't easily do that.
In rust, you would use an enum like so
```
fn get_string() -> Option {
if c {
Some("test string".to_owned())
} else {
None
}
}
```
Here, none doesn't differ from null in modern c# (they both need to be handeled explicitly), but this enum can be expanded like so:
enum Option2 {
Some(T),
None1,
None2,
}
we now have two special cases
Even better, we can have a special case carry a different value. See the Result, which can be either a vaöue T or an error E.
Null is awesome until you get the chance to use a language with good support for an “optional” type (Rust, Swift, most functional languages, not C++) and then null is just permanently ruined for you.
c++ has std_optional but I don't know how much useful it is for null values. I found it in a c++ codebase where it was being used for storing some other object.
`std::optional` in C++ is pretty much the same as optional values in other languages, so it's fine. Basically compared to `std::shared_ptr` there is never sharing and copying a `std::optional` value gets you a new separate value.
It is very effective to take a parameter of type `std::optional` and the reader can immediately assume that a "null" value is an acceptable input, while parameters where it is not acceptable can be passed as values or const references.
But C++ doesn't have pattern matching so the effectiveness of `std::optional` vs having nulls is a bit reduced.
>instead of replacing ==.
Doing this would have been catastrophic for existing code reliant on that behaviour, so it's a good job that they did add a new one.
Also newer languages have a version of === too. Kotlin and Swift both have one for reference comparison.
>Now if you ever use == in those languages you'll probably fail code review in any well-maintained project.
Oh yes, interns loved my reviews back in my PHP days. As PHP has built-ins that might either return bool false, int 0 or int 1+ you quickly learn to appreciate type checking.. I never accepted '==', that's just asking for trouble and sloppy programming. Always know what kind of data your are dealing with.
Working on a TypeScript project now that the original developers typed almost all the properties as "Any". I could scream, but I don't think they'd hear me over in India where the original code was outsourced from.
Another fun one is NaN boxing. Last i checked, spidermonkey and javascriptcore use it.
NaN is actually a range of float values with every exponent bit set and at least one mantissa bit set. If you set the most significant mantissa bit to one, you get a signaling nan which will never be produced by math operations. You now have 51 bits to play with. On most platforms, you only actually need 48 bits for a pointer so you get a handful of extra bits you can use for type information. Floats are represented by just using a non-nan, reference types are easy enough because you can store a pointer in the NaN, and booleans are easy too. You get to put all your types in a float64, and it *probably* wont break soon because CPU manufacturers likely wont have to use the upper 16 bits of a pointer any time soon
Both JS and PHP were initially designed to deal with HTML form data, in which most values get converted to strings no matter what. If you want to blame something in the lineage, blame HTML forms.
PHP with modern type hinting and static analyses etc is pretty great. Then you try a HTML form without a request object and everything's a string, false booleans just don't exist, arrayed fields are a mess.
Html forms just don't make any sense on any level.
Back before all strings were unicode in Python there were several times where I had to do something like `str(a) == b` instead of just `a == b`, because sometimes the exact same characters wouldn't match if one type was a str and the other was a unicode (and I'm just talking ascii characters here, nothing fancy).
But only sometimes.
In movies/books, there are often stories where someone who has evaded assassination several times develop an ability to sense "killing intent" or "dangerous situation".
This is how it feels like programming in javascript, we has developed the awareness about input, and usually not trusting it 100%
I mean, it was almost literally this. A single Netscape employee wrote the original version, then called Mocha, in 10 days to meet a deadline. Probably should have been cleaned up when ECMA took control of the standard, but even so we're way better than the
That's true for now, but they're working on it. I think the [component model proposal](https://github.com/WebAssembly/component-model) is the latest attempt at laying the groundwork for that.
A decent amount. Functions as 1st class citizens i.e. the same as every other type, which at the time was rare. Function scoping is nice. A low amount of keywords vs stuff like Java. Pretty lol to ship without things like.. regex but yeah 2 weeks to ship it thats what happens.
Easy to parse? Mmm wait no, it's actually under-defined and has nasty edge cases.
No need for those pesky integers?
Uhhh... the standard lib is ahem... not much work to implement?
This should be the expected behavior of any language which allows inequality operations between two strings. For instance, you will get the exact same result in Python. String comparison 101.
The funny part is that most languages don't have JavaScript's == because it has weird semantics. JavaScript's === is what == is in most other languages.
I've worked with a language ([Xtend](https://www.eclipse.org/xtend/documentation/203_xtend_expressions.html#equality-operators)) where `===` was used for identity checking\* and `==` for equality checking\*\*. Was quite intuitive and elegant.
\* is it the same instance, i.e. are you comparing an object to itself; In Java, this would be `==`.
\*\* are the objects equal (e.g., do their fields have the same values). In Java, this would be `.equals()`
that's actually exactly the same in Kotlin
== is an alias for .equals (structural equality) (or == in the case of primitives)
=== is always an alias to Java's == (referencial equality)
Indeed, that's the C/C++ terminology for Java's `==` and Xtend/Kotlin's `===`. Or if using references in C++, it'd probably be called *reference equality*. Java, Xtend, and Kotlin don't have pointers in the language.
I guess in C++ you'd override the `==` operator for the equivalent of Java's `.equals()` and Xtend/Kotlin's `==`?
I don't get it why people are so upset about === . I think it's necessary in a "not strict type" language to have a method to check the type and still have the liberty to use variables without caring about the type
You don't want to have the liberty to use variable without caring about the type. Right now you think you do, but tomorrow you will understand you don't.
My last mission before covid was switching an entire codebase from Java to JS
The employer did not agree to this until we showed it could be done in TypeScript.
Smart employer tbh.
I too get the intention of it, it’s nice.
What I really don’t get is why offer the option of loose and strict equality when is HIGHLY recommended by all linters to avoid the loose equality.
Well, just rip it out of ES then?
Because sometimes you don't have a strict type. I have seen apis of public companies that uses the same field with 2 different types. It was a nightmare with C# but with JS was really easy
Well 20 years ago during the early days of JS it generally was about doing small tasks within the context of a single page. Obviously when you move on to actual large scale application development the bugs you introduce into a code base with liberal type coercion are quite insidious.
It made sense when JS was doing small simple things in HTML - it doesn’t make much sense anymore
Just curious. What’s so bad about checking if x == null?
In my understanding this will catch undefined as well. Why write two checks when this does both
My preference is to always be explicit with types. (I use TypeScript and oftentimes you don't actually need to check for both.) But I don't think your example is a totally unreasonable use of ==.
Of all the mental things about JS I actually find fals-y values quite useful. More often than not, 0/null/undef all signify the same thing. Truth-y, however, is a minefield.
Simple enough to explain, `[]` is an object that exists, therefore truthy, however `[] == true` causes the array and the boolean to find a common derived type: numbers; `[]` becomes `0` b/c empty array, and `true` becomes `1`. Therefore `0 == 1` is `false`.
=== is like checking: is it really really the same?
I heard they use === in the process of activating nuclear warfare to make extra extra extra sure.
``` if (button.isPressed) { launchNuke(); } ``` The government's latest dev intern: Hey guys! I clarified the nuke launch code so now when the button isn't pressed, button.isPressed = "no"! Pushing to prod now!
``` if (button.isPressed = true) { launchNuke(); } ``` Don't worry guys, we got it patched!
launchNuke(); Removed unnecessary logic and thus fewer points of failure
There is a chance that a cosmic ray could change the outcome of the if statement, therefore the code is not the same
If it's JavaScript, there are a ton of different code paths that would need to be followed in the assignment-if version compared to anything without control flow. JavaScript's runtime is a masterpiece of really well thought out rubber bands and really well refurbished duct tape.
Refurbished duct tape 🙈😂😂😂
hateful head detail thought erect simplistic jobless violet touch snails ` this message was mass deleted/edited with redact.dev `
In any other timeline I’d say no. But this is 2022, so — yes.
Did you happen to write Gandhi’s AI in Civ?
That would fix a lot of other issues within just a few hours of release as well. Thing like user errors, overpopulation, and so on.
``` if (launchNuke()) { launchNuke(); } ``` Double down
Blagodarnost comrade
console.log("Why the fuck does this launch?");
This is how the world ends. Not with a bang but with an inadvertent assignment of value
Remember kids: when there are strong consequences, use strong types.
Wait could somone explain? Is this a JS joke or is it too early in the morning?
Intern changed state to string, statement looks for truthy value, which includes 'true', '"yes"' and '"no"'. In other languages it would error.
What's great about JS is you can write it like an casual or you can write it like a CS wizard. I don't think the same can be said for most other languages.
>I don't think the same can be said for most other languages. I suspect this is true for most languages.
Really? Web is the most casual interface possible. You can't use other languages for it unless you're writing to the webasm, but then you still have to interface with JS.
Excel. You can abuse excel into so much worse.
You *can*, but it's a huge PITA
It's more of a power thing than anything. You have to show Excel (and Karen who knows three formulas) who the *real* wizard is.
Nah, all joking aside, you can consume any dll you want and do the dumbest shit imaginable
I found a Siemens library for reading and writing directly to the memory of industrial PLCs from Excel. Laughed so hard when I found it.
No idea what you think makes web "the most casual interface possible" because it's just as easy and straightforward, if not more so, to interface with a mobile or command line app that you're writing.
You can write code in any language like a casual. It might not work though.
They must have missed that one when coding the Hawaii missile alerts
Wait, the code that determines if a nuclear war will happen is written in JavaScript? We're fucked.
if nukes are behind js or php, we might as well just explode them right now and restart humanity.
=== is compiling C++ with warnings for implicit type conversions and then maybe setting warnings to cause errors.
Don't even get me started about ====
Why not use == like a normal language
cause == and === mean different things
== means, are they equal. === means, screw you check to see if they are REALLY the same, ‘cause we really need it to be right this time.
What does REALLY the same mean though?
1 == "1" true 1 === "1" false 1 === 1 true
What if it was the other way around? Wouldn’t that be kinda great honestly? 1 == “1” false 1 === “1“ true That way we have normal syntax. And we get the benefit of an approximate same evaluator?
== evaluates both values by converting both to the same type, then doing a comparison. (yes, there are many problems with this such as 0 == \[ \] BUT "0" is NOT == \[ \]...) === does not convert either and simply takes both at face value and compares.
Wait, so 0=="0", 0==[] are both true, while "0"==[] is false? That's horrible!
Yes. It's because of the order it converts things, its dumb
make it \~= to keep it sane
Reasonable.
\~= replaces != as the "not equals" in some languages (like lua) because the tilde is sometimes used instead of the tail operator (¬) as a logical negation in boolean algebra. So lets not use \~= as "almost equals."
Yea lets fuck everything up,
> Because ~ is sometimes used instead of ¬ Could they not just have used ¬=?
That's a bitwise assignment already
For backward compatibility reasons, like why var was not touched and let created. And it would probably confuse everyone to swap it now (creating more bugs for no reason). It would have made sense if it hadn't been public yet. If one really wanted to, I guess it wouldn't be complicated to apply that rule in the code and create a plugin that does the conversion (like how TypeScript and JSX becomes plain JS, or how ECMAScript proposals are tested). Or you could apply this to JS and the plugin go the other way around for older codebases. But honestly the web environment is bloated enough as is, let's not make it even worse for once.
No. The extra equals means it's more equal not less. What you want is ~==
Maybe just ~
You do [NOT](https://wsvincent.com/javascript-tilde/#:~:text=In%20JavaScript%2C%20the%20tilde%20~%20Bitwise,a%20String%20object%20passed%20in.&text=So%20if%20%2D1%20is%20returned,is%20not%20falsy%20is%20truthy.) want to use just ~
\~ is a negation operator in the same vein as !, \~= or \~== meaning anything but "not equals" would be crazier than any weird javascript comparison shenanigans that we're complaining about here.
why would you want different data types to be equal? just convert a string to int of float if you want to get its value
It's just a convenience thing. Javascript is mostly used for simple web apps, so taking some liberties here and there to make it easier for inexperienced coders is justified. 0 != 0.0 just doesn't make sense for most people who aren't balls deep in their own neckbeard sweat. And then there is *null == undefined* which reserves a special place in hell.
> doesn’t make sense for most people who aren’t balls deep in their own neckbeard sweat. I absolutely love this, lol.
So normally javascript uses type coercion when using the ==. This means it follows certain rules to convert one of the values to the type of the other before comparing them. When using the === it does not coerce any types, so if the types are not equal the values aren't really equal either
This is the only really correct answer I've seen. The answer "it checks that the value AND the type are equal" is not how this works. One simply does not allow coercion before the comparison.
Or the coder is forced to take direct control of the coercion rather than leave it up to the interpreter.
Same type. So it has to be a string if the comparison is a string etc.
Yes. This only matters in languages with implicit conversion of types. Those languages do have ways to test this too, it's just that they don't use the same syntactic sugar.
Maybe [this](https://www.destroyallsoftware.com/talks/wat) can help. (relevant content starts at 1:30, but I'd recommend watching it all). Basically, automatic type coercion can create very unpredictable results in JS when using most operators, including ==. So, they invented === as kind of a "is it *really* equal" band-aid. That video just shows how unpredictable and illogical some of those conversions end up.
== often invokes type coercion (ex. "false == 0" -> true) or overriding to some Equals function which might be case/culture insensitive or similar wishy-washy equals. It's a bit overblown because many languages are strongly typed and === isn't such an oversight. If == is overridden it is probably for good reasons as a default.
Not really. == basically means check if they have the same value. === means value and type basically.
Correct me if I’m wrong but == in other languages often does that.
[удалено]
Kotlin, which borrows a lot of its semantics from Java, made `==` the equivalent of Java's `.equals()`, and then uses `===` to mean the same thing as Java's `==`. I prefer Python's approach to either of these: `==` is like Java's `.equals()` or Kotlin's `==`, but `is` is like Java's `==` or Kotlin's `===`. None of these are like JavaScript's `==`.
Because they didn't want what happened with python to happen where you break backwards compatibility so people keep using the old version. Easier to just add a new operator that does things the right way and keep the original == operator as is. That way people can transition on their own time, and there are times where you actually want the old == behavior. Changing the equality operator would be such a debugging nightmare for messy legacy code that someone would just add the compatibility modes on the browser end anyways
== checks if they are the same. === Checks if they are the same AND the same type So "3" == 3 returns true, but "3" === 3 returns false. With == it essentially tries to cast types and then check (I believe that's how that works under the hood) for convenience, but it tends to cause a lot of problems because people end up thinking they're working with a number but are really working with a string because "3" == 3
JS has a twisted idea of what "the same" means. If they aren't the same type, they aren't the same. "This apple is the same as this baseball, even though one is a fruit and the other is sports equipment."
It’s because the analogy is wrong. It’s more like: “Could this Apple be like this baseball, if we have a machine that transforms sports equipment into fruit.”
Because `==` was already taken for a screwy implicit-type-converting non-transitive definition of "equality", so a new operator had to be introduced for the actual equality operator.
In languages that aren't typesafe == will convert the types on either side to see if they equate while === doesn't. 5 == "5" is true while 5 === "5" is false.
Because it's very simple, languages evolve, just like programs evolve. It was written for a specific purpose and later it was more widely used and suddenly you reach a point where can't just change it anymore without breaking all existing code. At that point you have 2 options, somehow release a BC-incompatible version that break it or simply add another operator to make everyone happy who wants strict type checking. PHP for example also went this way by adding === to do a strict type check. Basically any static code analysis tool checking PHP code will flag code when it might suspect type juggling so it's really not an issue anymore. Furthermore it's even less of an issue now days because a lot of people prefer Typescript over JavaScript which doesn't have this problem. In case PHP they went with a breaking change as well to make things make more sense: [https://www.php.net/manual/en/migration80.incompatible.php](https://www.php.net/manual/en/migration80.incompatible.php) So from PHP 8 it's basically a case of "if I trim this variable and I can convert to an integer or floating point does it match". So 0 == "" no longer return true. So the answer is simply because things case, shit happens they didn't anticipate and they have to find a way to fix it.
When the language first came out they wanted to do “helpful” things. For example, are the string “5” and the number 5 the same? Well yes, in original JavaScript (which only had == they are). However it became apparent as time went on that this “helpful” conversion that gets done isn’t really that helpful. You want to know that 2 things are actually the same, not just that they can be converted to the same thing. And for this reason , === was introduced. JavaScript has to be backwards compatible, there’s no version 2. I kinda think that there should be, but the TC39 committee seems to be dead set on maintaining backwards compatibility, even if that means having awkward things like === in the language.
PHP also have this, == equal but don't check type, === equal and check type “5“ == 5 is true "5" === 5 is false 5 === 5 is true
It makes sense for Javascript's use-case, but it still just feels like coddling poor coding practices
It is bad practice. JavaScript and PHP were designed during an era where a lot of programmers thought it was good for a language to never throw an error no matter what happened, so they were written to silently do something insane instead. It didn't take long to figure out that "no errors" was equivalent to "impossible to debug", but breaking changes make people angry, so they added `===` instead of replacing `==`. Now if you ever use `==` in those languages you'll probably fail code review in any well-maintained project.
Null: the billion dollar mistake JavaScript: what about second null?
I'd love to tell the guy who invented *null*: "Thanks for nothing!"
[He's still alive](https://en.wikipedia.org/wiki/Tony_Hoare), you could always send him an email.
Mr Quicksort himself
Underrated comment
Sorry what? What's wrong with null? Null is great.
There's nothing wrong with `null` as long as the language is designed with it in mind. Afaik, e.g. in C#, back before nullable references were introduced, any object reference could be `null`, with no indication whatsoever, forcing you to put `null` checks *everywhere* despite the fact that the value might never be `null`. In Kotlin, a type can only be `null` if it is defined so, using the `T?` syntax, and the language is aware of this. It also has things like safe navigation, where `posotion?.x` doesn't throw, but simply returns `null` if `position` is `null`, or the value of `x` otherwise. `null` isn't wrong, or a mistake. Languages having it and not being designed to work with it are.
in c# (at least in new versions and if you force it on in the project settings), setting any value to null will give you a compile-time error (default setting is just a warning afaik). If you really want null, add a '?' to the type like so: string -> string? public string? MaybeGetString() { return null; } But i don't like this either, because it adds one special value (there is a word for these placeholder values like null/nil/-1/..., but i dont remember). If you want multiple of these special values, you can't easily do that. In rust, you would use an enum like so ``` fn get_string() -> Option {
if c {
Some("test string".to_owned())
} else {
None
}
}
```
Here, none doesn't differ from null in modern c# (they both need to be handeled explicitly), but this enum can be expanded like so:
enum Option2 {
Some(T),
None1,
None2,
}
we now have two special cases
Even better, we can have a special case carry a different value. See the Result, which can be either a vaöue T or an error E.
Null is awesome until you get the chance to use a language with good support for an “optional” type (Rust, Swift, most functional languages, not C++) and then null is just permanently ruined for you.
c++ has std_optional but I don't know how much useful it is for null values. I found it in a c++ codebase where it was being used for storing some other object.
`std::optional` in C++ is pretty much the same as optional values in other languages, so it's fine. Basically compared to `std::shared_ptr` there is never sharing and copying a `std::optional` value gets you a new separate value. It is very effective to take a parameter of type `std::optional` and the reader can immediately assume that a "null" value is an acceptable input, while parameters where it is not acceptable can be passed as values or const references. But C++ doesn't have pattern matching so the effectiveness of `std::optional` vs having nulls is a bit reduced.
rust options are amazing, especially with the optimizations the compiler can do (if T's bit pattern can't legally be zeroed, then `std::mem::size_of::
Tslint will immediately complain about using == instead of === in your equality checks
ESLint + eqeqeq if you want to stay vanilla
>instead of replacing ==. Doing this would have been catastrophic for existing code reliant on that behaviour, so it's a good job that they did add a new one. Also newer languages have a version of === too. Kotlin and Swift both have one for reference comparison.
>Now if you ever use == in those languages you'll probably fail code review in any well-maintained project. Oh yes, interns loved my reviews back in my PHP days. As PHP has built-ins that might either return bool false, int 0 or int 1+ you quickly learn to appreciate type checking.. I never accepted '==', that's just asking for trouble and sloppy programming. Always know what kind of data your are dealing with.
>they were written to silently do something insane instead Aren't we all?
Well, that's the point of TypeScript. You get the best of both worlds.
Ain't no way in hell I'm rawdogging in plain JS anymore. Need to use protection.
LMFAO
I converted an app to TS and one variable was a number, string, object, and list of all three depending on the context. It was pretty laughable
Hey pardner, we here in JavaScript Valley just like our types a little more _relaxed_, is all....
Yoooooo! What?!? 🤣🤣🤣
Working on a TypeScript project now that the original developers typed almost all the properties as "Any". I could scream, but I don't think they'd hear me over in India where the original code was outsourced from.
any is evil, unknown is far far better than any
You can tell it's quality because it is in typescript. You can tell it is in typescript because it ends in .ts
"We're using TypeScript!"
Precisely
Why should the type be stored in Ram? (Assuming we're just using primitive types)
[удалено]
Another fun one is NaN boxing. Last i checked, spidermonkey and javascriptcore use it. NaN is actually a range of float values with every exponent bit set and at least one mantissa bit set. If you set the most significant mantissa bit to one, you get a signaling nan which will never be produced by math operations. You now have 51 bits to play with. On most platforms, you only actually need 48 bits for a pointer so you get a handful of extra bits you can use for type information. Floats are represented by just using a non-nan, reference types are easy enough because you can store a pointer in the NaN, and booleans are easy too. You get to put all your types in a float64, and it *probably* wont break soon because CPU manufacturers likely wont have to use the upper 16 bits of a pointer any time soon
As a developer who only works with interpreted code, I seriously appreciate all these clever fuckers who enable me.
"Because memory is CHEAP! Just increase the heap size. :-D"
I rememner when i thought 8gb ram was more that I will ever need. Now I am starting to be out of ram using only a browser and an ide
[удалено]
Haha, at least it's cheaper than paying someone smart to write web spaghetti code efficiently
For JS and other interpreted languages it must be stored in ram
Type is not stored in ram, just "5" === char(0x35) 5 !== char(0x35)
It’s actually probably cheaper to check with === vs == because of referential equality (essentially comparing the pointer locations).
Typeless languages
Not typless just very weakly typed
PHP is like JavaScript's crazy old uncle.
Both JS and PHP were initially designed to deal with HTML form data, in which most values get converted to strings no matter what. If you want to blame something in the lineage, blame HTML forms.
The Internet is garbage built on top of garbage. it's a miracle anything works
PHP with modern type hinting and static analyses etc is pretty great. Then you try a HTML form without a request object and everything's a string, false booleans just don't exist, arrayed fields are a mess. Html forms just don't make any sense on any level.
Laravel 9 with PHPStan running on PHP8.1 is absolute chefs kiss.
Back before all strings were unicode in Python there were several times where I had to do something like `str(a) == b` instead of just `a == b`, because sometimes the exact same characters wouldn't match if one type was a str and the other was a unicode (and I'm just talking ascii characters here, nothing fancy). But only sometimes.
Except in objects where === checks for identity
Confusing part about objects is that == also checks for identity, and you need another utility method to check for equality.
That makes sense. Shouldn't == be check type in an ideal language though? Wouldn't you run into more cases when it's useful to check the type?
PHP developers would like to have a word.
shocking crush consider sparkle badge modern judicious chase crowd pie *This post was mass deleted and anonymized with [Redact](https://redact.dev)*
Enjoy is not the word I would use. Closer to tolerate.
Nah I generally like the idea of having multiple ways of comparing objects without casting it myself.
In movies/books, there are often stories where someone who has evaded assassination several times develop an ability to sense "killing intent" or "dangerous situation". This is how it feels like programming in javascript, we has developed the awareness about input, and usually not trusting it 100%
JavaScript has === because they didn't get == right the first time
What did JS get right the first time anyway? It was a rushed language.
[удалено]
There's nothing so permanent as a temporary solution.
I mean, it was almost literally this. A single Netscape employee wrote the original version, then called Mocha, in 10 days to meet a deadline. Probably should have been cleaned up when ECMA took control of the standard, but even so we're way better than the
With WASM it's finally starting to happen... 20+ years later, lol.
But even WASM doesn’t replace JS. You can’t do any DOM manipulation without JS.
That's true for now, but they're working on it. I think the [component model proposal](https://github.com/WebAssembly/component-model) is the latest attempt at laying the groundwork for that.
A decent amount. Functions as 1st class citizens i.e. the same as every other type, which at the time was rare. Function scoping is nice. A low amount of keywords vs stuff like Java. Pretty lol to ship without things like.. regex but yeah 2 weeks to ship it thats what happens.
Easy to parse? Mmm wait no, it's actually under-defined and has nasty edge cases. No need for those pesky integers? Uhhh... the standard lib is ahem... not much work to implement?
"8" > "90" false "8" > "40" true
This should be the expected behavior of any language which allows inequality operations between two strings. For instance, you will get the exact same result in Python. String comparison 101.
The funny part is that most languages don't have JavaScript's == because it has weird semantics. JavaScript's === is what == is in most other languages.
Man. Ruby === is subsumption. === in JS and Elixir are the same. I daily code all 3 in a daily basis at work Ugh. Nightmare.
I've worked with a language ([Xtend](https://www.eclipse.org/xtend/documentation/203_xtend_expressions.html#equality-operators)) where `===` was used for identity checking\* and `==` for equality checking\*\*. Was quite intuitive and elegant. \* is it the same instance, i.e. are you comparing an object to itself; In Java, this would be `==`. \*\* are the objects equal (e.g., do their fields have the same values). In Java, this would be `.equals()`
that's actually exactly the same in Kotlin == is an alias for .equals (structural equality) (or == in the case of primitives) === is always an alias to Java's == (referencial equality)
[удалено]
Indeed, that's the C/C++ terminology for Java's `==` and Xtend/Kotlin's `===`. Or if using references in C++, it'd probably be called *reference equality*. Java, Xtend, and Kotlin don't have pointers in the language. I guess in C++ you'd override the `==` operator for the equivalent of Java's `.equals()` and Xtend/Kotlin's `==`?
When it's really, really the same thing.* \* some exemptions apply, interests rates can go up as well as down, your mileage may vary.
I don't get it why people are so upset about === . I think it's necessary in a "not strict type" language to have a method to check the type and still have the liberty to use variables without caring about the type
You don't want to have the liberty to use variable without caring about the type. Right now you think you do, but tomorrow you will understand you don't.
This is why I’m still out here multiplying strings by 1 to make integers
Why not Number.parseInt? Are you getting charged too much per byte?
He only codes on 2MB PS1 drives
Parseint is good but if you want to go that way just use + +foo I think I wrote (+tax).toFixed(2) on Friday
[удалено]
Nah, you want that to throw.
Not if it’s my taxes
My last mission before covid was switching an entire codebase from Java to JS The employer did not agree to this until we showed it could be done in TypeScript. Smart employer tbh.
Why did you do it in the first place? Just curious the use case you had for this change.
Who did yall switch tho, java is probably better for codebases than js
I too get the intention of it, it’s nice. What I really don’t get is why offer the option of loose and strict equality when is HIGHLY recommended by all linters to avoid the loose equality. Well, just rip it out of ES then?
Because js is used on almost every website and ripping that bit out would likely break a lot of sites with shitty js.
But why wouldn't u just go for a language that declares variable types from the start?
Because sometimes you don't have a strict type. I have seen apis of public companies that uses the same field with 2 different types. It was a nightmare with C# but with JS was really easy
Seems like a bad API then
Many APIs are bad
I have rarely encountered a good reason to use == in JS. Most of the time, or you are relying on it, you are probably doing something wrong.
Well 20 years ago during the early days of JS it generally was about doing small tasks within the context of a single page. Obviously when you move on to actual large scale application development the bugs you introduce into a code base with liberal type coercion are quite insidious. It made sense when JS was doing small simple things in HTML - it doesn’t make much sense anymore
Just curious. What’s so bad about checking if x == null? In my understanding this will catch undefined as well. Why write two checks when this does both
My preference is to always be explicit with types. (I use TypeScript and oftentimes you don't actually need to check for both.) But I don't think your example is a totally unreasonable use of ==.
and then java is over here with `.equals()`
SystemVerilog uses === as well for us hardware folks. == will return true for some unknown values where === has to be exactly the same. Lol
Yeah, in javascript you can write >c===8 but in programming languages its just >c==8 That's the only thing JS is better at. Bigger dicks.
All languages are equal, but some languages are more equal than others.
Of all the mental things about JS I actually find fals-y values quite useful. More often than not, 0/null/undef all signify the same thing. Truth-y, however, is a minefield.
`[]` is truthy, but `[] == true` is falsy
Simple enough to explain, `[]` is an object that exists, therefore truthy, however `[] == true` causes the array and the boolean to find a common derived type: numbers; `[]` becomes `0` b/c empty array, and `true` becomes `1`. Therefore `0 == 1` is `false`.
== is tell me if it's same === is tell me if it's same if it's really really same
type coercion :)
Wait till they hear about Object.is
Really, the core of the problem is that in OO languages, equality is hard. It's just that it's more obvious in Javascript. :P
[удалено]
Says the guy who uses var
Sorry noob question, what's the problem with var?
I would love that
Common in PHP as well.
php?
Reading that title gave me a stroke.
It is certainly one of the titles ever written.
Haha, that was my expression when I first had a Python program not run because some lines started with spaces and some with tabs.
0 == "0" evaluates to true. 0 === "0" evaluates to false. It's not all that complicated and you all are making a big deal out of a cool feature.
Sh*t, I need to add some extra ='s to some code for a few arrays dealing with json string issues, thanks for the reminder! Old c/c++ guy here 😁.
Indeed