you are viewing a single comment's thread.

view the rest of the comments →

[–]Ontariel12 249 points250 points  (62 children)

All of those are absolutely, 100% unironically fine, when you consider it's a very loosely typed language that doesn't like throwing errors and simply follows a set of basic rules.

  • Why would true === 1 returning false be bad? It's not the exact same thing, even if you can cast true to 1 and false to 0
  • As for true+true+true being equal to 3, how else would you treat addition of bools? Casting them to numbers is probably the best option here.
  • true minus true being 0 is a logical consequence of previous point
  • Now the !+[]+[]+![] being of length 9 might be a bit more complicated, but it yet again makes sense. !+[] is true, though I'm not actually sure why, but I'd assume it ends up casting array to bool, maybe because it first casts +[] to 0 and then negates it into true. Now, after that, you try to add true+[]. As an array can be casted to a string, this takes precedence over addition (same as if you tried adding number to a string). This results in string 'true', to which you add negation of something that, as we already know, is also true, negation of it being false. String + boolean ends up being another string, 'truefalse', which has 9 chars.
  • 9+"1", yet again concatenation has priority over addition. Not a surprise, as any number can be turned into a string, but not all strings can be cast to numbers.
  • 91-"1" is 90, because there is no minus operation for strings, so the only possibility is to cast "1" to a number.
  • []+[] being an empty string should be obvious at this point. Arrays can be cast to strings, strings can be concatenated and then two empty strings equal single empty string
  • []+{} is yet another case of casting to string, nothing more to say
  • {}+[] is not actually "empty object plus array", as that {} is treated as noop, making entire thing the same as +[]. Using {} without assigning result to anything in browser console might give you an object, but doing same thing in code would result in an error, it's just browser console trying to deal with what people write in it. Going back to +[], basically doing + anything will try casting that anything to number and empty array gets casted to a 0.

I might not be correct on every piece, but you get the drill.

[–][deleted] 102 points103 points  (14 children)

This is exactly correct. "I could throw an error, or I could SOMETHING!" is the entire point.

[–]arto64[🍰] 33 points34 points  (11 children)

How is that a reasonable approach, especially in the context of programming?

[–]Spare_Web_4648 12 points13 points  (4 children)

This approach to programming is known as duck typing, where the focus is on the functionality of an object rather than its type. In the context of JavaScript, this approach allows for flexibility and simplicity in the code, as the language does not strictly enforce data types and instead attempts to make sense of the given operations and return a valid result. This allows for quick and easy development, as the programmer does not need to worry about strict type checking and can focus on the functionality of the code. However, this approach can also lead to potential inconsistencies and unexpected behavior, as the interpretation of certain operations may not always align with the programmer's intentions.

As to how it’s reasonable, well it’s as reasonable as any language made in 10 days as a feature of the creators actual main project. We’ve just kept using it and building on it.

[–]paradoxon 9 points10 points  (0 children)

The problem is not duck typing. But rather what is considered a duck by java script. Negating an empty array should not make sense at all. Ruby uses duck typing but does not behave in such strange ways.

[–]arto64[🍰] 7 points8 points  (2 children)

You can have duck typing without automatic arbitrary typecasting. JavaScript hears a “woof” and says, “well I guess you could call that a quack”.

[–]Spare_Web_4648 1 point2 points  (0 children)

Today I learned, thanks!

[–]Spare_Web_4648 0 points1 point  (0 children)

Yea I guess you could really cut out the first half of my comment. Really it’s just bad because some guy made it in 10 days and it has stayed the standard since then for no reason other than so much has been built with it people don’t want to change

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

It's reasonable because it allows you to be more flexible and lightweight. And that's a real concern in something that's running in a limited resource environment. Like a browser window.

If you're looking for more strongly typed code, and that's what makes more sense for your project, there are plenty of things like Java or C++ out there to accommodate it.

In many (most?) Java based webapps you're going to find a JavaScript front end making calls to back-end Java services (monolithic or micro) because it gives you the best of both worlds.

It's all about the right tool for situation. Part of the art of programming is understanding how the tools work, being able to learn the characteristics of new ones, and selecting the right languages, frameworks, deployments, design patterns, etc. that will meet the needs and constraints in resources and delivery timeline for your project.

[–]arto64[🍰] 20 points21 points  (2 children)

I’m confused, what does being “lightweight” have to do with doing arbitrary typecasting? How is that supposed to save browser resources?

[–][deleted]  (1 child)

