This is a discussion on Python’s forums about adding something akin to a throws keyword in python.

  • twoframesperminute
    link
    fedilink
    01 year ago

    @sugar_in_your_tea Since when is Python supposed to equal pseudo code? It should be easily readable, but that doesn’t mean it should *equal* pseudo code.

    You can either test for values being 0 before dividing, or catching an exception when it is. Especially when dividing multiple times in one function, I would go for the latter option.

    • @[email protected]
      link
      fedilink
      11 year ago

      It’s not an explicit design goal, but it explains a lot of the Zen of Python and other pushback on PIPs, so to me it’s always been an unwritten design goal (be as close to pseudocode as practical, but no closer). It’s also how I generally write code (start with Python “pseudocode,” then decide what to use in production).

      For example, from the Zen of Python:

      There should be one-- and preferably only one --obvious way to do it.

      Being clever in Python is a bad thing, just as it is in pseudocode. Python will never win awards for performance, so if you need that, you drop in something non-Python to do the expensive operations to keep the rest of the code clean and obvious.

      If you think of Python as pseudocode, everything else makes a ton more sense.

      You can test for values being 0 before dividing, or catching an exception when it is.

      Ideally, you just test for input variables outside of the function and do neither. Something like:

      def calc(x, y):
          assert x > 0
          assert y != 0
          ...
      

      This throw exceptions if the preconditions fail, but those can (and should) be removed for production since their primary purpose is to inform the developer of the preconditions and catch mistakes in development. In production, you’d rely on some kind of schema validation to ensure the asserts never trigger (I’m partial to Pydantic).

      So ideally you’d never expect a divide by zero or clutter your code with zero checks outside of those asserts (which shouldn’t be relied on) because you’ve already prevented those cases from happening.

      • twoframesperminute
        link
        fedilink
        01 year ago

        @sugar_in_your_tea Using asserts in any code except testing is frowned upon, afaik. You should use specific exceptions instead of vague unlabeled assertion errors.

        You also seem to think that you’re not allowed to use exception to communicate the fact a check failed. If that’s the case, you’re seriously underusing the power of exceptions.

        It sounds a lot to me like you don’t even want to use Python or think it shouldn’t be used for anything serious. Why then even argue about it?

        • @[email protected]
          link
          fedilink
          11 year ago

          Assertion errors should never fire, they’re merely there for documentation and catching mistakes in development. Any assertion is merely a sanity check (the value should’ve been checked before calling the function), which is why they’re disabled in production.

          In fact, I conceptually like the way D makes checking preconditions and postconditions explicit. However, it’s clunky in practice imo, so asserts are usually elegant enough. I honestly only use asserts when it’s the clearest way to document the usage constraints.

          you’re seriously underusing the power of exceptions

          No, I use them for communicating data errors and whatnot and have a bunch of custom exceptions in my code. It’s the current Pythonic way, so that’s what I do.

          However, I don’t like that pattern and find it to either hide errors or clutter my code. I much prefer the Rust style of error handling where errors are always acknowledged when they can happen, but usually handled at a higher level (like you’d do in Python, but with explicit syntax to acknowledge a call could error). I find this gives me, the programmer, a chance to consider the error case to correct logical mistakes before actually running any code, and it also improves code reviews because it’s obvious to the reviewer that the code could error. I’ve had far too many bugs caused by not knowing or forgetting a call could raise an error.

          you don’t even want to use Python

          When did I say that? I use it at my day job and actually argued against using Rust for our project because Python maps really well to our problem domain. Our project is hundreds of thousands of lines of Python across a dozen or more microservices, and it has served us well.

          Criticizing a language doesn’t necessarily mean I don’t like it, it just means I think it could be better. Python is generally my first choice unless I know I need top performance and correctness out of the gate. For example, I’m writing a distributed lemmy competitor in Rust in my free time for various reasons (mostly I don’t want to deal with Python installers, and there’s no server component), and also building a game in Godot in GDScript (very similar to Python, even worse in perf). There are very few languages I actively dislike.

          That said, in general, I prefer functional-style programming, and exceptions are one glaring wart that makes FP in Python feel bad. I want that to be better.

    • twoframesperminute
      link
      fedilink
      01 year ago

      @sugar_in_your_tea I don’t think we should change any functionality when it comes to exception handling. Code based documentation would be great for type checking and auto-generated docs, but they can be done using annotations, not changed interfaces.

      Monads are already possible, but should not be the normal way to code either. It’s clunky and difficult to understand. It might work great for some scenarios, but doesn’t for many others.

      • @[email protected]
        link
        fedilink
        11 year ago

        Monads are only clunky because Python doesn’t really support them.

        And I agree, I don’t think we should change existing exception handling, just allow the programmer to interact with it differently. I’d love to be able to turn exceptions into monads with a little bit of syntax. Under the hood, Python would still do the try/except, but my code would use exceptions as values instead. You’d still be able to use the older try/except explicitly just like you can express a list comprehension as a generator manually, you’d just have the option to do something else if it’s cleaner in your project.

        That said, exceptions as values isn’t a hill I’m willing to die on, but I will push against “throws” being added, and optional chaining is a hill I’m willing to die on.