Hacker News new | ask | show | jobs
by atirip 2825 days ago
We fully embrace Javascript as dynamically typed language and when one does this, types on most cases will become irrelevant. Then also using === in the code means that the usage is explicitly required in this specific place and == will cause wrong result. But when === and == are the same, then we use strictly ==. Also read this: http://dmitry.baranovskiy.com/post/typeof-and-friends

If you are curious, please post some real life real working code where in your mind usage of === is absolutely needed and I try my best to explain how I would tackle that with ==.

5 comments

> "We fully embrace Javascript as dynamically typed language and when one does this, types on most cases will become irrelevant."

That's not dynamic typing, that's weak typing.

Dynamic typing just means the types are omitted in the source code, but they're still there. typeof 3 is still 'number'. If you explicitly specify the types, you get TypeScript.

But weak typing means you can do things with disparate types that you can't normally do, usually by implicitly coercing one to the same type as the other.

The world has generally considered weak typing a very bad idea. Type coercion has too many edge cases and unintuitive/unexpected combinations. Even Lua is experimenting with runtime flags that disable type coercion such as "1" + 2. (That's the reason they have the .. operator btw.)

The only byproduct of weak typing that most people agree on keeping in modern languages is the concept of "truthy", but even then, languages have different ideas of what should be truthy. Clojure and Ruby say everything except nil and false are truthy, Python says "" and [] are also falsey, and I don't remember where JavaScript fully stands on this, but I know that null, undefined, false, and "" are at least falsey.

Yep, you are correct about generic truthy. We have standard library function empty(), which is custom (agreed internally what is empty) and which everyone knows. That solves many issues you pointed.
> The world has generally considered weak typing a very bad idea.

Now that is the type of thing that screams for supporting evidence.

> Type coercion has too many edge cases and unintuitive/unexpected combinations.

That depends on the implementation. I would say Perl handles this problem neatly by making the coercion done entirely based on the operator used, so it's always obvious.

> Now that is the type of thing that screams for supporting evidence.

I think the direction of mainstream programming languages over the past 20 years is overwhelmingly clear about this.

There's only one language that I know of that's still in popular use and that likes weak typing.

> That depends on the implementation. I would say Perl handles

Yep that's the one.

> There's only one language that I know of that's still in popular use and that likes weak typing.

As much as I wish it wasn't so, I believe PHP sees more activity currently than Perl, and it's also weakly typed.

Javascript itself is weakly typed as well, which is why we're all having this discussion.

I would say that two of the most popular languages (probably the two most popular new languages) of the last two decades have been weakly typed.

That's a fair point, but I think this article shows that weak typing in JS is actively avoided by most people. That's why the article is interesting in the first place. I don't know if PHP heavily relies on weak typing though, I haven't used it in 9-10 years. But JS doesn't rely on it. It's just there, and easily avoided.
> please post some real life real working code where in your mind usage of === is absolutely needed and I try my best to explain how I would tackle that with ==.

I think you're expending your energy for the wrong reasons. There is no need to be "clever" when writing code. Being explicit is always better. Being explicit is how bugs are avoided, how new people can enter your codebase, and how you can maintain your codebase in the future. If you spend time thinking about how to justify usage of something in your code, it has no justification being used.

Disagree. Nothing clever in this, just elementary JS knowledge. I claim that relying in types in dymanic language (always ===) is actually worse. Better is not rely on types.
The types are there, are to some extent you always have to rely on them. You can't call .push() on a string, or pass a number to Object.keys(). I can't imagine a situation where using == even works as you expect it to, aside from comparing numbers and strings that contain numbers. In which case the string should be converted to a number at the user input edge, as part of (but not the entire) input normalization, sanitation and validation phase.
> Nothing clever in this, just elementary JS knowledge.

How's your score on the minesweeper? :)

Probably bad ;-) Seriously speaking all that comparison tables are pure academic stuff. In real code I honestly ever encountered a case where I have no clue whatsoever what both sides of equation are. To the claim that when you have such conditions, then you need to fix that and such code is bad to the bones. Real life code is much more boring - if (a == “b”) where there is no value possible for a where === would give different result. But, I like to alleviate that there is no beef for me in this discussion, i just wanted to show that, yes, someone still uses == and he is not looney ;-)
>We fully embrace Javascript as dynamically typed language [...]

I won't outright dismiss your coding style because I don't know what your codebase looks like and maybe you're genuinely talented JS devs who know what they're doing (something I'm decidedly not) but your comment makes it sound like discouraging the use of '==' is not "embracing" JS's dynamism. I don't think I agree with that, actually there are a bunch of highly dynamic languages where comparison is not such a mess. The main problem with '==' is that it's highly inconsistent and intransitive (as showcased by TFA). It's tricky to figure out what evaluates to true or false when types don't match. It's not PHP bad but it's pretty damn bad.

I'm certain that at least 95% of our code would be safe if you replaced === with ==. We likely have some edge cases that would blow up, but by and large, we don't really depend on the type checking of identity. We write code as if you explicitly declare type on JS.

I don't think using equality is inherently bad. I think that it can lead to a lot of bad habits for junior devs who don't understand some basics about types. I'm not against weak/implicit typing systems, but my experience has taught me that junior devs (and student alike) are prone to errors extending from the type system.

Yes. To combat that we have code reviews (pull request workflow) and generally friendly and supportive atmosphere.
"We fully embrace Javascript as dynamically typed language"

Ok, but why? Do you not think there's an advantage in having a difference between strings and numbers?

"1" == 1?

You can chose that if you want, surely, but what are the advantages of 'embracing' this?

If you do arithmetic's it's converted to Number, if you concatenate it's converted to string. It's however unfortunate that + is used for both concatenation and addition. The advantage is flexibility and convenience. You can for example have functions that takes almost anything as input and does what you want, so that you do not have to tell the computer in detail what types to use.

For example in Node.JS callback convention the last argument is always the callback functions, even if the function takes 4 arguments, you can put the callback in the 3:rd argument and it will figure out which one is the callback function. Then the first parameter in the callback function is either null or an Error.

Another example is RegeExp where you can write if( str.match(/foo/) ) instead of if ( str.match(foo) === null )

It's also convenient that empty strings are "falsy" which allow you to write if(!foo) instead of if( foo==="" || foo===undefined || foo===0 )

Ok, but I really don't think that any of those conveniences outweigh the downsides of total lack of typing.

Also - you can use the == 'falsiness' whilst still in a strict scenario.

If you take the typing argument one step further, into Typescript, the advantages of just some basic typing become considerably more clear as the compiler/transpiler picks up loads of problems that wouldn't be found otherwise.

The only problem I can see is mixing strings and numbers. But there are probably more errors someone pro types would say is type errors while someone pro dynamic/loose typing would say is not ... Here's a nasty bug that took me like two hours to debug (this is only two lines, but imagine a sea of code where such thing could easily hide). Can you spot it ?

    var foo = [];
    foo.push["bar"];
You could say it's a type error. It's however not caught by neither TypeScript or Flow.
If you want to type an array, you can do that in Typescript.

let x:number[] = []; x.push("x");

Here, the transpiler will catch the error of trying to push a string to a number array.

Typing is your friend, and it will in almost all cases help you write cleaner and safer code.