JavaScript
-
You're right. I've got too much Perl on the brain and forgot my roots. There is a language that does what you're talking about with the '+' operator: BASIC
Good luck getting the same thing retrofitted into JavaScript though. I can imagine a large number of websites would break or develop mysterious problems if this (mis)behaviour was fixed.
I don't think there's a way to retrofit JS - but php versions are deprecated all the time. Why not do the same with client-side script versions?
-
That is just the tip of the iceberg:
Oh wow, that's upsetting
-
It's not nonsensical, implicit type coercion is a feature of JavaScript, it's perfectly logical and predictable.
JavaScript is a filthy beast, it's not the right tool for every job, but it's not nonsensical.
When you follow a string with a
+
, it concatenates it with the next value (converted to string if needed). This makes sense, and it's a very standard convention in most languages.Applying arithmetic to a string would be nonsensical, which they don't do.
You are entitled to your opinion. implicit conversion to string is not a feature in most languages for good reasons.
-
That is just the tip of the iceberg:
Not just javascript: https://www.destroyallsoftware.com/talks/wat
-
That is just the tip of the iceberg:
Ugh, like... I get why it outputs like that, but I also absolutely hate that it outputs like that.
-
If you try what I wrote it will throw a NaN. I was asking about the first part of the proposal.
The NaN isn't an thrown. It's just silently put into the result. And in this case it's completely unintelligible. Why would an operation between two strings result in a number?
"Hello" - "world"
is an obvious programmer mistake. The interpreter knows that this is not something anyone will ever do on purpose, so it should not silently handle it.The main problem here is downward coercion. Coercion should only go towards the more permissive type, never towards the more restrictive type.
Coercing a number to a string makes sense, because each number has a representation as a string, so
"hello" + 1
makes intuitive sense.Coercing a string to a number makes no sense, because not every string has a representation as a number (in fact, most strings don't).
"hello" - 1
makes no sense at all. So converting a string to a number should be done by an explicit cast or a conversion function. Using-
with a string should always result in a thrown error/exception. -
That is absolutely
(n > 1) * ("ba" + 0/0 + "a")
(n > 1) * ("ba" + 0/0 + "a")
Uncaught ReferenceError: n is not defined
?
-
That's the case in many languages, pretty much in all that don't have a separate string concatenation operator.
Yeah, and almost all languages I know then would throw an exception when you try to use
-
with a string, and if they offer multiple operators that take a string and a number, they always only perform string operations with that and never cast to a number type to do math operations with it.(e.g. some languages have
+
for string concatenation and*
to add the same string X time together, so e.g."ab" * 2 => "abab"
. It's a terrible idea to have+
perform a string operation and-
performs a math operation.) -
Yeah, and almost all languages I know then would throw an exception when you try to use
-
with a string, and if they offer multiple operators that take a string and a number, they always only perform string operations with that and never cast to a number type to do math operations with it.(e.g. some languages have
+
for string concatenation and*
to add the same string X time together, so e.g."ab" * 2 => "abab"
. It's a terrible idea to have+
perform a string operation and-
performs a math operation.)Sure, but then your issue is with type coercion, not operator overloading.
-
Sure, but then your issue is with type coercion, not operator overloading.
Because there's in fact no operator overloading happening, true, but that's mostly an under-the-hood topic.
It should not happen no matter why it does happen under the hood.
Operator overloading for
string - string
is wrong and type coercion to implicitly cast this toint(string) - int(string)
is just as wrong. -
Because there's in fact no operator overloading happening, true, but that's mostly an under-the-hood topic.
It should not happen no matter why it does happen under the hood.
Operator overloading for
string - string
is wrong and type coercion to implicitly cast this toint(string) - int(string)
is just as wrong.wrote on last edited by [email protected]There is operator overloading happening - the
+
operator has a different meaning depending on the types involved. Your issue however seems to be with the type coercion, not the operator overloading.It should not happen no matter why it does happen under the hood.
If you don't want it to happen either use a different language, or ensure you don't run into this case (e.g. by using Typescript). It's an unfortunate fact that this does happen, and it will never be removed due to backwards compatibility.
-
There is operator overloading happening - the
+
operator has a different meaning depending on the types involved. Your issue however seems to be with the type coercion, not the operator overloading.It should not happen no matter why it does happen under the hood.
If you don't want it to happen either use a different language, or ensure you don't run into this case (e.g. by using Typescript). It's an unfortunate fact that this does happen, and it will never be removed due to backwards compatibility.
There is operator overloading happening - the + operator has a different meaning depending on the types involved. Your issue however seems to be with the type coercion, not the operator overloading.
For
string + string
andnumber + number
there is operator overloading, that's correct. Forstring + number
there is not, there's only type coercion. It becomesstring + string(number)
. All of that is fine. Other languages do that as well.What's not fine is that JS also looks the other way on the type coercion tree: There's no
string - string
overloading, so it goes down the type coercion tree, looking for any-
operation that it can cast to and it ends up withnumber(string) - number(string)
, which makes no sense at all.If you donβt want it to happen either use a different language, or ensure you donβt run into this case (e.g. by using Typescript). Itβs an unfortunate fact that this does happen, and it will never be removed due to backwards compatibility.
It's not the point of the discussion that there are other languages that are better. This here is about complaining about bad language design, and no matter how you turn this, this is not a matter of taste or anything, this is just bad language design.
You are obviously right that this crap will stay in JS forever. That doesn't make it good design.
-
The NaN isn't an thrown. It's just silently put into the result. And in this case it's completely unintelligible. Why would an operation between two strings result in a number?
"Hello" - "world"
is an obvious programmer mistake. The interpreter knows that this is not something anyone will ever do on purpose, so it should not silently handle it.The main problem here is downward coercion. Coercion should only go towards the more permissive type, never towards the more restrictive type.
Coercing a number to a string makes sense, because each number has a representation as a string, so
"hello" + 1
makes intuitive sense.Coercing a string to a number makes no sense, because not every string has a representation as a number (in fact, most strings don't).
"hello" - 1
makes no sense at all. So converting a string to a number should be done by an explicit cast or a conversion function. Using-
with a string should always result in a thrown error/exception.wrote on last edited by [email protected]The interpreter knows that this is not something anyone will ever do on purpose, so it should not silently handle it.
You basically defied the whole NaN thing. I may even agree that it should always throw an error instead, but... Found a good explanation by someone:
NaN is the number which results from math operations which make no sense
And the above example fits that.
"hello" - 1
makes no sense at all.Yeah but actually there can be many interpretations of what someone would mean by that. Increase the bytecode of the last symbol, or search for "1" and wipe it from string. The important thing is that it's not obvious what a person who wrote that wants really, without additional input.
Anyway, your original suggestion was about discrepancy between + and - functionality. I only pointed out that it's natural when dealing with various data types.
Maybe it is one of the reasons why some languages use . instead of + for strings.
-
Look! I bought this for free on capybaras website, there's a glitch!
capybara: at least it didn't throw an error.
/ jk
Use typescript if you're paranoid about this
-
I'd rather have my website shit itself than have silent difficult to find errors.
Use typescript
-
This is exactly why it should throw an error, to make it incredibly obvious something isn't working correctly so it can be fixed. Otherwise you have wrong logic leading to hard to notice and hard to debug problems in your code
Use typescript
-
In practice runtime errors are a bitch to find and fix.
Fair enough. This is why people prefer typescript
-
The interpreter knows that this is not something anyone will ever do on purpose, so it should not silently handle it.
You basically defied the whole NaN thing. I may even agree that it should always throw an error instead, but... Found a good explanation by someone:
NaN is the number which results from math operations which make no sense
And the above example fits that.
"hello" - 1
makes no sense at all.Yeah but actually there can be many interpretations of what someone would mean by that. Increase the bytecode of the last symbol, or search for "1" and wipe it from string. The important thing is that it's not obvious what a person who wrote that wants really, without additional input.
Anyway, your original suggestion was about discrepancy between + and - functionality. I only pointed out that it's natural when dealing with various data types.
Maybe it is one of the reasons why some languages use . instead of + for strings.
You basically defied the whole NaN thing. I may even agree that it should always throw an error instead, but⦠Found a good explanation by someone:
NaN is the number which results from math operations which make no sense
Well, technically this is the explanation, it really isn't a good one.
x + 1
with x not being defined also doesn't result in aNaN
but instead it throws a reference error, even though that undefined variable isn't a number either. Andx = 1;x.toUpperCase();
also doesn't silently do anything, even though in this case it could totally return"1"
by coercing x to a string first. Instead it throws a TypeError.It's really only around number handling where JS gets so weird.
Yeah but actually there can be many interpretations of what someone would mean by that. Increase the bytecode of the last symbol, or search for β1β and wipe it from string. The important thing is that itβs not obvious what a person who wrote that wants really, without additional input.
That's exactly the thing. It's not obvious what the person wants and a
NaN
is most likely not what the person wants at either. So what's the point in defaulting to something they certainly didn't want instead of making it obvious that the input made no sense?A similarly ambiguous situation would be something like
x = 2 y
. For someone with a mathematical background this clearly looks likex = 2 * y
with an implicit multiplication sign. But it's not in the JS standard to interpret implicit multiplication signs. If you want multiplication, it needs to explicitly use the sign. And thus JS dutifully throws a Syntax Error instead of just guessing what the programmer maybe wanted.Anyway, your original suggestion was about discrepancy between + and - functionality. I only pointed out that itβs natural when dealing with various data types.
My main point here was that if you have mathematical symbols for string operations, all of the acceptable operations using mathematical symbols need to be string operations. Like e.g.
"ab" * 2 => "abab"
, which many languages provide. That's consistent. I didn't mean that all of these operators need to be implemented, but if they aren't they should throw an error (I stated that in my original comment).What's an issue here is that "1" + 1 does a string concatenation, while "1" - 1 converts to int and does a math operation. That's inconsistent. Because even you want to use that feature, you will stumble over
+
not performing a math operation like-
.So it should either be that +/- always to math operations and you have a separate operator (e.g.
.
or..
) for concatenation, or if you overload+
with string operations, all of the operators that don't throw an exception need to be strictly string-operations-only. -
You are entitled to your opinion. implicit conversion to string is not a feature in most languages for good reasons.
Sure. And you're entitled to yours. But words have meaning and this isn't MY OPINION, it's objective reality. It follows strict rules for predictable output, it is not nonsensical.
You're entitled to think it's nonsense, and you'd be wrong. You don't have to like implicit type coercion, but it's popular and in many languages for good reason...
Language Implicit Coercion Example JavaScript '5' - 1 β 4
PHP '5' + 1 β 6
Perl '5' + 1 β 6
Bash $(( '5' + 1 )) β 6
Lua "5" + 1 β 6
R "5" + 1 β 6
MATLAB '5' + 1 β 54
(ASCII math)SQL (MySQL) '5' + 1 β 6
Visual Basic '5' + 1 β 6
TypeScript '5' - 1 β 4
Tcl "5" + 1 β 6
Awk '5' + 1 β 6
PowerShell '5' + 1 β 6
ColdFusion '5' + 1 β 6
VBScript '5' + 1 β 6
ActionScript '5' - 1 β 4
Objective-J '5' - 1 β 4
Excel Formula "5" + 1 β 6
PostScript (5) 1 add β 6
I think JavaScript is filthy, I'm at home with C#, but I understand and don't fear ITC.
-
Sure. And you're entitled to yours. But words have meaning and this isn't MY OPINION, it's objective reality. It follows strict rules for predictable output, it is not nonsensical.
You're entitled to think it's nonsense, and you'd be wrong. You don't have to like implicit type coercion, but it's popular and in many languages for good reason...
Language Implicit Coercion Example JavaScript '5' - 1 β 4
PHP '5' + 1 β 6
Perl '5' + 1 β 6
Bash $(( '5' + 1 )) β 6
Lua "5" + 1 β 6
R "5" + 1 β 6
MATLAB '5' + 1 β 54
(ASCII math)SQL (MySQL) '5' + 1 β 6
Visual Basic '5' + 1 β 6
TypeScript '5' - 1 β 4
Tcl "5" + 1 β 6
Awk '5' + 1 β 6
PowerShell '5' + 1 β 6
ColdFusion '5' + 1 β 6
VBScript '5' + 1 β 6
ActionScript '5' - 1 β 4
Objective-J '5' - 1 β 4
Excel Formula "5" + 1 β 6
PostScript (5) 1 add β 6
I think JavaScript is filthy, I'm at home with C#, but I understand and don't fear ITC.
C# is filthy. But it explains where you got your warped idea of righteousness.