But I can't think of any case with `==` type operators, or really any other operators where it also makes sense.
So was that maybe an overgeneralized feature that should have been limited to the math operators?
But I can't think of any case with `==` type operators, or really any other operators where it also makes sense.
So was that maybe an overgeneralized feature that should have been limited to the math operators?
I think that’s a pretty reasonable expectation, too.
In JavaScript, {} + [] evaluates to integer 0. That doesn’t make any sense, but it makes more sense after reading the ES spec for the addition operator.
There are many expressions you can write in dynamically typed languages that don’t make any sense, probably most of them actually, but they have to be considered valid because it’s a dynamically typed language. So they’re valid, they will evaluate to something.
The language designers aren’t so concerned with identifying every possible combination that makes no human-intuitive sense. The important part is that when it seems like types should be inferred and coerced in a particular way, then that’s how it should work. It should match human intuition.
I don’t have any intuition or opinion about how True == False is False should be evaluated, this kind of thing is going to receive superfluous parentheses from me every time for the benefit of the reader, and if someone else wrote it this way I’m always going to look it up or test it in a REPL...
10 < x <= 100 though, if that’s considered a valid expression and it doesn’t evaluate to true for numbers in the range (10,100], I’m going to stop using that language...
Not really - a language could throw an exception in these cases, as Python does for things like “a”+1. Not every dynamically-typed language is JavaScript.
a = "a"
a = 1
That's dynamic typing. Strong typing means only that a = "a" + 1
fails.More about that at https://en.hexlet.io/courses/intro_to_programming/lessons/ty...
JavaScript and PHP and Perl automatically cast to a reasonable value with all the advantages and pitfalls.
> a = "a" + 1
>fails.
String a = "a" + 1; works in Java. So Java is not strongly typed?
Without overloading the + operator, string concatenation which is a common operation, would have been unnecessarily verbose. Your example without the + operator would look like below:
String a = new String(“a”).concat(1); // String object concat
String a = “a”.concat(1); // String literal concatJava just happens to be less prominent in tech media right now since JS on the server is the new(-ish) hotness. There's still plenty of dislike for it, but really, all that needed saying about it happened long before now.
See C where ints, pointers, floats, and bools can almost all coerce into each other, such that the compiler will allow you to use arithmetic/logic operators with most different types, whether you meant to or not.
Those two attributes are mostly orthogonal.
Dynamic typing refers to checking of types at runtime. JS does not do this consistently or effectively. Python does.
The typeof operator cannot be the basis of a type system since you can count all the answers it gives on your fingers. JS needs a bunch of extra functions like Array.isArray() to determine if something is an array or not. The language itself has no clue, everything that isn't a primitive is just an "object" as far as JS is concerned.
For the rest I don't understand how anybody can seriously make the argument that JS has no types. Shell scripts have no types because almost everything is a character string and that's it. JS type system is very limited but it does exist and I don't see how it can be used to justify {} + [] = 0, which is where we started (especially given that {} and [] are objects in JS, but 0 is a "number", so different core types). Adding two objects and getting a number is not a limitation of the type system, it's a conscious decision by the designers (or at least the side effect of one).
It's the consequence of ill-thought mechanics when it comes to type coercion. It's the original sin of many scripting languages: "let's just add a bunch of shortcuts everywhere so that it doesn't get in the way of the developer trying to make a quick script". Then you end up with a bunch of ad-hoc type coercion and the language guessing what the user means all over the place, and eventually these bespoke rules interact with each other in weird ways and you end up with "{} + [] = 0".
> I think in language design there’s an expectation that if an expression or statement doesn’t make any sense, then people won’t write it that way.
That's either very idealistic or very naive. In either case I'd argue that's a terrible way to approach language design. I'd argue that many well designed languages don't make any such assumptions.
>but they have to be considered valid because it’s a dynamically typed language.
Nonsense. Try typing `{} + []` in a python REPL. You seem to be suffering from some sort of Javascript-induced Stockholm syndrome, or maybe simply lack of experience in other languages. JS does the thing it does because it was designed(?) that way, not because there's some fundamental rule that says that dynamically typed languages should just do "whatever lol" when evaluating an expression.
The widespread prevalence of JS transpilers and everyone’s apparent unwillingness to write pure JS makes me think it probably isn’t such a great language. It probably never had a chance given its history with browsers.
Just using it to make the point that every language has valid expressions that make no sense. You can find similar examples in every language. All you have to do to find them is start writing code in a way that no person ever would or should write it.
Especially in the case of dynamically typed languages, throwing an exception sometimes but not always based on the “human intuitiveness” of any given type inference would make the language even more unpredictable. It’s just instead of asking why expression a evaluates to x, we would all be asking why expression a evaluates to x but similar expression b throws an exception.
If you ask me, the latter is even more arbitrary.
These aren’t useful criticisms. The only reason these kind of critiques even get so much attention is because people reading the headline think: “I wonder how the hell that would be evaluated?” And so they click.
The headline is only interesting to begin with because nobody ever writes that, and nobody should ever write that.
If nobody would ever write it or have any expectations about its evaluation, then how is it even significant that the language will interpret it one way vs another?
I think these criticisms are a good springboard to have the debate about static vs dynamic typing, but arguing over whether True == False is False should be evaluated one way vs another is kind of pointless. If the result of that argument is agreement, then we might end up with people actually writing this, which should be the last thing any of us want.
This not really true. Put this js console and you'll see that a is the string "[object Object]":
a = {}+[]
When you put just {}+[] in your console its doing an empty block followed by unary-plus,like: {/*do nothing block*/}; +[]I guess JS’s parser explicitly prohibits adding things to a curly-brace enclosed entity?
I’m normally quite defensive of JS, but I’ll have to admit I don’t like that.
You can also do like ({} + []) and it will actually be "adding" them; the confusion solely comes from people typing into the JS console something that wouldn't make any sense to put into an actual script.
({}) + []
-> "[object Object]"
will correctly make it "[object Object]"Did you try to do this?
{a: 1} + []
-> 0
That's interpreted as the statement 1 labeled a, not as an object. This makes it obvious it's not an object: {a: 1, b: 2} + []
-> Uncaught SyntaxError: Unexpected token ':'
JavaScript supports labels so you can continue/break multiple levels at once: {
a: while (true)
while (true)
break a;
} foo == bar == baz
But chaining the == with other operators feels weird, especially "is". Similarly foo >= bar <= baz
feels very off to me, and I'm not sure it should be chainable. If the intuition is to emulate human notation in math, there are many chained expressions that we would not allow to happen.Chaining anything with `is` feels weird to me, but:
foo >= bar == baz >= fooo
fells perfectly ok.
if a <= b > c:
But then, what to do in those disallowed cases? Is the parser powerful enough to make them SyntaxErrors?If not, I’d much rather have the above compiled into the unintuitive `a <= b and b > c` than the completely wrong `(a <= b) > c`.
But, yeah, if there are contradictory comparisons, that should be deprecated and raise an error immediately because it indicates a logic error. If you're doing something awful like using custom operators for side-effects, just write out (a <= b) and (b > c).
Most likely, though, no one is using custom operators for side-effects in chaining because the implicit `and` coerces arguments to booleans. So, with numpy, you can compare two ndarrays with a < b and it returns a new array of booleans, but you can't chain compare three ndarrays because `and` coerces the result to a single boolean.
if x == y == z:(= x y z)
x = y = z = 4;
But I think this is assignment expressions which were controversial in Python or something.But then the two lists are the same, and appending to one appends to the other. Not particularly useful.