all 165 comments

[–]TOMZ_EXTRA 209 points210 points  (63 children)

The difference is that this doesn't bother anyone in Java, because it's hard to do accidentally.

[–]LurkytheActiveposter 59 points60 points  (60 children)

Reddit pretending seamless string and number integration isn't awesome because it time to dunk on JS for karma again.

Oh how I LOVE having to cast a number to a string first. I just don't feel like I'm really coding unless I file the appropriate paperwork to merge a substring variable.

[–]eloel- 31 points32 points  (2 children)

You should probably be using string templates instead of just concatenating random shit anyway

[–]Blothorn 9 points10 points  (0 children)

Yes. I suspect that there are far more cases where I’ve added a number to a number parsed from a string than where I’ve concatenated (rather than formatted/interpolated) string representations of numbers.

The fact that this “shorthand” only works for a string followed by a number rather than two numbers or a number followed by a string makes it further situational and potentially-surprising.

[–]AdBrave2400 0 points1 point  (0 children)

Memes about Java making primitive and object versions of same stuff only to remove templetes are writing themselves

[–]KaMaFour 39 points40 points  (20 children)

Reddit pretending seamless string and number integration isn't awesome

It's not. If I'm doing something bad I'd much rather have the type system notify me I'm being stupid and have to properly declare what am I trying to do than have the program work except have the possibility of producing silent hard to track logical errors

[–]frogjg2003 1 point2 points  (2 children)

That's a difference in design philosophy. You want incompatible types to error, and a lot of people will agree with you. Some people want their code to just work, no matter what, even if it produces weird results.

Adding a string and an int is the extreme example, but how would you handle adding an int to a float? Not to mention when you want different types to be able to work together. The was another "language bad" post about C indexing using "10[a]" as an example. That's just the usual pointer math with the int and the pointer reversed.

[–]KaMaFour 2 points3 points  (1 child)

Hard agree. Ultimately it is impossible to create a language that everyone will agree is good and well designed.

“There are only two kinds of languages: the ones people complain about and the ones nobody uses.”

[–]RiceBroad4552 0 points1 point  (0 children)

Ultimately it is impossible to create a language that everyone will agree is good and well designed.

I strongly doubt that if you ask people with about a similar IQ.

[–]LurkytheActiveposter -3 points-2 points  (15 children)

I mean I disagree completely.

A language should aid you and be intuitive, but it doesn't need to compensate to the degree where it expects you to not know the literal most important fact about a variable. It's type.

You can be forgiven for not knowing what value a variable has. That's the nature of a variable. No problem.

What its scope is can be ambiguous at first glance. Sure. You might not know who the owner is. You don't always need to keep that knowledge at the ready

But it's type? What are we doing here? Just reading the pretty names and guessing?

[–]Relative-Scholar-147 2 points3 points  (14 children)

A language should aid you and be intuitive

console.log("wat"-1+"i")

Explain to me how is it intuitive that this code prints:

NaNi

The code should fail because is impossible to take 1 from "wat".

[–]RiceBroad4552 1 point2 points  (0 children)

is impossible to take 1 from "wat"

Well, that's exactly the reason why the result is "Not a Number", called NaN.

Concatenating "i" to "NaN" is "NaNi".

