4 ms·
> Python does And it's awful. I use EAFP locally (to avoid TOCTOU and the like) at low level interfaces but I don't let it bubble up out of a function scope, b
by kortex 5y ago
> Python does
And it's awful. I use EAFP locally (to avoid TOCTOU and the like) at low level interfaces but I don't let it bubble up out of a function scope, because it is a goto in all but name.
I've also been increasingly using the `result` library/data structure. It's incredibly liberating to return an error as an object you can compose into other functions, vs try/catch, which does not compose.
Yes I write python almost like rust, and it's great. Strong types, interfaces, immutable types. It looks nothing like "old school python" but also behaves nothing like it. Gone are the day of "oh it crashed again, fix one line and rerun".
Exceptions should be for exceptional circumstances, not errors.
Edit: I see this is controversial. What do you take objection to? Making your python look less dynamic and more like rust? Try it before you knock it. Python's my favorite language, but I do not agree that many of the common "pythonic" patterns are good at scale.
https://returns.readthedocs.io/en/latest/pages/result.html https://returns.readthedocs.io/en/latest/pages/result.html
- eru 5y agoI find, that the problem with exceptions in Python is not so much that it is a goto, but that they are a bit like dynamic scoping (vs static scoping of variables), so you can not reason about them statically. An example: suppose you have a function that does some work with the filesystem, and also calls some user-supplied code. (Perhaps because the user can subclass something etc, or because you are getting a callback, the details don't matter.) Naturally your function might have some idea how to handle its own filesystem trouble, but you have no clue how to handle any filesystem exceptions that come from user provided code. It's rather awkward to get this exactly right.
- Karunamon 5y agoMaybe I'm just too inexperienced, but I don't see the point of this library. The linked example shows a really basic sqlalchemy model lookup. What does spewing these new types all over my code get me that returning None or an empty dict/list doesn't without the overhead? def find_user(user_id: int) -> Optional[User]: user = User.objects.filter(id=user_id) if user.exists(): return user[0] else: return None Not only is this idiomatic, it conveys the same semantic meaning. I'm using an IDE, as is anyone else working in a large codebase. I'll be told at the point of invocation that find_user could return None and I need to possibly deal with that.
- dragonwriter 5y ago> Not only is this idiomatic, it conveys the same semantic meaning No, it doesn’t. For a single computation like this, that pattern is roughly equivalent to Maybe (which contains no information about the case where there is no success result besides that it is absent) rather than Result (which has error information, kind of like an exception, but in the normal return path.) For a series of computations, the composability of both Maybe and Result means that they are semantically richer.
- Karunamon 5y agoCouldn't I just return a tuple instead if I wanted to give the caller information on the nature of the success or failure? Also, both Django and SQLAlchemy throw proper exceptions on bad queries or DB errors, which is probably the right thing to do in the average app using these libraries (the exception bubbles up, getting logged, returning the appropriate http error, etc). I'm not crapping on this library, mind, I just can't find the use case that justifies it.
- linkdd 5y agoIt's about function composition. How do you compose a function that returns an int or an error with a function that takes an int as parameter? Yes you can split this in multiple steps, or you can use monads to handle the composition for you, making you type less code, giving more information to the typesystem (mypy for python for example) about what is valid and what's not. This is a completely different programming style, it's functional programming, aka: "how to make functions by composing other functions".