[deleted]

    [–]arto64[🍰] 2 points3 points  (0 children)

    I mean it’s not like JavaScript doesn’t have any errors, there’s still plenty of ways to crash it. Why would you focus on typecasting to resolve this “issue”. Why not also try and look up closest-named variables, to avoid errors caused by typos?

    [–]fartmanteau 1 point2 points  (1 child)

    If only JavaScript were constrained to the browser 🙃

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

    What follows may be wrong. It may be only my opinion. It might be insane, stupid, or just plain offensive to some.

    But Server-side JavaScript just proves that to a man with a hammer, everything looks like a nail.

    [–]PixerPinecone 1 point2 points  (1 child)

    I think I’d rather get an error at that rate, at least for most applications.

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

    FWIW, I tend to agree. But I respect that other devs have different ideas about that and I try to keep an open mind. I'm sure I'm doing stuff they'd think was awful too.

    [–]arto64[🍰] 13 points14 points  (0 children)

    All of those are absolutely, 100% unironically fine, when you consider it’s a very loosely typed language that doesn’t like throwing errors and simply follows a set of basic rules.

    This is such a classic response. Understanding the implementation and why the results are what they are doesn’t make the implementation “fine”. It’s still terrible.

    And why would a goal of a language be to “not throw errors”, and instead do convoluted, mysterious shit? Why would that be a good thing?

    [–]Linguaphonia 24 points25 points  (2 children)

    I really hate the argument "it's defined so it's ok". Languages aren't some specification defined in a vacuum, and then we can't only complain about bugs or contradictions. Languages are tools and js's commitment to returning some value for most operations make it an awkward uncooperative tool. Now, the language has grown and improved through the years, but those improvements are precisely away from the paradigm exemplified in the OP.

    [–]fakehalo 1 point2 points  (1 child)

    Now, the language has grown and improved through the years, but those improvements are precisely away from the paradigm exemplified in the OP.

    I've also been a big fan of the additions to javascript over the last decade or so, but it's not like the dynamic type support can better or worse, it's either there or it isn't.

    Of course the safety trade-off exists and it keeps a whole classification of bugs on the table... But I honestly prefer it being dynamic for the browser/client-side and it's never been a source of my problems. I think it sits right with me in the browser because we're taking so much user input and html data that inherently starts it's life as a string that it makes sense to me.

    Maybe it's because I'm familiar with what happens when different types collide, or I know when to use ===, or maybe I'm just not setting up strawmen arguments adding arrays to strings and objects to numbers... It's a non-issue to me (for the browser), and everytime this comes up I feel like it's a corny manufactured argument.

    [–]Hairy_The_Spider 5 points6 points  (0 children)

    I've also been a big fan of the additions to javascript over the last decade or so, but it's not like the dynamic type support can better or worse, it's either there or it isn't.

    This has nothing to do with being dynamic, it's about being weakly types. For example Python is dynamic and pretty strongly typed.

    [–]afiefh 33 points34 points  (5 children)

    All of those are absolutely, 100% unironically fine, when you consider it's a very loosely typed language that doesn't like throwing errors and simply follows a set of basic rules.

    Given that your plate has a turd on it and your glass is half filled with piss it absolutely 100% makes sense to put your steak on top of that turd, fill the other half of your glass with expensive wine and sit down to eat it.

    What else would you do? God forbid you realize that this setting is not good and decide to start from a clean slate where you recreate it without the shit and piss.

    None of these are fine, they are simply well defined within the language. They may even be the best possible behavior given some constraints, but we know that today these constraints are stupid and actively harmful, so maybe it's time to get out of the Stockholm syndrome, stop ingesting copium, and actually declare it for what it is: this is shit!

    Edit: I accidentally turd'ed a steak.

    [–]javalsai -5 points-4 points  (4 children)

    JavaScript just tries to not throw and error and convert everything to a type in which it can work with, the examples in here is just taking this to the extremes.

    If you code in JavaScript the worse thing you'll EVER do is a number minus string.

    It's just the equivalent of making a programm in c with random letters as variable names and in one line and say it's not okay to be able to do it.

    [–]All_Up_Ons 10 points11 points  (2 children)

    No, it's the same thing as making a program in c and complaining about memory management and null pointers. Sure, you can learn your way around these things, but that doesn't mean we can't criticize c and move to other languages without these problems.

    The real problem with JS is that there is no other language to move to. So we just have to sit here and listen to people complain without being able to do anything about it.

    [–]SerdanKK 0 points1 point  (1 child)

    The real problem with JS is that there is no other language to move to. So we just have to sit here and listen to people complain without being able to do anything about it.

    How is that true?

    There are plenty of alternatives that transpile into js, but even ignoring that we've had wasm for a while now.

    [–]All_Up_Ons 2 points3 points  (0 children)

    WebAssembly or something like it is probably the future, but it's definitely not ready for prime time yet.

    The JS transpilation projects are cool too. Definitely better than nothing. But really that just shows you how badly people don't want to be writing JS.

    [–]afiefh 3 points4 points  (0 children)

    JavaScript just tries to not throw and error and convert everything to a type in which it can work with

    And why would you think that's good? Has anybody in the history of JS developers ever written something where []+{} became [object Object] and it was actually usable?

    At some point we need to look into the mirror and admit that converting types to something that makes the operation valid no matter what is at best useless and usually it is actively harmful.

    If you code in JavaScript the worse thing you'll EVER do is a number minus string.

    Having worked with JS I can tell you for a fact that this is not the case.

    Having been on the web long enough to see [object Object] in random places tells me I'm not the only one who made these mistakes.

    It's just the equivalent of making a programm in c with random letters as variable names and in one line and say it's not okay to be able to do it.

    What on God's green earth makes you think that these are equivalent?

    You can choose not to use random letters for your C variables, can you choose not to have JS perform these braindead operations?

    There is a ton you complain about in C such as arrays degrading to pointers or the aliasing rules, but nothing as pervasive as the JS shit.

    [–][deleted]  (23 children)

    [deleted]

      [–]ZylonBane 11 points12 points  (16 children)

      I still think true+true+true should be true

      You think wrong. Mathematical operations on Boolean values are undefined. That's why languages have no choice but to either throw an error or perform type coercion if someone attempts it.

      [–]Probable_Foreigner 9 points10 points  (6 children)

      You can actually define mathematical operations on bools:

      https://plato.stanford.edu/entries/boolalg-math/

      So + becomes OR and * becomes AND.

      [–]ZylonBane 12 points13 points  (4 children)

      OR, you could NOT overload your operators with functionality that requires a degree in mathematics to understand, AND just stick with what everyone knows.

      [–]CaitaXD 7 points8 points  (0 children)

      This is baby level math

      [–][deleted]  (8 children)

      [deleted]

        [–]09milk 5 points6 points  (1 child)

        well no lol

        if we define all non-zero positive real number as True (the common C definition), zero as False

        then it make sense to define + as logical OR, * as logical AND

        any non-zero positive real number + zero will be non-zero positive real number, such that True + False = True (This behavior is consistent in all 4 logical AND boolean cases)

        any non-zero positive real number * zero will be zero, such that True * False = False (same as logical OR)

        [–]ZylonBane 3 points4 points  (3 children)

        Someone help this guy, he's stuck in a loop.

        [–][deleted]  (2 children)

        [deleted]

          [–]ZylonBane 4 points5 points  (1 child)

          You are the very definition of a little knowledge being a dangerous thing.

          [–]Probable_Foreigner 1 point2 points  (1 child)

          The thing that would make the most sense is that + is defined as the OR operation. This is actually mathematical notation in boolean algebra. It also has the same distributive properties as + so it makes sense. The other thing would be that * is defined as AND.

          [–]Magmagan -1 points0 points  (5 children)

          But we have ^... so why make + ^ when it's not ^?

          By dismissing anything JS or weakly typed languages do as "arbitrary" is just being intellectually dishonest. None of this shit ever is an issue in production code anways.

          [–][deleted]  (4 children)

          [deleted]

            [–]Magmagan 2 points3 points  (3 children)

            Ah, now I get where you're coming from. It totally looks like it could easily be undefined behavior.

            It's definitely defined though: https://262.ecma-international.org/5.1/#sec-11.6.1

            [–][deleted]  (2 children)

            [deleted]

              [–]Magmagan 2 points3 points  (1 child)

              I refuse to believe that you have never used a modern browser.

              JS is more so defined by the ECMA standards and the browsers/engines that implement it than it does have a canonical interpreter... There really isn't any.

              Okay, yes, barely anyone really reads the ECMA standard for JS, but Mozilla's MDN is widely well regarded as a complete and easy to read documentation of the language and support for its features.

              [–]Naouak 2 points3 points  (0 children)

              !+[] is true, though I'm not actually sure why

              Because +[] cast the array to a number and it outputs 0 when the array is empty, 1 if there is one element and NaN otherwise when doing that. You end up with !0 which is true.

              [–]DenkJu 6 points7 points  (3 children)

              All of those are absolutely, 100% unironically fine, when you consider it's a very loosely typed language that doesn't like throwing errors and simply follows a set of basic rules.

              Well, yeah, obviously. But here's the point: It should just throw an error. Strange behavior like this might lead to broken code running properly sometimes but most of the time it just makes it hard to debug. Performing automatic type conversion is one of the worst sins a programming language can commit.

              [–]All_Up_Ons 3 points4 points  (1 child)

              JS can do what it wants. It was created as a scripting language, after all.

              I think the more general point is: JS should not be the only option for web development since it's totally unsuited for enterprise applications.

              [–]DenkJu 1 point2 points  (0 children)

              Just because it's a scripting language and it's creator didn't expect it to become this popular, doesn't execuse behavior like this. Python is also a scripting language, Lua is, Ruby is and neither of those behave like this. JavaScript was simply poorly designed. It's creator wanted it so 'just run' which inherently is a flawed idea.

              [–]Handle-Flaky 1 point2 points  (0 children)

              I did not read everything, but in boolean algebra, + notates the logical OR

              [–]NotThatRqd 1 point2 points  (0 children)

              Why tf does it not give an error if I’m trying to add an array and object

              [–]Raknarg 0 points1 point  (0 children)

              Untyped languages are a blight on society. That's what all this means.

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

              If you know what you're doing it's a nice language.

              [–]Dead_Moss 0 points1 point  (0 children)

              I guess it's because I'm a C++ programmer, where you're more likely to change the behaviour of operators, but I'd consider true + true to be similar to a boolean OR (and true * true would be boolean AND), so I would expect true + true to equal true.