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/

Reply via email to