9 ms·
Truly one of the great python programming books. The one thing that I found missing was the lack of static typing in the code, but that was a deliberate decisio
by Pandabob 2y ago
Truly one of the great python programming books. The one thing that I found missing was the lack of static typing in the code, but that was a deliberate decision by the authors.
- sevensor 2y agoHaven’t read the book, so I don’t know exactly what position they’re taking there, but type checking has done more to improve my Python than any amount of architectural advice. How hard it is to type hint your code is a very good gauge of how hard it will be to understand it later.
- pmg101 2y agoMy experience is that once people have static typing to lean on they focus much less on the things that in my view are more crucial to building clean, readable code: good, consistent naming and small chunks. Just the visual clutter of adding type annotations can make the code flow less immediately clear and then due to broken windows syndrome people naturally care less and less about visual clarity.
- natdempk 2y agoSo 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 2y 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 2y 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 2y agoType annotations are just like documentation though. Just because the annotation says int the function can still return a list.
- maleldil 2y 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 2y 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 2y 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 2y 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 2y 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__ 2y 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 2y 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 2y 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 2y 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.
- globular-toast 2y agoYeah, people from statically typed languages sometimes can't understand how dynamically typed languages can even work. How can I do anything if I don't know what type to pass?! Because we write functions like "factorial(number)" instead of "int fac(int n)".
- xboxnolifes 2y agoI wish that's how python functions were written. What i usually see is `draw(**kwargs)`.
- Pandabob 2y agoYup! I'm also hopeful that the upcoming type-checker from Astral will be an improvement over Mypy. I've found that Mypy's error messages are sometimes hard to reason about. [0]: https://x.com/charliermarsh/status/1884651482009477368 https://x.com/charliermarsh/status/1884651482009477368
- dlisboa 2y ago> The one thing that I found missing was the lack of static typing in the code It has type hints, such as here: https://www.cosmicpython.com/book/chapter_08_events_and_message_bus.html https://www.cosmicpython.com/book/chapter_08_events_and_mess... Do you mean it's not strict enough? There are some parts of the book without them.
- zahlman 2y agoSome examples use dataclasses, which force type annotations. Python does not support static typing. Tooling based on type annotations doesn't affect the compilation process (unless you use metaprogramming, like dataclasses do) and cannot force Python to reject the code; it only offers diagnostics.