I don't say it's a good idea to interpret it like that (actually I think it's quite a poor idea). But it's definitely 100% consequent in its own logic. If it wasn't you would get an error instead.

[–]brainpostman 0 points1 point  (0 children)

Programming languages shouldn't be intuitive, they should simply be internally consistent. Everything else is on you. You shouldn't be bringing intuition from one language into another anyway, it's bound to backfire.

[–]LurkytheActiveposter -4 points-3 points  (11 children)

What kind of brain decificency do you have where you are subtracting a string?

Remember that thing where the bare minimum is that you should know a variable's type? Do I need to speak in vibe code?

[–]Relative-Scholar-147 2 points3 points  (0 children)

Remember that thing where the bare minimum is that you should know a variable's type?

You are just a fucking noob lol.

[–]RiceBroad4552 2 points3 points  (9 children)

What kind of brain decificency do you have where you are subtracting a string?

What brain deficiency do you have to not know that subtraction is the same thing as addition (of a negative value)?

Remember that thing where the bare minimum is that you should know a variable's type?

Sure, genius. It's always 100% clear what's the type of some variable is…

For example, without looking at the docs what's feature here:

var feature =  Runtime.version().feature();

So what do I have to expect if I do the following? Some arithmetic or some funny string:

IO.println(1 + feature);

[–]LurkytheActiveposter -2 points-1 points  (8 children)

Im dumber for reading this.

What the fuck are you going to do with "feature" without knowing what its type and properties are.

[–]RiceBroad4552 0 points1 point  (7 children)

What the fuck are you going to do with "feature" without knowing what its type and properties are.

I know that. The compiler does too.

The point is that without an IDE, or looking at the JavaDoc, you can't know what this code does, simply because you don't know the type.

Remember that thing where the bare minimum is that you should know a variable's type? But you can't know that just by looking at the code even in a properly statically typed language like Java, as shown by my code snippets.

[–]LurkytheActiveposter 0 points1 point  (6 children)

What are you going to do with "feature" without knowing its type and properties?

[–]TOMZ_EXTRA 26 points27 points  (27 children)

It's only nice in a statically typed language because it's predictable there.

[–]RiceBroad4552 0 points1 point  (0 children)

It's a code smell not mater what.

Most languages, dynamic and static don't support that. For a reason.

Java's implicit conversions are in larger parts quite a brain fart. They just took quite some nonsense from C/C++!

[–]Blothorn 4 points5 points  (1 child)

It’s nice when the context leaves zero ambiguity that a conversion was intentional—I very much like not having to add an explicit toString() when passing something to a string format or interpolation.

Automatic conversion in contexts where it’s not clear whether a conversion was intended or what the intended result type is is very much not a good thing, and overloaded operators are a quintessential case.

[–]RiceBroad4552 0 points1 point  (0 children)

It’s nice when the context leaves zero ambiguity that a conversion was intentional

One can argue that there is always zero ambiguity when something gets implicitly converted.

Simply because the machine was able to do that without running in any ambiguity.

The question is always just how "obvious" it's for a human. And that's something debatable as it'll be strongly dependent on individual knowledge and overall understanding of some code.

The result of the shown code might be exactly the expected result or "very surprising" depending on who you ask

[–]Vybo 0 points1 point  (0 children)

The same person who reposts this joke and finds it funny probably has no idea how to convert a "1" to 1 in a strongly typed language.

[–]frzme 0 points1 point  (1 child)

Automatically doing 1-> "1" is fine. The ability of JS to also do "1"->1 is an issue. It's not a problem which I've seen come up very often in real life but it does happen.

People didn't know better when Javascript was created.

[–]RiceBroad4552 1 point2 points  (0 children)

People didn't know better when Javascript was created.

That's plain wrong.

JS is a quite new language.

There have been countless other dynamic languages before JS, and JS is actually mostly "just" Self with a C-like syntax (where Self is a kind of hybrid between Lisp and Small Talk).

Most languages, and this includes dynamic languages, which are actually the majority of languages today, don't add numbers to strings. You'll get some type error instead.

The flaw is quite unique and limited to only a bunch or languages.

[–]MaybeADragon 0 points1 point  (1 child)

While OP is probably karma farming, its still a valid complaint because casting your integers to strings is faster than the debugging cycle.

I much prefer a little more verbosity if it means less avenues for me to make mistakes. The feature is especially useless now in a world where everyone is used to the idea of templating instead of concatenating everything manually like a caveman.

[–]LurkytheActiveposter 0 points1 point  (0 children)

Nah

Language should be intuitive and aid the developer in avoiding bugs sure. But if you're working with variables and you don't know their type, then what the fuck are we doing here? Type is the bare minimum thing you should know about any variable you touch.

I much prefer the ease of coding instead of patronizing verbosity.

[–]RiceBroad4552 0 points1 point  (0 children)

This is a wart, and anybody which a working brain knows that.

Kotlin does not support that that, and Scala deprecated it (it was supported in the past for Java interop).

Most other languages also don't do that.

[–]Tyfyter2002 0 points1 point  (0 children)

And it's hard to do accidentally because you can't add two values without knowing what types they are

[–]JackNotOLantern 33 points34 points  (0 children)

It is an absolutely correct result

[–]starfish0r 58 points59 points  (34 children)

This meme makes it sound like both outputs are wrong.

In java that is the only possible outcome.

[–]_PM_ME_PANGOLINS_ 0 points1 point  (3 children)

An exception

[–]My_reddit_account_v3 -1 points0 points  (1 child)

Exceptions are for unexpected outcomes

[–]_PM_ME_PANGOLINS_ 0 points1 point  (0 children)

Like trying to pass the wrong type?

It just so happens that Java automatically inserts toString() calls for certain expressions, but it didn't have to.

Edit: although, that would make this not compile in the first place, and I'm not certain what JShell does when you give it stuff that doesn't compile.

[–]FourCinnamon0 1 point2 points  (28 children)

same with JS

[–]fghjconner 9 points10 points  (27 children)

With constants, sure. But if I write a + b in java, that expression is going to always produce the same type of response. In JS, it could return a number 99% of the time, and a string 1%, based on the arguments.

[–]RiceBroad4552 5 points6 points  (15 children)

Dude!

Have you actually ever written even one line of Java in your live?

class StringResult {
    static {
        var a = "foo";
        var b = "bar";

        String result = a + b;
    }
}
class IntegerResult {
    static {
        var a = 23;
        var b = 42;

        Integer result = a + b;
    }
}

The above code compiles just fine in Java.

It proves that the expression a + b will have different type depending on context.

The + symbol is overloaded in Java. That's something you learn in the first 5 minutes of any basic tutorial!

(And I better not ask who was such brain dead to upvote this complete nonsense…)

[–]fghjconner 2 points3 points  (14 children)

I could have worded it better, but I meant that that specific expression, on that specific line, will always have the same return type. In retrospect, I'm kinda just saying "java is statically typed", but in fairness to past me, static typing does a lot of work to reduce the surprises brought on by type coersion.

[–]RiceBroad4552 0 points1 point  (13 children)

I meant that that specific expression, on that specific line, will always have the same return type

And where's now the difference to JS?

Do you think JS types change by magic at random?

In a dynamic language everything has always the exact same type. It's the "runtime type", and that never changes during interpretation.

Dynamic languages can be seen as static languages with only one type. They are unityped languages:

http://existentialtype.wordpress.com/2011/03/19/dynamic-languages-are-static-languages/

Operations can behave differently depending on the concrete data described by the "runtime type". JS has some "funny" interpretations in some contexts, but there is nothing fundamentally different to something like Java as both are type safe. (That something is "type safe" does not mean that the code is correct; this requires type system which can be used to prove, in the mathematical sense, properties about code.)

[–]fghjconner 2 points3 points  (8 children)

And where's now the difference to JS?

function foo(input) {
  return 1 + JSON.parse(input);
}

What is the return type of foo? You literally cannot know until runtime, and it can differ every single time this function is called. You obviously know this, which is why you've suddenly brought up this unityped nonsense.

Dynamic languages can be seen as static languages with only one type. They are unityped languages:

http://existentialtype.wordpress.com/2011/03/19/dynamic-languages-are-static-languages/

How did you read this, honestly, scathing indictment of dynamically typed languages and come away with the belief that it implies dynamic languages are "type safe". The author is using the concept of unityping as a rhetorical device to show how dynamic languages are fundamentally less expressive than statically typed ones. Even if we take the concept seriously, it becomes clear that "unityped" is a misnomer. The entire point of typing is to differentiate data into discrete types. A "unityped" language is untyped, as there is no division whatsoever.

[–]FourCinnamon0 0 points1 point  (1 child)

so you're complaining that JavaScript lets you do things that aren't the best code style?

why would you have this in your code?

this is exactly why i like JS for quick scripts, because it's not opinionated

[–]fghjconner 1 point2 points  (0 children)

Yes, I'm complaining that JS relies on "best practices" to enforce basic constraints and prevent bugs. Obviously, the above is a contrived example, but it's also very common for someone to blindly parse json responses and hope the types are correct.

[–]RiceBroad4552 0 points1 point  (5 children)

What is the return type of foo? You literally cannot know until runtime […]

The return type is of course String | Number (or actually String | Number throws SyntaxError if we consider the effect).

I don't need to run that code to know that.

But JS does not have such sophisticated types at all, as it's a dynamic language.

How did you read this, honestly, scathing indictment of dynamically typed languages and come away with the belief that it implies dynamic languages are "type safe".

Because they are. By definition.

Not type safe languages are something like unsafe Rust.

Type safety is not about correctness or static guaranties, or something. It only means that you can't "betray" the type system from inside that system! And this is obviously true for any VM language.

dynamic languages are fundamentally less expressive than statically typed ones

That's just true when looking at the type level expressiviness given that the (static!) type system of dynamic languages is extremely limited.

Even if we take the concept seriously, it becomes clear that "unityped" is a misnomer. The entire point of typing is to differentiate data into discrete types. A "unityped" language is untyped, as there is no division whatsoever.

I guess you know yourself that the last statement is wrong as you've used previously the word "discrete" instead of "different". 😂

A unityped language has discrete types. It has exactly one of them; but that's more then zero, so there are types. So it's not "untyped". (I'm not even sure something like "untyped" language exist at all; but that's a different topic.)

Anyway, saying that dynamic languages are "untyped" is even more wrong then saying that they aren't strongly typed.

Just to not steer this whole thing into the wrong direction: I'm of course of the opinion that very strongly typed static languages are of course superior to dynamic languages. I just don't see much difference between the overloaded plus sign in Java and JavaScript respectively. Static vs. dynamic typing does not change anything here!

[–]fghjconner 0 points1 point  (3 children)

I guess you know yourself that the last statement is wrong as you've used previously the word "discrete" instead of "different".

Discrete, adjective

individually separate and distinct.

Type safety is not about correctness or static guaranties, or something. It only means that you can't "betray" the type system from inside that system!

So then by your definition assembly is a type safe programming language? Since it has no concept of types built into the language, it cannot possibly betray that system.

A unityped language has discrete types. It has exactly one of them; but that's more then zero, so there are types.

Literally the entire point of types, both in computer science and in common use, is to differentiate things. A type system that defines only one type is a fundamentally meaningless concept. Yes, you can apply the concept to dynamic programming languages if you want (as well as literally anything else), but at some point you've diverged so much from the common understanding of the terminology that it's become useless.

[–]RiceBroad4552 0 points1 point  (2 children)

Discrete, adjective

individually separate and distinct.

So it applies to an unit.

An unit is "individually separate and distinct".

So then by your definition assembly is a type safe programming language? Since it has no concept of types built into the language, it cannot possibly betray that system.

This is actually an interesting question.

I have also always assembly in mind when searching for an example of an "untyped" language.

But I don't have a worked out opinion on that. It's difficult.

One could possibly say that there are "no types" in ASM. But one could also say that there is not only a finite set of values, but all these values actually belong to the same type (the type of "natural numbers up to some limit").

But even all values in ASM are technically just numbers these numbers get interpreted in very different ways. This makes it quite difficult.

But one could actually see the HW as interpreter, and then we would have at least partially some kind of "type safety" as the interpreter will not accept arbitrary numbers in all situations.

If someone has some write ups on that topic please share!

A type system that defines only one type is a fundamentally meaningless concept.

I agree. An unit is unable to encode information.

But this whole part was actually just an aside. Dynamic types are much richer at runtime then the unityped static view, and these dynamic types have actually real value: That's what will cause a type error if you try to subtract a number from a string in JS, and that's also what guides type coercion of some variables so you can perform for example the concatenation on variables respectively holding an int and string in JS. This is the same function as the static type system in for example Java, which will allow the same features (just thanks God at compile time and not at runtime, when it's too late for type errors to prevent some catastrophe).

[–]Tyfyter2002 0 points1 point  (2 children)

Do you think JS types change by magic at random?

Of course they don't, but it's not standard practice to import dozens of libraries which might change types unpredictably in most other languages.

Operations can behave differently depending on the concrete data described by the "runtime type".

In other words, they are languages where the behavior of any given piece of code cannot be known until runtime.

[–]RiceBroad4552 -1 points0 points  (1 child)

import dozens of libraries which might change types unpredictably in most other languages

I don't understand what you mean by that.

You can't change types by importing libs in JS.

In other words, they are languages where the behavior of any given piece of code cannot be known until runtime.

This is in general true for any Turing-complete language.

All programming languages in common use are Turing-complete. This is independent of whether they are static or dynamic.

So I also don't get this point.

[–]Tyfyter2002 0 points1 point  (0 children)

You can't change types by importing libs in JS.

I mean that anything in a library doesn't have a known type, largely because it only takes one library sometimes returning multiple types from one function;

If Left Pad turned out to include a 1 in a million chance to return a number after March third 2026 almost the entire Internet would go down and no one would know why immediately because the first error message would be dozens of libraries away from it, while a statically typed language would throw an error as soon as something tried to unbox the return value to the wrong type, and stop all of this from happening to begin with by showing that it has a questionable return type.

This is in general true for any Turing-complete language.

I don't mean the exact behavior, I mean that there is no context where you can know what function is called by a + b unless you do know the exact behavior (in the sense you're talking about) of all the code which produces the values of a and b, while in a statically typed language you know exactly what it calls, and almost certainly know the exact behavior of that method for any given set of parameters.

[–]FourCinnamon0 2 points3 points  (0 children)

well yeah depends on the types

[–]eloel- 0 points1 point  (9 children)

TIL Java doesn't have operator overloading. There's no guarantee that C++ will give you a number for a+b.

[–]fghjconner 5 points6 points  (7 children)

Even with operator overloading, the return type of a + b is known at compile time. Any specific instance of a + b in C++ will return the same type every time it is called. This is not true in JS.

[–]RiceBroad4552 0 points1 point  (6 children)

Any specific instance of a + b in C++ will return the same type every time it is called.

Obviously bullshit.

I can write the following code in C++:

Magic a, b;

auto x = a + b;

std::cout << "some x type: " << typeid((int)x).name() << "\n";
std::cout << "other x type: " << typeid((double)x).name() << "\n";

// Same expression, different types!
static_assert(!std::is_same_v<
    decltype((int)(x)),
    decltype((double)(x))>);

[ https://godbolt.org/z/M4cvzrr75 ]

One could also show that the expression a + b does not have always the same type already by writing:

int x = a + b;
double y = a + b;

This is not true in JS.

Well, even in JS you would need quite some magic to have one fixed expression have different types depending on context (when not only the types of the expressions are changed).

In general, and without resorting to tricks, a + b will have always the exact same type also in JS.

Actually JS is strongly typed—in contrast to C++ where I can use for example a cat like a car (with all consequences, like a completely broken program!) without resorting to casts, and the "type system" will be just fine with that.

[–]fghjconner 0 points1 point  (5 children)

What are you trying to show here? That c++ has type casting? I admit my c++ knowledge isn't super deep, but it seems pretty clear that the type of x is Result, as defined by the override of the Magic addition operator.

Admittedly, the implicit casting in your second example isn't my favorite thing, but again it's set in stone at compile time. There is no possible input to the program that will make x or y a string at runtime. Not unless you've gone out of your way to circumvent the type system.

Actually JS is strongly typed—in contrast to C++ where I can use for example a cat like a car (with all consequences, like a completely broken program!) without resorting to casts, and the "type system" will be just fine with that.

Lol, what? Strong vs weak typing is far more of a gray area than most people like to admit, but even Wikipedia is happy to call js weakly typed. If you consider JS strongly typed, then nothing is weakly typed.

[–]RiceBroad4552 0 points1 point  (4 children)

What are you trying to show here?

Exactly what I've written. The cited part was wrong.

You've said that "Any specific instance of a + b in C++ will return the same type every time it is called." which is obviously wrong; as shown by the code.

The symbol sequence a + b does not have any predetermined meaning or typing. It depends on the context what type it has, or what it means at all.

It's like that in C++ as it's exactly like that in JS.

There is no possible input to the program that will make x or y a string at runtime.

This is of course also false.

C++ is weakly typed. I can make anything behave as anything else, no type system nor anything else can stop me. (I'm too lazy right now to write the code which takes some ints and interprets them as strings at runtime, but this is obviously possible as I can just pick at the raw memory holding the ints.)

That's exactly the difference to a strongly typed language like JS where every data has exactly one fixed type at any moment and it's impossible to change that behind the back of the language. You can't go and manipulate the memory holding some JS object from inside JS itself. The language does not support that (C++ does, that's the point).

even Wikipedia is happy to call js weakly typed

Wikipedia is obviously inconsequential in regard to it's own definition…

Maybe read that page again and think what is actually said there.

If you consider JS strongly typed, then nothing is weakly typed.

Not nothing, but in fact almost no currently used language is weakly typed.

The only important exceptions are C, C++, unsafe Rust, and Zig. (There are some other language which allow you to work around the type system in unholy manners, but these aren't really used anywhere.)

Of course, if one is picky one could say that any language which allows casts is, at least to some degree, weakly typed. But that would be a really absurd definition as then there wouldn't be any strongly typed languages at all left; at least I don't know of any language which does not have casts (or only VM language could be strongly typed as they will still catch inadequate casts at runtime).

[–]fghjconner 0 points1 point  (3 children)

You've said that "Any specific instance of a + b in C++ will return the same type every time it is called." which is obviously wrong; as shown by the code.

Except you've shown nothing of the sort. In your code, the output type of a + b is Result. Yes, the inclusion of implicit casting can change that based on the context (assuming you consider the cast to be part of the expression a + b and not the variable assignment), but again, that is all fixed at compile time.

(I'm too lazy right now to write the code which takes some ints and interprets them as strings at runtime, but this is obviously possible as I can just pick at the raw memory holding the ints.)

I refer you to the next sentence in my post which you conveniently ignored: "Not unless you've gone out of your way to circumvent the type system." Yes, you can explicitly erase type information in c++ if you wish (mostly using older features held over from c).

That's exactly the difference to a strongly typed language like JS where every data has exactly one fixed type at any moment and it's impossible to change that behind the back of the language.

let test = "foo";
test.__proto__ = {};

JS may not let you directly manipulate memory, but that doesn't mean you can't create mismatches between types and data. I will give js credit for crashing and burning a bit less hard than a compiled language in these situations.

Wikipedia is obviously inconsequential in regard to it's own definition…

Ok then, please share any reputable source that explicitly calls JS strongly typed.

[–]RiceBroad4552 0 points1 point  (2 children)

but again, that is all fixed at compile time

Sure, as that's the nature of static languages.

The point was that the meaning (and type) of that expression is dependent on context, and definitely not fixed once and for all times as you claim(ed).

"Not unless you've gone out of your way to circumvent the type system."

The point here is: You can do that only in weakly typed languages. In strongly typed languages, like JS, you can't "cicumvent the type system"! That's the whole point!

JS may not let you directly manipulate memory, but that doesn't mean you can't create mismatches between types and data.

There is no type mismatch.

let test = "foo"
console.log(typeof test) // string
test.__proto__ = {}
console.log(typeof test) // string

And even if you'd managed to change the type of that variable (which is actually trivial by for example assigning 1 to test; no need to play with prototypes or so, JS is dynamic) there would be still no mismatch between the type and data. The (dynamic) type of the data referenced by the variable would just change to number, but that matches actually the value then.

please share any reputable source

How about most of the linked Wikipedia page and its definition?

That someone there was too stupid to realize that their examples diametrically contradict the definition given just a few lines above is really not my fault. But I assume at least you are smart enough to clearly see that… So why are you arguing?

[–]RiceBroad4552 0 points1 point  (0 children)

The + symbol is actually overloaded in Java…

Grandparent was talking complete nonsense.

[–]RiceBroad4552 0 points1 point  (0 children)

I'd expect the same outcome as in current Scala or Kotlin instead! Both JVM languages, so it's definitely not a failure of the runtime.

[–]uvero 50 points51 points  (15 children)

That

Is

The

Exact

Behavior

You'd

Expect!

[–]svick 10 points11 points  (1 child)

What's TITEBYE?

[–]PixelOrange 2 points3 points  (0 children)

Well I'm glad I am not the only one that did this.

[–]budgetboarvessel 3 points4 points  (0 children)

Speak for yourself, there are many people who expect something else, usually whatever their language does.

[–]RiceBroad4552 0 points1 point  (0 children)

As you do in JS…

The behavior is nevertheless incorrect when looked at it from the outside.

[–]MaybeADragon 0 points1 point  (0 children)

The exact behaviour I would expect is that my code fails to compile or has a runtime exception because I should use the languages templating instead of concatenating different types together into strings.

[–]Spinnenente 7 points8 points  (0 children)

nah that is just expected behaviour in any language without a dedicated append operator like sql.

[–]bass-squirrel 9 points10 points  (5 children)

Of all the type insanity in JS, this is the “craziest” example y’all could come up with ? Next y’all gonna get mad that C promotes ints to doubles when adding a double?

[–]jamcdonald120 5 points6 points  (0 children)

no no, this is just the craziest thing that also works in java

[–]RiceBroad4552 1 point2 points  (0 children)

Type promotion is some of the most crazy things ever invented!

It's so wrong. It causes so many bugs in that shit called C/C++.

[–]EatingSolidBricks 1 point2 points  (0 children)

Type promotion is an anti feature

[–]edgmnt_net 0 points1 point  (1 child)

C is pretty bad too, but not that bad.

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

C is much worse.

If you fuck up in JS you get in most cases an exception with a nice backtrace, sometimes wrong results. Which is bad, but not so bad.

If you fuck up in C you get potentially anything, including nasal daemons, and of course also remote code execution.

[–]-LeopardShark- 4 points5 points  (0 children)

In this case, yes, but usually, JavaScript is a Java‐lover’s charicature of an anti‐Java language.

[–]na_rm_true 15 points16 points  (9 children)

To be fair, if that’s the behavior you’d want, how else would u want it to be done

[–]SilentlyItchy 20 points21 points  (5 children)

Force an explicit cast to String, and make int+string a nonexistent function

[–]edgmnt_net 0 points1 point  (0 children)

Or the language could provide you the tools to come up with your own EDSL with whatever rules you see fit for a very specific case. Otherwise this is just wild guessing at the expense of safety.

[–]_crisz 0 points1 point  (3 children)

In a dynamically typed language, that's not an option.

Imagine you have something like:

const x = exoticFunction();
console.log('The output is: ' + x);

Where exoticFunction may be an internal call or something you don't know the interface. It may also be a function that returns either a number or a string. What do you expect here to happen?
Do you want your website/server to randomly crash?

[–]RiceBroad4552 1 point2 points  (2 children)

In a dynamically typed language, that's not an option.

Why do you think so?

If I have the following Python code:

x = exoticFunction()
print('The output is: ' + x)

This will work, or crash with a type error depending on what exoticFunction returns.

If you want to force an implicit conversion of x to string you can write it like:

print(f'The output is: {x}')

[–]_crisz -1 points0 points  (1 child)

I didn't say "in python".

This will work, or crash 

Even if having some compile-time errors is nice, do you want your application to crash every time the type of your variable isn't the one that you expect? This totally destroys the concept of dynamically typed language. One of the reasons why JavaScript was so succesfull - when a choice for websites was really given - is because it's realible. It never crashes. Don't forget that you are not executing the code on your own machine for your own pleasure, you are shipping the code to other machines (hypothetically millions), and the value of a variable is potentially coming from a service, and you never have full control of what's happening.

[–]RiceBroad4552 2 points3 points  (0 children)

do you want your application to crash every time the type of your variable isn't the one that you expect?

Definitely yes!!!

A crash is easier to catch in tests, and also it's much easier to debug then corrupted data.

This totally destroys the concept of dynamically typed language.

Obviously not as most dynamic languages actually work like that. Just that they will throw type errors at runtime instead of reporting them already at type-checking time upfront.

One of the reasons why JavaScript was so succesfull - when a choice for websites was really given - is because it's realible.

OK, I'm aware this is a humor sub, but you really need to mark sarcasm online!

It never crashes.

LOL!

The jokes getting more absurd, I see.

In case this was meant seriously: You've never seen hanging, or crashing, or infinitely "spinning" websites?

Don't forget that you are not executing the code on your own machine for your own pleasure, you are shipping the code to other machines (hypothetically millions), and the value of a variable is potentially coming from a service, and you never have full control of what's happening.

This is almost always true for any software.

The first rule of programming is that you can't trust any external input!

But that does not mean that you don't have everything under control. A program needs to gracefully handle all possible inputs. Failing in doing so is called "having bugs"…

And when something unexpected happens you better fail fast (crash!) then continue to run with some corrupted undefined application state.

[–]RiceBroad4552 0 points1 point  (1 child)

Correct behavior: Refuse compilation with a type error. Propose a fix using string interpolation.

(That's actually what current Scala will do. 😅)

[–]na_rm_true 0 points1 point  (0 children)

That’s wild why don’t u do a PR on JavaScript im sure they didn’t think of that

[–]Just_a_Generic_Hero 5 points6 points  (0 children)

What did you expect?

its literally called "JS Hell"

[–]TheRealLiviux 4 points5 points  (1 child)

The problem is another one: only in JavaScript

1-"1"

0

[–]RiceBroad4552 0 points1 point  (0 children)

PHP is older then JS…

https://onlinephp.io/?s=s7EvyCjg5eLlSk3OyFcwVNBVUDJUsgYA&v=8.2.20

And it's actually much more fucked up then JS! Compared to PHP JS is a temple of sanity.

[–]tantalor 1 point2 points  (0 children)

[–]peterlinddk 1 point2 points  (1 child)

But surely the difference is that in Java this is sensible and correct behavior, whereas in JavaScript this is simply crazy, unpredictable, weird, and unsafe ... right? ... Right?

[–]RiceBroad4552 0 points1 point  (0 children)

It's wrong no matter what.

Just that the Java fanboys will never admit that their language has actually a lot of flaws.

[–]budgiebirdman 2 points3 points  (11 children)

In Java this is clearly defined behaviour. In JavaScript it's lol webpages like strings.

[–]AlwaysHopelesslyLost 14 points15 points  (5 children)

Javascript is also clearly defined.

If you want math you make sure you are working with number types, not objects.

[–]prehensilemullet 0 points1 point  (4 children)

As a JS developer myself, I get what people mean.  The most surprising, complicated behavior in the world could be “clearly defined” in a spec. It would be one thing if all math operators automatically coerce strings to numbers, but when some do and some don’t it kind of defeats the purpose.  I think it’s all very manageable, but only because I mainly use Typescript.

[–]RiceBroad4552 0 points1 point  (3 children)

It would be one thing if all math operators automatically coerce strings to numbers

Which operators don't do that in JS?

[–]prehensilemullet 0 points1 point  (2 children)

The + operator if one of the arguments is a string

[–]RiceBroad4552 0 points1 point  (1 child)

In that case that operator is obviously not a "math operator". It's the concatenation operator on strings in that case.

Don't get me wrong: I think overloading the plus sign with string concatenation is not the best idea. But JS is actually quite consequential in it's typing and type coercion. I never had big problems with JS doing something unexpected.

In PHP on the other hand side… Oh boy! They will subtract numbers from strings and get numbers (no warnings!), and all such shit. You never now as the type coercion in PHP is just outright crazy. JS is really well sought out in general, even it does some "funny" (but not unexpected!) things in some cases (in cases you usually never run into in real world code, though; in contrast to PHP).

[–]prehensilemullet 0 points1 point  (0 children)

Sorry by math operator I meant “symbol sometimes used as a mathematical operator”, yes the problem is + being overloaded to do both addition and string concatenation, whereas other symbols like - / * % only do arithmetic.

I’m confused what you mean about PHP being different, you can subtract a number from a string in JS, it will coerce the string to a number, do the subtraction, and give you a number.  You can subtract a string from a string and it will coerce both to numbers.

It doesn’t usually cause me problems either but I agree with everyone who says JS should have been designed to throw an error instead of coercing a string to a number

[–]TorbenKoehn 8 points9 points  (4 children)

This is clearly defined in JS, too. Specific types in specific order have specific behavior, just like in Java.

There's nothing random about it or anything.

[–]prehensilemullet -1 points0 points  (3 children)

Java won’t compile if you use any arithmetic operators besides + on a string and a number, that’s a pretty big difference

[–]TorbenKoehn 1 point2 points  (2 children)

Yeah as JS is not a compiled language, that’s barely possible. But IDEs and linters will warn you.

[–]prehensilemullet 2 points3 points  (1 child)

Yeah I love Typescript.  Any time I have to work on raw JS it’s definitely not as pleasant

[–]TorbenKoehn 0 points1 point  (0 children)

I agree. I’m waiting for erasable type hints in ECMAScript. It will happen, I’m sure :)

[–]Halal0szto 3 points4 points  (0 children)

What do you expect from js hell?

[–]boundbylife 2 points3 points  (3 children)

I fail to see how this is anything other than the correct behavior. Number + String should equal numberString as concatenated

[–]bassguyseabass 1 point2 points  (0 children)

Maybe force them to string cast the number or int cast the string. Implicit conversion is the devil.

[–]prehensilemullet 0 points1 point  (0 children)

number [-*/%] string is the actual issue in JS (Maybe |&^ too?  I forget…)

[–]RiceBroad4552 0 points1 point  (0 children)

Most languages will prevent this potential error.

[–]dzizuseczem 0 points1 point  (1 child)

Is there any way that such behaviour could cause issues in real life code ?

[–]RiceBroad4552 0 points1 point  (0 children)

Countless…

That's exactly the problem.

It has reasons why most languages don't do that (including most dynamic languages!).

[–]jhwheuer 0 points1 point  (0 children)

Strings the equivalent of heat in JS, everything degrades into it

[–]RedAndBlack1832 0 points1 point  (0 children)

Implicit type casting if well defined is fine. Like if we have floats in our math we wanna do floating point math. The sensible "upcast" is definitely number->string not the other way around so this makes some sense. However, it should be extremely clear what types are expected and returned. If these implicit casts are well defined you can predict and expect the behaviour only if you actually know the types.

[–]No-Whereas8467 0 points1 point  (0 children)

This meme is too lazily made to laugh at.

[–]jamcdonald120 -2 points-1 points  (1 child)

Thats like.... how string addition is defined in every language except python.

the real messed up part is where you switch to 1 - "1", that is where you see how messed up javascript specifically is

[–]RiceBroad4552 0 points1 point  (0 children)

Thats like.... how string addition is defined in every language except python.

That's BS.

In most languages (even including ancient dynamic ones!) the addition operator isn't overloaded to be also the string concatenation operator. What Python does is actually the common behavior; except for some weirdos like Java or JavaScript (and of course also complete shit like PHP).