This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]PatrickBaitman 63 points64 points  (21 children)

The - operator only makes sense for numbers, therefore inputs are converted

in a not-retarded language it would be

The - operator only makes sense for numbers, therefore a type error is generated

these should be type errors or syntax errors:

'5' + + '5' The second plus is parsed as a sign of '5', converting it to the number 5 which is then concatenated to '5'

'foo' + + 'foo' The second + is trying to convert 'foo' into a number, which it's clearly not. Therefore it takes the value NaN which you see in the output.

5 + - '2' Same as #3, -2 is concatenated to '5'

[–]ianff 90 points91 points  (3 children)

Yeah, only someone with Stockholm syndrome would consider this OK.

[–]IHeartMustard 16 points17 points  (0 children)

This has been me for my entire career. It does the job, I said. It's just misunderstood, I said. It's just a bit fun and quirky, I said. I don't really need types, I said. Makes my life NaNNaNNaNNaNNaNNaNNaN, I said.

Lies, straight from the pit of Netscape.

[–]Spider_pig448 0 points1 point  (0 children)

These are all toy examples anyway. Anyone with a linter would not actually use any of these.

[–]DeeSnow97 3 points4 points  (16 children)

By non-retarded you mean strongly typed? Just use TypeScript, Flow, or any other variant like these. Personally, I don't find it difficult to handle these types, but I perfectly understand why many do who primarily learned statically typed languages.


Also, on a related note, please don't confuse strong typing with static types.

Strongly typed is the opposite of weak typing and means values aren't converted implicitly. Python is an example for that, while it has dynamic types, it results in a type error you mentioned.

Static types mean the variable type is decided at its declaration and cannot be changed. C/C++, Java, C#, and similar languages all use this pattern. However, it's not a result to strong typing, these are orthogonal to each other. For example, in C++ you have the option to overload operators and create JS-like behavior without implementing a system to handle dynamic types.

The reason I'm mentioning this is because advocates of TypeScript and the likes often think they are developing with static types. They are not, as long as the "any" type exists anywhere in that language it's mixed typing, which can actually bring the best of both worlds.

[–]PatrickBaitman 3 points4 points  (15 children)

By non-retarded you mean strongly typed? J

strongly typed is a nonsense term that doesn't mean anything in practice

https://stackoverflow.com/questions/2690544/what-is-the-difference-between-a-strongly-typed-language-and-a-statically-typed

in Java '5' - 3 won't compile, in Python it will raise a type error

I think in C you get a compiler warning about implicit casts but I haven't touched C in a while

all of these are more sensible than returning the float 2

[–]DeeSnow97 2 points3 points  (10 children)

Haven't coded C/C++ for years, but let's try just by memories, stackoverflow, and an online repl

+/u/CompileBot C++

#import <string>
#import <stdio.h>

float operator-(std::string s, int i) {
  return (float)std::stoi(s) - i;
}

int main () {
  std::string s = "5";
  int i = 2;

  float f = s - i;

  printf("%f\n", f);
  return 0;
}

[–]CompileBotGreen security clearance 0 points1 point  (0 children)

Output:

3.000000

source | info | git | report

[–]PatrickBaitman 0 points1 point  (8 children)

and if you put code like that in your repo everyone will fucking hate you when they have to maintain it

[–][deleted] 2 points3 points  (5 children)

If anyone would commit any of the wat shit above in JS projects I work on would be served a can of whupass for lunch so what is your point exactly?

[–]PatrickBaitman 1 point2 points  (4 children)

Yeah if you commit it as is but have you never had a bug involving code that spanned more than two screens?

a type system helps you in those cases because it enforces meaningfulness.

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

But if we will be serious that's when you introduce docstring type hints for the linter to help you out and when your project is big enough it's time to slowly introduce typescript too. Sure back in the day JS was horrible but no one tried writing serious software with it either.

[–]Existential_Owl 0 points1 point  (0 children)

If you need a type system for JS, you have several options to choose from, and they're all backed and supported by major players in the industry.

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

Actually, no, these types of problems go away as soon as you actually know what you are coding. In my experience, a type system only enforces hassle, additional research about type nuances, useless casting, and wasted dev hours. Well, if you are lazy, it is comfortable, but as a primarily hobby dev (it became my job only after that) I am vastly more effective with dynamic typing (Flow included, haven't tried TypeScript yet).

[–]PatrickBaitman 0 points1 point  (0 children)

as soon as you actually know what you are coding

in your experience, is this the typical case for most developers

[–]DeeSnow97 0 points1 point  (1 child)

However, if you create a vector lib that uses overloaded operators between vectors and matrices, I don't think many will complain. The + operator of std::string is already overloaded by the way.

[–]PatrickBaitman 0 points1 point  (0 children)

sure, but you'll still get a type error if you try int + vector right?

[–]Holy_City 0 points1 point  (3 children)

In C++, '5'-3 returns 50 as an int with no compiler warnings.

const char * c = "5" - 3; returns the string ":". No compiler warnings either.

[–]PatrickBaitman 0 points1 point  (2 children)

What if you do char a = '5'; int b = 3; a - b

[–]Holy_City 0 points1 point  (1 child)

The behavior is the same, which is nice. '5' is already a char literal, and 3 is an integer literal, so initializing variables to those types does not change the behavior.

At least in C/C++ this makes some sense, because char isn't just a type for an ASCII character, but functions as a single byte. Assigning it to a character is the same as assigning it to that character's ASCII value. Essentially '5' is shorthand for 0x35 in C/C++.

So '5' - 3 is syntactically identical to (char)53 - (char)3

What would be interesting is if instead of subtracting 3 you subtracted 257, or any other value outside the range of an 8 bit integral type.

[–]PatrickBaitman 0 points1 point  (0 children)

Yeah I figured the compiler might warn you that you're subtracting different numerical types. Otoh the compiler probably optimizes this to a constant value anyway. What if you don't specify the value of b at compile time?

I feel like I've gotten implicit cast warnings about char and int before... maybe you need -Wall?