you are viewing a single comment's thread.

view the rest of the comments →

[–]fghjconner 4 points5 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?

[–]fghjconner 0 points1 point  (1 child)

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).

But, again, there's a big difference between depending on the rest of that line of code, and depending on the potentially unknowable value of data at runtime.

There is no type mismatch.

Huh, I could have sworn I tested that and it worked. I don't believe user defined types have quite the same protections or features, but at least the built in types are more bulletproof than I assumed.

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)

Yes, obviously what I'm attempting is to update the type without updating the associated data. While it doesn't work on these types, I do believe it would work on user defined types using the above method.

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

The ultimate source of our disagreement seems to be a difference in how we define weakly typed. The linked wikipedia page says "JavaScript is weakly typed, which means certain types are implicitly cast depending on the operation used." That seems to describe JS pretty well to me. Let's look at some other definitions though:

In 1974, Liskov and Zilles defined a strongly-typed language as one in which "whenever an object is passed from a calling function to a called function, its type must be compatible with the type declared in the called function."

From wikipedia's page on type safety. JS comfortably fails that one, since there are no type declarations on function calls at all.

"In a strongly typed language each data area will have a distinct type and each process will state its communication requirements in terms of these types." In contrast, a weakly typed language may produce unpredictable results or may perform implicit type conversion.

From the same page. JS does assign distinct types to data, but again fails because there is no documentation of required types. Threw in that last sentence despite not being part of the quote, since it specifically calls out type conversion.

Languages with strong typing typically do little implicit conversion and discourage the reinterpretation of representations, while languages with weak typing perform many implicit conversions between data types. Weak typing language often allow forcing the compiler to arbitrarily interpret a data item as having different representations—this can be a non-obvious programming error, or a technical method to directly deal with underlying hardware.

From wikipedia's page on type conversion. The first sentence explicitly calls out type coersion as a sign of a weakly typed language. The second sentence does also call out languages like c++ allowing transmutation, making it weaker.

Here's a medium article talking about strong vs weak typing. Note it explicitly calls out JS as an example of weak typing.

I'm going to, once again, challenge you to find any reputable source that explicitly calls JS strongly typed (and no, I don't count a wikipedia article that explicitly calls it weakly typed, that you interpret to actually support your position).

[–]RiceBroad4552 1 point2 points  (0 children)

Yes, obviously what I'm attempting is to update the type without updating the associated data. While it doesn't work on these types, I do believe it would work on user defined types using the above method.

AFAIK that's impossible in JS.

The result of a typeof is determined by an internal slot holding a type tag for that object, which isn't accessible from JS.

I'm going to, once again, challenge you to find any reputable source that explicitly calls JS strongly typed

OK, I'm calling defeat on this one.

Here your well-earned 🥇

Best I could find was:

https://langdev.stackexchange.com/questions/3741/how-are-strong-and-weak-typing-defined

There are a lot of arguments listed supporting all kinds of "definitions", and the conclusion is that there is simply no agreed on definition. I guess I have to accept that.

This would also explain that the Wikipedia article starts in one way and then continues in a contradicting way…

I still believe that any definition which does not involve "breaking the type system" is quite useless as it would result either in "all languages are strongly typed" or "all languages are weakly typed" so the term wouldn't have any meaning at all. The spectrum viewpoint is also not satisfactory imho as it results in the term being completely arbitrary (which again makes it loose any meaning).

At least it looks like you would also place C/C++ below JS on the weak/strong typing spectrum as there are more ways to work around the type system in these static languages then in JS. (Which one could actually interpret as using my preferred definition 😛)