
On Sat, Feb 22, 2014 at 1:03 AM, Eli Bendersky <eliben@gmail.com> wrote:
Chris, while I also commend you for the comprehensive PEP, I'm -1 on the proposal, for two main reasons:
1. Many proposals suggest new syntax to gain some succinctness. Each has to be judged for its own merits, and in this case IMHO the cons eclipse the pros. I don't think this will save a lot of code in a typical well-structured program - maybe a few lines out of hundreds. On the other hand, it adds yet another syntax to remember and understand, which is not the Pythonic way.
It doesn't need to save a huge number of lines. Just like lambda and the if/else expression, it's there as a tool - if it makes your code easier to read, it's a good too, and if it makes it harder, then don't use it. Yes, it's more to learn, but so is the proliferation of ad-hoc alternatives, several of which are listed in the 'Motivation' section at the top.
2. Worse, this idea subverts exceptions to control flow, which is not only un-Pythonic but also against the accepted practices of programming in general. Here, the comparison to PEP 308 is misguided. PEP 308, whatever syntax it adds, still remains within the domain of normal control flow. PEP 463, OTOH, makes it deliberately easy to make exceptions part of non-exceptional code, encouraging very bad programming practices.
Again, I point to the current alternatives, including: * dict[key] -> dict.get(key, default) * min(sequence) -> min(sequence, default=default), as of 3.4 Both offer a way to either get an exception back or use a (usually constant) default value. In each case, the author of the class/function had to cater to the fact that some callers might want it to not raise an exception. The alternative is to always use the full try/except block, which leads to questions like "How can I keep going after an exception?" with code like this: try: spam = d["spam"] ham = d["ham"] eggs = d["eggs"] sausage = d["sausage"] except KeyError: thing_that_failed = "" The dict class offers a way to avoid the exception here, by showing that it's non-exceptional: spam = d.get("spam","") ham = d.get("ham","") eggs = d.get("eggs","") sausage = d.get("sausage","") But not everything does. Writing that with just exception handling looks like this: try: spam = d["spam"] except KeyError: span = "" try: ham = d["ham"] except KeyError: ham = "" try: eggs = d["eggs"] except KeyError: eggs = "" try: sausage = d["sausage"] except KeyError: sausage = "" with extreme likelihood of an error - do you see what I got wrong there? With inline exception handling, d could be a custom class that simply defines [...] to raise KeyError on unknowns, and the code can be written thus: spam = d["spam"] except KeyError: "" ham = d["ham"] except KeyError: "" eggs = d["eggs"] except KeyError: "" sausage = d["sausage"] except KeyError: "" It's still a bit repetitive, but that's hard to avoid. And it puts the exception handling at the exact point where it stops being exceptional and starts being normal - exactly as the try/except statement should. ChrisA