https://docs.python.org/3/faq/design.html#how-fast-are-exceptions :
""" A try/except block is extremely efficient if no exceptions are raised. Actually catching an exception is expensive. In versions of Python prior to 2.0 it was common to use this idiom: try: value = mydict[key] except KeyError: mydict[key] = getvalue(key) value = mydict[key] This only made sense when you expected the dict to have the key almost all the time. If that wasn’t the case, you coded it like this: if key in mydict: value = mydict[key] else: value = mydict[key] = getvalue(key) For this specific case, you could also use value = dict.setdefault(key, getvalue(key)), but only if the getvalue() call is cheap enough because it is evaluated in all cases. """ And then the next FAQ is "Why isn’t there a switch or case statement in Python?" https://docs.python.org/3/faq/design.html#why-isn-t-there-a-switch-or-case-statement-in-python - [ ] DOC: Which should probably be updated to mention the new Structural Pattern Matching PEP 622 and 634 "PEP 622 -- Structural Pattern Matching" https://www.python.org/dev/peps/pep-0622/ "PEP 634 -- Structural Pattern Matching: Specification" https://www.python.org/dev/peps/pep-0634/ Are there docs for patten matching (the match and case keywords) yet? Which PEPs explain the rationale for doing away with string exceptions? ... https://en.m.wikipedia.org/wiki/Message_passing lists programming languages that include message passing as a core language feature and also links to the actor model (which is usually applied for concurrent applications) https://en.wikipedia.org/wiki/Message_passing#Message-passing_versus_calling Are Exceptions slower because they carry a traceback reference to a stack frame? Why else are Exceptions slower than conditionals and/or structural pattern matching? ( FWIU, pykka is similar to the Akka actor model framework and predates the new structural pattern matching functionality https://www.pykka.org/en/latest/quickstart/#rules-of-the-actor-model ) On Tue, Oct 13, 2020, 9:25 PM Steven D'Aprano <st...@pearwood.info> wrote: > On Tue, Oct 13, 2020 at 02:08:11PM -0000, jmwar...@gmail.com wrote: > > > I am not particularly concerned with performance here. I am more > > worried about code clarity, boilerplate that de-incentivizes a feature > > and hidden values. > > Okay. > > > The current exception mechanism encourages passing, > > effectively, un-named lists of parameters or building boilerplate to > > create the equivalent of named tuples (e.args[0] or building an > > __init__ that defines members). > > I don't agree that it *encourages* that, more that it allows it. > > I'd like to see the typical use you make of exceptions. For me, almost > without exception (pun intended) the exception is intended for three > purposes: > > 1. A human-readable error message: > > # expecting a prime number, but didn't receive one > raise ValueError('argument is not a prime number') > > > 2. A low-resolution mechanism for re-trying or suppressing errors: > > for number in numbers: > try: > process(number) # May raise ValueError > except ValueError: > print("skipping non-prime") > > > 3. A simple protocol for returning an out-of-bounds state flag, in the > way StopIteration is used. > > (Number 3 is technically a form of flow-control, but in practice the way > it is used is quite simple.) > > For those three purposes, I think exceptions are fine. But you seem to > be using exceptions as some sort of dispatch mechanism. > > > > If the only value is the name, why not > > just define it where you use it instead of creating an intermediary > > class definition? > > > > I use string literals for state names all the time > > instead of creating objects and importing them all over my code > > because most of the time the mental overhead of imports and the like > > isn't worth the ease and clarity of just passing a string. > > I don't see that this situation is relevant. Your exception handling > code seems to make use of a lot of internal state: you store variables > as exception attributes, then extract them later. While I guess you > could do that with strings: > > string = f'{spam}; {eggs}; {cheese}; {aardvark}' > # later on... > spam, eggs, cheese, aardvar = string.split(';') > > I'm guessing you don't. But that's what you're doing with the > exceptions: you store a bunch of values into the exception object, then > raise the exception, only to *immediately* catch it again, retrieve > those same values, and use them. Why not just use the values directly? > > (Based on your earlier pseudo-code example. Perhaps real code is > different.) > > > [...] > > I mentally do think of this as just a convoluted function call > > passing control. > > I try to avoid convoluted code of any description. Sometimes I fail, but > I don't do it intentionally. > > > > When you make that mentality switch then the current > > mechanism starts looking either obfuscated or bloated for the reasons > > I said above (passing anonymous lists of parameters, e.args, or adding > > extra code and defining an object just to pass named parameters). > > Doesn't that suggest to you that maybe you are using the wrong tool for > the job, or using it badly? If serving soup with a carving knife > requires you to create an obfuscated, bloated, convoluted framework, > perhaps you would be better off using a ladle like everyone else :-) > > I do look forward to seeing a more realistic example of what you are > doing, because from the pseudo-code you supplied earlier, it looks like > an obfuscated, bloated, convoluted way of doing something that is simple > if you just don't use exceptions. > > > > I guess what I am _really_ suggesting here is more of a named return > > that passes to the first block capable of handling it. That's really > > what exceptions are conceptually doing, just make it more explicit. > > Hmmm, are you thinking of message-passing mechanisms? > > Your description sounds like Hypertalk and other XTalk programming > languages, such as Apple's Hypercard in the 1990s. To call a function, > you would send a message to another widget. If that widget could handle > it, it would execute the appropriate message handler. If not, the > message would fall through to the next level of the message-handling > hierarchy: > > > widget > card > background > window > application > interpreter > > > In Hypercard this was based on a GUI framework, but the principle > doesn't just apply to GUIs. I think that the Actor model of computation > is similar. > > > -- > Steve > _______________________________________________ > Python-ideas mailing list -- python-ideas@python.org > To unsubscribe send an email to python-ideas-le...@python.org > https://mail.python.org/mailman3/lists/python-ideas.python.org/ > Message archived at > https://mail.python.org/archives/list/python-ideas@python.org/message/XCQEZ3P3DZUTR7PL6RFWR36I6FHX4A5Y/ > Code of Conduct: http://python.org/psf/codeofconduct/ >
_______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/OPJD5YCJSGZODUDRMBPKMYTFL6AMA3VT/ Code of Conduct: http://python.org/psf/codeofconduct/