4 ms·
Python is dynamically but strongly typed. “2+True” is a type error; once something has a type, it has a type. There’s no WAT.
by prionassembly 6y ago
Python is dynamically but strongly typed. “2+True” is a type error; once something has a type, it has a type. There’s no WAT.
- solosoyokaze 6y agoVariables can change type though. This is working python code: x = 1 y = 2 print(x + y) x = "no " y = "types" print(x + y) Whereas this will not even compile in Go: x := 1 y := 2 x = "no" y = "types"
- anaerobicover 6y agoThat's the difference between static and dynamic typing, not the difference between weak and strong. The values cannot be used as if they were another type.
- solosoyokaze 6y agoSo what's the type signature of `print()` then? I do think my example code demonstrates why Go is easier to reason at scale than Python. Python is conflating assignment and type declaration. Go has = and :=, so it's crystal clear what's going on.
- anaerobicover 6y ago> what's the type signature of `print()` then? Dynamic typing doesn't rule out polymorphism. void print(PyObject objects...) where `PyObject` is a base type. Additionally, you could perfectly well have constants, or require variables to have a fixed type, in a dynamic language. You would just pay a cost at runtime to check the type on assignment.
- solosoyokaze 6y agoI would argue that you pay the cost at runtime but you also pay a cognitive overhead cost while writing in a dynamically typed language. Refactoring in particular is a lot more difficult.
- dexterlemmer 6y agoI agree. But this particular example ironically has nothing to do with dynamic typing.
- dexterlemmer 6y ago> So what's the type signature of `print()` then? I like the way Rust makes clear what are the different possibilities: In Rust we use a macro to handle variadic arguments, but if it was just a case of supporting different types, not of supporting an arbitrary number of arguments we would've had three options for the type signature: 1. Monomorphic duck typing: `fn print(arg: &impl Debug)`. Here the compiler simply generates multiple print functions, one for every type the function gets called on. The exact concrete type is known at compile time. 2. Polymorphic dynamic dispatch (with dynamic sizing) duck typing: `fn print(arg: Box<dyn<Debug>>)`. Here the compiler generates a vtable and allocates on the heap. Only a type approximation is known at compile time, not the exact concrete type, but it still counts as static typing. 3. Dynamic typing: `fn print(arg: Box<dyn<Any>>)`. Note `Any` in stead of `Debug`. Full dynamic typing with the type completely unknown at compile time. Juck! But occasionally useful for prototyping or for FFI with dynamically typed languages.
- anaerobicover 6y ago> what's the type signature of `print()` then? Dynamic typing doesn't rule out polymorphism. void print(PyObject objects...) where `PyObject` is a base type.
- dexterlemmer 6y agoIt has nothing to do with the difference between strong and weak typing and also has nothing to do with the difference between weak and strong typing. It is about Python not disambiguating between variable shadowing and variable reassignment. Here's a comment of mine that explains why Python is weakly typed: https://news.ycombinator.com/item?id=26354039 https://news.ycombinator.com/item?id=26354039.
- dexterlemmer 6y agoThis has nothing to do with either dynamic or weak typing in Python. It's just Python not disambiguating between shadowing and reassignment. Here's a comment of mine that explains why Python is weakly typed: https://news.ycombinator.com/item?id=26354039 https://news.ycombinator.com/item?id=26354039.
- lhjn 6y agoBad example, booleans in python are integer subclasses since forever... 2 + True = 3. Also, False in [1, 2, 0] evaluated to True. But you're still right saying python is strongly typed.
- dexterlemmer 6y agoPython is more strongly typed than JS/Perl, granted. But it is still very weakly typed overall. Here are some examples: 1. if list(): pass # implicit coercion from collection -> None -> bool. (Very uncommon weak typing and a terrible idea.) 2. a = 123; b = 4.5; c = a + b # implicit coercion from int -> float (Common but not universal weak typing. More often hides bugs than helps with ergonomics and readability but sometimes a worthwhile tradeoff.) 3. a = 1 + false # implicit coercion from bool to int (Common weak typing in scientific languages (for masking) and older C-family languages (for bit twiddling). However, that's still bad language design. Libraries/syntax sugar should special case masking and bit twiddling. You should not have global coersion between bool and int.) 4. etc.