jmwar...@gmail.com writes:

 > I am not particularly concerned with performance here. I am more
 > worried about code clarity, boilerplate that de-incentivizes a
 > feature and hidden values. 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).

You use a lot of deprecatory words that don't apply to any exception
handling code I've seen as far as I can tell.  Examples (preferably
from code that has been reviewed and revised and still is ugly) would
help a lot.

 > 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 might be interesting if you had a definition and offered use
cases.

For example, as a contrast with "named return", a couple of months
back there was a long discussion of "named breaks" (ie, breaking
multiple levels of nested loops, which can be implemented with
exceptions or flags and conditionals, but neither is very pretty).
The concept is well-defined by those two words, I think, but it fell
down and didn't get up because the use cases are scarce and the syntax
proposals were not copacetic.  A well-defined named return concept
might have legs because it sounds like it would be more powerful than
named break.

But I think of the command "return from stack frame" provided by many
debuggers when I see "named return".  I don't think you're talking
about that.  "Coming home to a place he'd never been before" is not a
return, not even a named one.  That is, catching an exception is not a
return to the place of "the" call in the control flow, it's a
non-local jump to independent code that happens to be lexically
adjacent to some try suite containing a parent call that descends to
calling the function containing the raise statement.

Note the ambiguity of the "the" in scare quotes above.  Also unlike
return, where normal flow of control resumes after *the* call point,
there's no presumption that the handler associated with this try will
ever "see" the exception: it could be "intercepted" by another try
statement in called code -- the exception mechanism is *designed* for
that.  In most of the code I work on, in fact, I desperately hope it
gets intercepted because if it gets to my function, I have to give up
-- the only thing I can do to help is to give up gracefully.

In some sense, this isn't fair to you, because I'm imposing my
understanding on your words.  My intent is to convey the cognitive
dissonance I feel reading your posts.

 > Exceptions however require definition in three places,

In the general case, four mentions.  See below.

 > the class, the call and the handler and the mechanism to pass
 > arguments is a bit convoluted (either un-named lists or manual
 > parameter assignment).

The argument-passing mechanism is the same as in any Python callable.
I don't understand what you think is convoluted about it.  The only
way I can understand it is that you have a conventional pattern of use
that you'd like to implement as Python syntax (ie, syntactic sugar),
but the only pattern I'm familiar with is

    raise SomeException('explanatory string', offending_object)

and even then, that exception object is accessed only very rarely
(except by top-level code that logs and/or prints it, and there the
simple structure of e.args usually makes "print(*e.args)" all you
need).  If I needed access to the context of the raise in the handler,

    class SomeExceptionWithContext(SomeException):
        def __init__(self, *args, **kwargs):
            self.args = args
            self.context = kwargs

    def foo():
        raise SomeExceptionWithContext('explanatory string',
                                       offending_object,
                                       a=a, b=b)

seems to be a nice-enough, lightweight-enough, quite general pattern
that would do what I need.  I write "seems" because I've never wanted,
let alone used, this construct.

It would help to have examples from actual programs of tangled-ball-
of-string code that a "function-like" exception creation and catching
mechanism would help straighten out.

 > Why not open up the simpler function like mechanism to exception
 > handling?

Because exceptions are frequently used to communicate across module
boundaries, I don't see how to avoid (as a practical minimum in the
general case) four mentions: definition and raise in one module, and
import and catch in another.  We could define abbreviated syntax for
common use cases, but what are those cases?  Adding syntax is a heavy
lift, and the define-or-import-class implementation has significant
readability and typo-checking benefits to me at least.

Regards,
_______________________________________________
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/M4VLVLV3BZG2U4CSIE5M7ZHGS63QNPY5/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to