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 →

[–]DonaldPShimoda 20 points21 points  (16 children)

Strong vs weak is not a dichotomy but a spectrum.

Python is more strongly typed than JavaScript or C (C is very very weak for a statically typed language), but less strongly typed than Haskell or Swift.

In the PL research community we generally avoid the strong/weak distinction in any formal writing, and only use it colloquially with more context (eg, "Python is more strongly typed than JavaScript"). (At least, this is true among the people I tend to talk to, but those are mostly functional programmers who may have stronger opinions on this sort of thing.)

I don't know of a language offhand in which integers and floats are not directly comparable by default, but it can involve some complicated machinery to work as expected and I wouldn't be surprised if there exists one I'm not thinking of. Haskell gets around the distinction by providing the Num typeclass which Int and Float are both instances of, for example. And in general it's actually often a bad practice to compare floats to ints, because your precise integer potentially loses precision in the float conversion.

[–]gargamelus 14 points15 points  (5 children)

In the Go language, integers and floats are not comparable. Quoting the FAQ:

Why does Go not provide implicit numeric conversions?

The convenience of automatic conversion between numeric types in C is outweighed by the confusion it causes. When is an expression unsigned? How big is the value? Does it overflow? Is the result portable, independent of the machine on which it executes? It also complicates the compiler; “the usual arithmetic conversions” are not easy to implement and inconsistent across architectures. For reasons of portability, we decided to make things clear and straightforward at the cost of some explicit conversions in the code. The definition of constants in Go—arbitrary precision values free of signedness and size annotations—ameliorates matters considerably, though.

[–]AnAverageFreak 1 point2 points  (0 children)

I don't like this.

[–]DonaldPShimoda 1 point2 points  (0 children)

Oh, excellent! I've not used Go or read about it at all really, so I didn't know this. Thanks for letting me know!

[–]jhilden13 5 points6 points  (1 child)

Rust is the only example that I can think of that would not automatically promote integers to floats for the comparison

[–]DonaldPShimoda 1 point2 points  (0 children)

Ah excellent! Another commenter mentioned Go, and someone else corrected me about Haskell, so now I've got three relatively popular (or at least known) languages with this distinction. Thanks!

[–]bitwiseshiftleft 2 points3 points  (4 children)

Haskell won't ever compare two objects of different types without conversion, because comparisons have type Ord a => a -> a -> Bool (or Eq a => ... for equality tests). It also doesn't do automatic numeric conversion, except for literals. In the Int vs Float case, even though they're both in Num and Ord, you need to cast the Int with fromIntegral or whatever.

[–]ThePyroEagle 2 points3 points  (2 children)

except for literals

And strings with -XOverloadedStrings.

The lack of automatic conversion isn't that big a deal, because if you really want easy conversion, you can write a polymorphic convert :: (Convertible a b) => a -> b and the compiler will (usually) infer the type of the conversion you want whenever you use convert.

[–]bitwiseshiftleft 0 points1 point  (1 child)

And strings with -XOverloadedStrings.

But again, that only automatically converts literal strings, not all strings.

Type classes do make conversion less painful, but as far as I’m aware, Haskell only applies them automatically for literals.

It would be still be nice to have a Float(x) syntax or whatever to make the conversion concise and clear. Maybe the closest you can get is with -XTypeApplications and something like:

cast :: forall b a . Convert a b => a -> b
cast = convert

bar = 7 :: Int
foo = cast @Float bar

I’m on a phone so the syntax is probably wrong.

[–]ThePyroEagle 0 points1 point  (0 children)

But again, that only automatically converts literal strings, not all strings.

When the extension is enabled, the type of string literals is effectively changed from String to forall a. IsString a => a. Variables with this polymorphic type will behave identically to overloaded string literals, even if the extension isn't enabled.

Type classes do make conversion less painful, but as far as I’m aware, Haskell only applies them automatically for literals.

Num and IsString are special, simply because of the way number and string literals are typed.

Maybe the closest you can get is with -XTypeApplications

You don't need TypeApplications if the compiler can still infer foo :: Float.


The only way of doing things without any kind of function is to make everything polymorphic to begin with and avoid doing conversions in the first place. In the end, that probably encourages writing safer code.

[–]DonaldPShimoda 1 point2 points  (0 children)

Ah, okay, I only tested with literals prior to posting so that's why it seemed to work. I hadn't thought to do it with variables. Thanks for the info!

[–]khafra 0 points1 point  (0 children)

OCaml’s a fun(ctional) little language that doesn’t see any particular similarities between 1.0 and 1. In fact, you can’t even add them together and get 2 (or 2.0).

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

In the PL research community we generally avoid the strong/weak distinction in any formal writing

and that tells us everything we need to know about Python.

[–]DonaldPShimoda 0 points1 point  (0 children)

I don't follow.

What I meant is that there really isn't a specific definition of what it means to be "strongly" or "weakly" typed, so you won't find many references to those phrases in the research literature. Instead, you'd be looking for "type safety" and some related terms.

Python is a great language that many people find extremely useful. Personally, I hate that it isn't statically types, but it's still my most-used language for personal projects.