Aren't checked exceptions in Java generally regarded as a bad mistake?
Python
Welcome to the Python community on the programming.dev Lemmy instance!
π Events
Past
November 2023
- PyCon Ireland 2023, 11-12th
- PyData Tel Aviv 2023 14th
October 2023
- PyConES Canarias 2023, 6-8th
- DjangoCon US 2023, 16-20th (!django π¬)
July 2023
- PyDelhi Meetup, 2nd
- PyCon Israel, 4-5th
- DFW Pythoneers, 6th
- Django Girls Abraka, 6-7th
- SciPy 2023 10-16th, Austin
- IndyPy, 11th
- Leipzig Python User Group, 11th
- Austin Python, 12th
- EuroPython 2023, 17-23rd
- Austin Python: Evening of Coding, 18th
- PyHEP.dev 2023 - "Python in HEP" Developer's Workshop, 25th
August 2023
- PyLadies Dublin, 15th
- EuroSciPy 2023, 14-18th
September 2023
- PyData Amsterdam, 14-16th
- PyCon UK, 22nd - 25th
π Python project:
- Python
- Documentation
- News & Blog
- Python Planet blog aggregator
π Python Community:
- #python IRC for general questions
- #python-dev IRC for CPython developers
- PySlackers Slack channel
- Python Discord server
- Python Weekly newsletters
- Mailing lists
- Forum
β¨ Python Ecosystem:
π Fediverse
Communities
- #python on Mastodon
- c/django on programming.dev
- c/pythorhead on lemmy.dbzer0.com
Projects
- PythΓΆrhead: a Python library for interacting with Lemmy
- Plemmy: a Python package for accessing the Lemmy API
- pylemmy pylemmy enables simple access to Lemmy's API with Python
- mastodon.py, a Python wrapper for the Mastodon API
Feeds
Yes, but not because the goal of having exceptions in types is bad, rather Java's type system isn't advanced enough to support the ideal solution here.
Scala 3 is working on experimental capture checking capabilities, which allows functions to express certain capabilities (file access, networking, db, etc.), and CanThrow capabilities (e.g exceptions at the type level) are one reification of this.
The CanThrow docs I linked have a good introduction into why Java checked exceptions are bad, and how Scala's alternative is far better. Essentially it comes down to a lack of polymorphism in checked exceptions. In practice this means they're incredibly verbose outside of simple usecases, and with a very easy escape hatch (RuntimeException), you don't even get the guarantee of knowing a function without checked exceptions doesn't throw.
Python will also have this latter issue. Python's "typing" in general has this issue actually. Types aren't validated unless you use an external tool, and even then Any
is a leaky abstraction that can hide any level of typing errors, unlike in properly typed languages where it's not leaky. You need it to be leaky in gradually typed environments, or you wouldn't be able to use a ton of the Python ecosystem, but this vastly reduces the effectiveness of the typing solution.
I don't know if Python's solution here will address the lack of polymorphism that Java's solution has, I'll have to look into it more.
I heard the same, but not sure why. Do you have a link?
When I used to write Java and switched to Python, this was one of the things I missed. It was always quite clear which exceptions I had to catch (or not). Just today, I ran into the issue of trying to cover the exceptions a library could throw without using except:
or except Exception as e
, but finally gave up and gave in to it. The linter wasn't happy, but fuck it.
I disagree, I'd instead like to move toward handling errors as logic, and keeping exceptions for actually exceptional cases. If you're expecting an exception, that's data.
So here's my proposal:
- introduce monads like Maybe/Result that forces the dev to handle expected errors in logic
- make an easy way to return errors early without interrupting logic flow
- simplify checking for None values in chaining
For the first (not exactly a monad, may need a new type to wrap things):
def maybe_err(val: int) -> Result[int, ValueError]:
if val < 0:
return ValueError("cannot be negative")
return val
match (val := maybe_err(-1)):
case int():
case ValueError():
For the second:
val = maybe_error(-1)? # special handling to return instances of Error early
And the third:
val = x?.y?.z ?? DEFAULT
I like this much better than having try/except blocks throughout the code, and reserve those only for logging and whatnot at the top level. If you document exceptions, people will use them even more as data instead of exceptions.
So only raise if you want it to bubble all the way up, return errors if it's just data for the caller. Libraries should almost never raise.
Anything but over9000 variations of nullables like in C#
I'm not too familiar with C# (last used it like a decade ago), but I think the rules here would be pretty simple:
- x? - if x is None or an Error, return from the function early, otherwise use the value and continue
- x?.y - same as above, but with an attribute of x
- x ?? y - instead of returning as in the first, use y as the default value
And maybe add an option to convert exceptions from a function to an Error value (maybe some_func?()
to convert to error values? IDK, I haven't thought through that part as much).
Hopefully that's simple enough to be useful.
If I were proposing this, I'd limit it to optional chaining since that's far more annoying to me currently.
My counter: let's throw Java into a pit
@Maoo @onlinepersona
That's unfair. Java did everyone a huge favour by giving a practical demonstration of why (mandatory) checked exceptions are awful.
Yeah, let's not. This is not a good idea