9 ms·
So far off from what actually happens. The type annotations provide an easy scaffolding for understand what the code does in detail when reading making code flo
by natdempk 1y ago
So far off from what actually happens. The type annotations provide an easy scaffolding for understand what the code does in detail when reading making code flow and logic less ambiguous. Reading Python functions in isolation, you might not even know what data/structure you’re getting as input… if there’s something that muddles up immediate clarity it’s ambiguity about what data code is operating on.
- sevensor 1y agoExactly my experience. I call Python a surprise-typed language. You might write a function assuming its input is a list, but then somebody passes it a string, you can iterate over it so the function returns something, but not what you would have expected, and things get deeply weird somewhere else in your codebase as a result. Surprise! Type checking on the other hand makes duck typing awesome. All the flexibility, none of the surprises.
- zahlman 1y agoThis is because of Python's special handling of iteration and subscripting for strings (so as to avoid having a separate character type), not because of the duck typing. In ordinary circumstances (e.g. unless you need to be careful about a base case for recursion - but that would cause a local fault and not "deep weirdness at a distance"), the result is completely intuitive (e.g. you ask it to add each element of a sequence to some other container, and it does exactly that), and I've written code that used these properties very intentionally. If you passed a string expecting it to be treated as an atomic value rather than as a sequence (i.e. you made a mistake and want a type checker to catch it for you), there are many other things you can do to avoid creating that expectation in the first place.
- tayo42 1y agoType annotations are just like documentation though. Just because the annotation says int the function can still return a list.
- maleldil 1y agoAnnotations can and should be checked. If I change a parameter type, other code using the function will now show errors. That won't happen with just documentation.
- tayo42 1y agoIn some cases don't you need to actually execute the code to know what the type actually is. How does the type checker know then?
- maleldil 1y agoIt doesn't. There are cases where the type-checker can't know the type (e.g. json.load has to return Any), but there are tools in the language to reduce how much that happens. If you commit to a fully strictly-typed codebase, it doesn't happen often.
- sevensor 1y agoYou can actually annotate the return type of json.load better than that: JSON = float | bool | int | str | None | list[“JSON”] | dict[str, “JSON”]
- pansa2 1y ago> Annotations can and should be checked Unfortunately Python’s type system is unsound. It’s possible to pass all the checks and yet still have a function annotated `int` that returns a `list`.
- __MatrixMan__ 1y agoDo you mean that you're allowed to only use types where you want to, which means maybe the type checker can't check in cases where you haven't hinted enough, or is there some problem with the type system itself?
- zahlman 1y ago>So far off from what actually happens I disagree strongly, based on 20 years of using Python without annotations and ~5 years of seeing people ask questions about how to do advanced things with types. And based on reading Python code, and comparing that to how I feel when reading code in any manifest-typed language. >Reading Python functions in isolation, you might not even know what data/structure you’re getting as input I'm concerned with what capabilities the input offers, not the name given to one particular implementation of that set of capabilities. If I have to think about it in any more detail than "`ducks` is an iterable of Ducklike" (n.b.: a code definition for an ABC need not actually exist; it would be dead code that just complicates method resolution) I'm trying to do too much in that function. If I have to care about whether the iterable is a list or a string (given that length-1 strings satisfy the ABC), I'm either trying to do the wrong thing or using the wrong language. > if there’s something that muddles up immediate clarity it’s ambiguity about what data code is operating on. There is no ambiguity. There is just disregard for things that don't actually matter, and designing to make sure that they indeed don't matter.
- pansa2 1y ago> using the wrong language IMO this is the source of much of the demand for type hints in Python. People don't want to write idiomatic Python, they want to write Java - but they're stuck using Python because of library availability or an existing Python codebase. So, they write Java-style code in Python. Most of the time this means heavy use of type hints and an overuse of class hierarchies (e.g. introducing abstract classes just to satisfy the type checker) - which in my experience leads to code that's twice as long as it should be. But recently I heard more extreme advice - someone recommended "write every function as a member of a class" and "put every class in its own file".
- sevensor 1y agoI’d say I use type hints to write Python that looks more like Ocaml. Class hierarchies shallow to nonexistent. Abundant use of sum types. Whenever possible using Sequence, Mapping, and Set rather than list, dict, or set. (As these interfaces don’t include mutation, even if the collection itself is mutable.) Honestly if you’re heavily invested in object oriented modeling in Python, you’re doing it wrong. What a headache.