[Python-ideas] except expression

spir denis.spir at gmail.com
Thu Feb 13 19:30:08 CET 2014


On 02/12/2014 10:02 PM, Ram Rachum wrote:
> Hi,
>
> Here's an idea that would help shortening code. Allow a ternary expression
> based on except, like so:
>
>      first_entry = entries[0] except IndexError else None
>      item = my_queue.get() except queue.Empty else None
>      response_text = request('http://whatever.com').text except HttpError
> else "Can't access data"
>
> Aside from the fact that this would be a big grammar addition, a big
> problem here is the usage of the `else` keyword, that when used with except
> usually means "what would happen if there wasn't an exception" and here
> means the opposite. But I couldn't think of a nicer syntax.
>
> I realize that this is a big change and that most people would be opposed
> to this... But I guess I just wanted to share my idea :)

After some considerations, it seems we reached the point of generalising the 
idea to:
     * provide a builtin way to indicate a special value for the special cases where
       the standard value's expression would raise an exception
As Nick Coghlan shows in another post, this is in fact close to a builtin way to 
deal with potentially failing functions, in general (below 'op'):

     def _helper(op, exc, make_default):
         try:
             return op()
         except exc:
             return make_default()

     x = _helper(op, Exception, make_default)

However, this only applies to the case of functions properly speaking (which 
purpose is computing a product). What about 'actions', meaning procedures that 
perform an effect? Take the case of count-words for instance, where (in python) 
when encoutering a word one would add 1 to its count in a dict which keys are 
the words. On first encounter, there no entry yet for that word. We could check 
"word in word_counts", but this is doing the dict lookup twice; and catching an 
exception is worse.

The problem I guess, here and also similarly for functions, is that there is no 
way for the _client_ (the caller) to control exception throwing; while only the 
caller knows whether the failing case actually is an error or not, meaning 
belongs or not the application's logics. Maybe what we need is in fact something 
like:

	maybe statement
         [then
	    dependant-block]
	else
	    alternative-block

This is similar in form to exception catching except (sic!) that the actual 
meaning is to _avoid_ an exception, not to catch it (to avoid it beeing thrown 
at all). More or less the opposite, in fact. The consequence is that in case of 
failure no exception is raised, instead the alternative 'else' branch is taken. 
Such a construct would work fine for both called actions and functions (which 
calls are expressions in statement). [1]

[Similar considerations are evoked in other languages, especially D where I 
first met them. Generally speaking, people start to realise the seamntic 
weakness of typical exception catching mecanisms which let no choice or control 
in the hands of the one who actually knows, namely the client.]

d

[1] Practically, this just means adding a test before throwing, and setting a 
flag instead (the carry would do the job nicely, since it can have no meaning on 
func return, and is the only copy flag one can set arbitrarily).

Thus, the above code translates to:
	statement
	if flag:
	    reset flag
             alternative-block
         [else:
	    dependant-block]



More information about the Python-ideas mailing list