(try-except) conditional expression similar to (if-else) conditional (PEP 308)
I'm new to this list, so please excuse me if this topic has been discussed, but I didn't see anything similar in the archives. I very often want something like a try-except conditional expression similar to the if-else conditional. An example of the proposed syntax might be: x = float(string) except float('nan') or possibly x = float(string) except ValueError float('nan') Here's a simple example: Converting a large list of strings to floats where there may be errors that I want returned as nan's. Currently I would write the function: def safe_float_function(string): try: result = float(string) except: result = float('nan') return result and get my list of floats using the list comprehension: xs = [ safe_float_function(string) for string in strings ] With a try-except conditional I would instead define the following lambda: safe_float_conditional = lambda string : float(string) except float('nan') leading to: xs = [ safe_float_conditional(string) for string in strings ] My understanding is that the second would be faster at run time, and, like if-else conditional expressions, possibly more easily read by the human. Again, please excuse me if this has been discussed previously. If so, I'd appreciate being pointed to the discussion. Please also excuse me if for there is some currently (pre-python 3.0) idiom that I could use to efficiently get this same behaviour. If so, I'd appreciate being educated. Thanks, Jeff McAninch -- ========================== Jeffrey E. McAninch, PhD Physicist, X-2-IFD Los Alamos National Laboratory Phone: 505-667-0374 Email: mcaninch@lanl.gov ==========================
[Jeffrey E. McAninch, PhD]
I very often want something like a try-except conditional expression similar to the if-else conditional.
An example of the proposed syntax might be: x = float(string) except float('nan') or possibly x = float(string) except ValueError float('nan')
+1 I've long wanted something like this. One possible spelling is: x = float(string) except ValueError else float('nan') If accepted, this would also solve the feature requests for various functions to have default arguments. For example: x = min(seq) except ValueError else 0 # default to zero for empty sequences It would also be helpful in calculations that have algebraic restrictions: sample_std_deviation = sqrt(sum(x - mu for x in seq) / (len(seq)-1)) except ZeroDivisionError else float('Inf') Raymond
At 05:59 PM 8/5/2009 -0700, Raymond Hettinger wrote:
[Jeffrey E. McAninch, PhD]
I very often want something like a try-except conditional expression similar to the if-else conditional.
An example of the proposed syntax might be: x = float(string) except float('nan') or possibly x = float(string) except ValueError float('nan')
+1 I've long wanted something like this. One possible spelling is:
x = float(string) except ValueError else float('nan')
I think 'as' would be better than 'else', since 'else' has a different meaning in try/except statements, e.g.: x = float(string) except ValueError, TypeError as float('nan') Of course, this is a different meaning of 'as', too, but it's not "as" contradictory, IMO... ;-)
P.J. Eby wrote:
At 05:59 PM 8/5/2009 -0700, Raymond Hettinger wrote:
[Jeffrey E. McAninch, PhD]
I very often want something like a try-except conditional expression similar to the if-else conditional.
An example of the proposed syntax might be: x = float(string) except float('nan') or possibly x = float(string) except ValueError float('nan')
+1 I've long wanted something like this. One possible spelling is:
x = float(string) except ValueError else float('nan')
I think 'as' would be better than 'else', since 'else' has a different meaning in try/except statements, e.g.:
x = float(string) except ValueError, TypeError as float('nan')
Of course, this is a different meaning of 'as', too, but it's not "as" contradictory, IMO... ;-)
(We're probably well into python-ideas territory at this point, but I'll keep things where the thread started for now) The basic idea appears sound to me as well. I suspect finding an acceptable syntax is going to be the sticking point. Breaking the problem down, we have three things we want to separate: 1. The expression that may raise the exception 2. The expression defining the exceptions to be caught 3. The expression to be used if the exception actually is caught
From there it is possible to come up with all sorts of variants.
Option 1: Change the relative order of the clauses by putting the exception definition last: x = float(string) except float('nan') if ValueError op(float(string) except float('nan') if ValueError) I actually like this one (that's why I listed it first). It gets the clauses out of order relative to the statement, but the meaning still seems pretty obvious to me. Option 2: Follow the lamba model and allow a colon inside this form of expression: x = float(string) except ValueError: float('nan') op(float(string) except ValueError: float('nan')) This has the virtue of closely matching the statement syntax, but embedding colons inside expressions is somewhat ugly. Yes, lambda already does it, but lambda can hardly be put forward as a paragon of beauty. Option 3a/3b: Raymond's except-else suggestion: x = float(string) except ValueError else float('nan') op(float(string) except ValueError else float('nan')) This has the problem of inverting the sense of the else clause relative to the statement form (where the else clause is executed only if no exception occurs) A couple of extra keywords would get the sense correct again, but I'm not sure the parser could cope with it and it is rather verbose (I much prefer option 1 to this idea): x = float(string) if not except ValueError else float('nan') op(float(string) if not except ValueError else float('nan')) Option 4: PJE's except-as suggestion: x = float(string) except ValueError as float('nan') op(float(string) except ValueError as float('nan')) Given that we now use "except ValueError as ex" in exception statements, the above strikes me a really confusing idea. Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia ---------------------------------------------------------------
On Thu, Aug 6, 2009 at 4:47 AM, Nick Coghlan<ncoghlan@gmail.com> wrote:
Option 2: x = float(string) except ValueError: float('nan') op(float(string) except ValueError: float('nan'))
This has the virtue of closely matching the statement syntax, but embedding colons inside expressions is somewhat ugly. Yes, lambda already does it, but lambda can hardly be put forward as a paragon of beauty.
+1 on this option as it resembles the standard try/except block enough it would be a quick edit to convert it to one if later you realize you need to catch more exceptions* * I recommend NOT allowing multiple exceptions in this form eg x = float(string)/var except ValueError, ZeroDivisionError, ...: float('nan') as it will start to reduce readability quickly
Nick Coghlan wrote:
P.J. Eby wrote:
At 05:59 PM 8/5/2009 -0700, Raymond Hettinger wrote:
[Jeffrey E. McAninch, PhD]
I very often want something like a try-except conditional expression similar to the if-else conditional.
An example of the proposed syntax might be: x = float(string) except float('nan') or possibly x = float(string) except ValueError float('nan') +1 I've long wanted something like this. One possible spelling is:
x = float(string) except ValueError else float('nan') I think 'as' would be better than 'else', since 'else' has a different meaning in try/except statements, e.g.:
x = float(string) except ValueError, TypeError as float('nan')
Of course, this is a different meaning of 'as', too, but it's not "as" contradictory, IMO... ;-)
(We're probably well into python-ideas territory at this point, but I'll keep things where the thread started for now)
The basic idea appears sound to me as well. I suspect finding an acceptable syntax is going to be the sticking point.
Breaking the problem down, we have three things we want to separate:
1. The expression that may raise the exception 2. The expression defining the exceptions to be caught 3. The expression to be used if the exception actually is caught
From there it is possible to come up with all sorts of variants.
Option 1:
Change the relative order of the clauses by putting the exception definition last:
x = float(string) except float('nan') if ValueError op(float(string) except float('nan') if ValueError)
I actually like this one (that's why I listed it first). It gets the clauses out of order relative to the statement, but the meaning still seems pretty obvious to me.
A further extension (if we need it): result = foo(arg) except float('inf') if ZeroDivisionError else float('nan') The 'else' part handles any other exceptions (not necessarily a good idea!). or: result = foo(arg) except float('inf') if ZeroDivisionError else float('nan') if ValueError Handles a number of different exceptions.
Option 2:
Follow the lamba model and allow a colon inside this form of expression:
x = float(string) except ValueError: float('nan') op(float(string) except ValueError: float('nan'))
This has the virtue of closely matching the statement syntax, but embedding colons inside expressions is somewhat ugly. Yes, lambda already does it, but lambda can hardly be put forward as a paragon of beauty.
A colon is also used in a dict literal.
Option 3a/3b:
Raymond's except-else suggestion:
x = float(string) except ValueError else float('nan') op(float(string) except ValueError else float('nan'))
[snip] -1
Nick Coghlan wrote:
Option 1:
Change the relative order of the clauses by putting the exception definition last:
x = float(string) except float('nan') if ValueError op(float(string) except float('nan') if ValueError)
I actually like this one (that's why I listed it first). It gets the clauses out of order relative to the statement, but the meaning still seems pretty obvious to me.
Since I don't know the parser coding, I won't comment on the relative implentability (implementableness?) of the syntax options that Nick, P.J. and Raymond suggested. But all seem readable and debugable. Nick's option 1 seems like it might be the most understandable to a Python novice. Would the full syntax include multiple Exceptions after the "if"? Jeff -- ========================== Jeffrey E. McAninch, PhD Physicist, X-2-IFD Los Alamos National Laboratory Phone: 505-667-0374 Email: mcaninch@lanl.gov ==========================
On option 1 is this legal then? x = float(string) except float('nan') if some_check() else float('inf') if ValueError -----Original Message----- From: python-dev-bounces+dinov=microsoft.com@python.org [mailto:python-dev-bounces+dinov=microsoft.com@python.org] On Behalf Of Nick Coghlan Sent: Thursday, August 06, 2009 3:48 AM To: P.J. Eby Cc: python-dev@python.org; Jeff McAninch Subject: Re: [Python-Dev] (try-except) conditional expression similar to (if-else) conditional (PEP 308) P.J. Eby wrote:
At 05:59 PM 8/5/2009 -0700, Raymond Hettinger wrote:
[Jeffrey E. McAninch, PhD]
I very often want something like a try-except conditional expression similar to the if-else conditional.
An example of the proposed syntax might be: x = float(string) except float('nan') or possibly x = float(string) except ValueError float('nan')
+1 I've long wanted something like this. One possible spelling is:
x = float(string) except ValueError else float('nan')
I think 'as' would be better than 'else', since 'else' has a different meaning in try/except statements, e.g.:
x = float(string) except ValueError, TypeError as float('nan')
Of course, this is a different meaning of 'as', too, but it's not "as" contradictory, IMO... ;-)
(We're probably well into python-ideas territory at this point, but I'll keep things where the thread started for now) The basic idea appears sound to me as well. I suspect finding an acceptable syntax is going to be the sticking point. Breaking the problem down, we have three things we want to separate: 1. The expression that may raise the exception 2. The expression defining the exceptions to be caught 3. The expression to be used if the exception actually is caught
From there it is possible to come up with all sorts of variants.
Option 1: Change the relative order of the clauses by putting the exception definition last: x = float(string) except float('nan') if ValueError op(float(string) except float('nan') if ValueError) I actually like this one (that's why I listed it first). It gets the clauses out of order relative to the statement, but the meaning still seems pretty obvious to me. Option 2: Follow the lamba model and allow a colon inside this form of expression: x = float(string) except ValueError: float('nan') op(float(string) except ValueError: float('nan')) This has the virtue of closely matching the statement syntax, but embedding colons inside expressions is somewhat ugly. Yes, lambda already does it, but lambda can hardly be put forward as a paragon of beauty. Option 3a/3b: Raymond's except-else suggestion: x = float(string) except ValueError else float('nan') op(float(string) except ValueError else float('nan')) This has the problem of inverting the sense of the else clause relative to the statement form (where the else clause is executed only if no exception occurs) A couple of extra keywords would get the sense correct again, but I'm not sure the parser could cope with it and it is rather verbose (I much prefer option 1 to this idea): x = float(string) if not except ValueError else float('nan') op(float(string) if not except ValueError else float('nan')) Option 4: PJE's except-as suggestion: x = float(string) except ValueError as float('nan') op(float(string) except ValueError as float('nan')) Given that we now use "except ValueError as ex" in exception statements, the above strikes me a really confusing idea. Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia --------------------------------------------------------------- _______________________________________________ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/dinov%40microsoft.com
Dino Viehland wrote:
On option 1 is this legal then?
x = float(string) except float('nan') if some_check() else float('inf') if ValueError
Well, is this is legal? try: x = float(string) except some_check(): x = float('nan') except ValueError: x = float('inf') In other words, some_check() returns an exception _class_.
def get_exception(): return ValueError
try: x = float("") except get_exception(): print "not a float"
not a float
MRAB wrote:
Dino Viehland wrote:
On option 1 is this legal then?
x = float(string) except float('nan') if some_check() else float('inf') if ValueError
Well, is this is legal?
try: x = float(string) except some_check(): x = float('nan') except ValueError: x = float('inf')
I was thinking this was would be equal to: x = float(string) except (float('nan') if some_check() else float('inf')) if ValueError
Dino Viehland wrote:
MRAB wrote:
Dino Viehland wrote:
On option 1 is this legal then?
x = float(string) except float('nan') if some_check() else float('inf') if ValueError Well, is this is legal?
try: x = float(string) except some_check(): x = float('nan') except ValueError: x = float('inf')
I was thinking this was would be equal to:
x = float(string) except (float('nan') if some_check() else float('inf')) if ValueError
I suppose it depends on the precedence of 'x except y if z' vs 'x if y else y'.
Should be legal, right?, since syntax would be <expression> except <expression> if <exception> Dino Viehland wrote:
On option 1 is this legal then?
x = float(string) except float('nan') if some_check() else float('inf') if ValueError
Thinking more about the syntax options: if P.J.'s "if" Option is used, it should also be optional. That is, I would want this to also be legal, <expression> except <expression> to trap any exception when robustness is more important than catching a specific exception. What would be the typical next step in trying to put this forward? A draft PEP? -- ========================== Jeffrey E. McAninch, PhD Physicist, X-2-IFD Los Alamos National Laboratory Phone: 505-667-0374 Email: mcaninch@lanl.gov ==========================
Jeff McAninch wrote:
Should be legal, right?, since syntax would be <expression> except <expression> if <exception>
Dino Viehland wrote:
On option 1 is this legal then?
x = float(string) except float('nan') if some_check() else float('inf') if ValueError
Thinking more about the syntax options: if P.J.'s "if" Option is used, it should also be optional. That is, I would want this to also be legal, <expression> except <expression> to trap any exception when robustness is more important than catching a specific exception.
Catch all exceptions: <expression> except <expression> Catch specific exceptions, optionally catching all others: <expression> except (<expression> if <exception>)+ [else <expression>] Of course, a catch-all is a bare except, with all its dangers!
What would be the typical next step in trying to put this forward? A draft PEP?
I figure I would write up the PEP draft, I have never tried writing a pep before, but i did read PEP 1 and tried to follow it's formating guides. If there are no additions to the idea, then it seems there just needs to be a consensus on the syntax before submitting it to the peps list I posted this to the python-ideas version of this thread already, but since more people seem to be posting to the python-dev list I will post it here as well PEP: <pep number> Title: try-except conditional expressions Version: <svn version string> Last-Modified: <svn date string> Author: Jeff McAninch <mcaninch@lanl.gov>, Dj Gilcrease <digitalxero@gmail.com> Discussions-To: python-ideas@python.org Status: Draft Type: Standards Track Content-Type: text/plain Created: 06-Aug-2009 Python-Version: 2.7/3.2 Post-History: <dates of postings to python-list and python-dev> Abstract: I very often want something like a try-except conditional expression similar to the if-else conditional instead of resorting to a multi-line try-except block. Design Goals: The new syntax should * Be simple to read * Be intuitive so people who may use it infrequently dont need to go lookup the format every time * Make it obvious what is happening Modivation: Often when doing calculations or string recasting (to int, float, etc) it is required to wrap the section in a simple try-except where the exception just assigns a default value. It would be more readable and consise if these type of try-excepts could be written on a single line. Issues: Unknown Specification: All 3 components would just be ordinary expressions. The exception definition would be allowed to resolve to a single exception or a tuple of exceptions, just as it is in a normal try/except statement. Syntax Ideas: Option 1: x = float(string) except float('nan') if ValueError op(float(string) except float('nan') if ValueError) Option 2: x = float(string) except ValueError: float('nan') op(float(string) except ValueError: float('nan')) Option 3: x = float(string) except ValueError else float('nan') op(float(string) except ValueError else float('nan'))
On Tue, 11 Aug 2009 12:29:32 am Dj Gilcrease wrote:
I figure I would write up the PEP draft, I have never tried writing a pep before, but i did read PEP 1 and tried to follow it's formating guides. If there are no additions to the idea, then it seems there just needs to be a consensus on the syntax before submitting it to the peps list
Shouldn't there be consensus on whether or not this is a good idea first? [...]
Modivation
Motivation.
Often when doing calculations or string recasting (to int, float, etc) it is required to wrap the section in a simple try-except where the exception just assigns a default value. It would be more readable and consise if these type of try-excepts could be written on a single line.
Concise (note spelling) certainly, but I question that it would be more readable. Newlines are not a bad thing, but trying to squeeze too much into a single line is. When the `x if y else z` expression was first introduced, I was very excited because I thought it would be very useful. But I soon found that it actually wasn't that useful to me: it was rare that I wanted it, and when I did, it was usually more readable to use an `if` block instead. So I don't find this proposal the least bit compelling. It seems to me to be primarily useful for saving wear and tear on the Enter key.
Syntax Ideas: Option 1: x = float(string) except float('nan') if ValueError op(float(string) except float('nan') if ValueError)
Looks too confusingly like an if test. I find my eye drawn to the final clause, `if ValueError`, and expecting that to evaluate to true. -1
Option 2: x = float(string) except ValueError: float('nan') op(float(string) except ValueError: float('nan'))
[bike-shedding] At the risk of an extra keyword, I would prefer `unless` instead of `except`. [/bike-shedding] I find this the least worst of the alternatives. -0
Option 3: x = float(string) except ValueError else float('nan') op(float(string) except ValueError else float('nan'))
Also looks confusingly like an if test, but not as strongly as Option 1. -0.5 Should the PEP allow expressions like this? func(obj) except str(e) if ValueError as e # Option 1 func(obj) except ValueError as e: str(e) # Option 2 func(obj) except ValueError as e else str(e) # Option 3 Justify your choice please. -- Steven D'Aprano
Raymond Hettinger wrote:
If accepted, this would also solve the feature requests for various functions to have default arguments. For example:
x = min(seq) except ValueError else 0 # default to zero for empty sequences
It would also be helpful in calculations that have algebraic restrictions:
sample_std_deviation = sqrt(sum(x - mu for x in seq) / (len(seq)-1)) except ZeroDivisionError else float('Inf')
Raymond Yes, exactly the situations I keep coding around.
-- ========================== Jeffrey E. McAninch, PhD Physicist, X-2-IFD Los Alamos National Laboratory Phone: 505-667-0374 Email: mcaninch@lanl.gov ==========================
Raymond Hettinger <python <at> rcn.com> writes:
For example:
x = min(seq) except ValueError else 0 # default to zero for empty
sequences How about: x = min(seq) if seq else 0 Shorter and more readable ("except X else Y" isn't very logical).
sample_std_deviation = sqrt(sum(x - mu for x in seq) / (len(seq)-1)) except ZeroDivisionError else float('Inf')
Same transformation here. I have to say that the original example: x = float(string) except ValueError else float('nan') looks artificial. I don't see how it's adequate behaviour to return a NaN when presented with a string which doesn't represent a float number. Besides, all this is python-ideas material (and has probably already been proposed before). Regards Antoine.
On 6 Aug 2009, at 00:22 , Jeff McAninch wrote:
I'm new to this list, so please excuse me if this topic has been discussed, but I didn't see anything similar in the archives.
I very often want something like a try-except conditional expression similar to the if-else conditional. I fear this idea is soon going to extend to all compound statements one by one.
Wouldn't it be smarter to fix the issue once and for all by looking into making Python's compound statements (or even all statements without restrictions) expressions that can return values in the first place? Now I don't know if it's actually possible, but if it is the problem becomes solved not just for try:except: (and twice so for if:else:) but also for while:, for: (though that one's already served pretty well by comprehensions) and with:.
In article <D28975E8-6706-4515-9C9E-FB7F90775CA5@masklinn.net>, Xavier Morel <catch-all@masklinn.net> wrote:
On 6 Aug 2009, at 00:22 , Jeff McAninch wrote:
I'm new to this list, so please excuse me if this topic has been discussed, but I didn't see anything similar in the archives.
I very often want something like a try-except conditional expression similar to the if-else conditional. I fear this idea is soon going to extend to all compound statements one by one.
Wouldn't it be smarter to fix the issue once and for all by looking into making Python's compound statements (or even all statements without restrictions) expressions that can return values in the first place? Now I don't know if it's actually possible, but if it is the problem becomes solved not just for try:except: (and twice so for if:else:) but also for while:, for: (though that one's already served pretty well by comprehensions) and with:.
I like this idea a lot. -- Russell
Russell E. Owen wrote:
In article <D28975E8-6706-4515-9C9E-FB7F90775CA5@masklinn.net>, Xavier Morel <catch-all@masklinn.net> wrote:
On 6 Aug 2009, at 00:22 , Jeff McAninch wrote:
I'm new to this list, so please excuse me if this topic has been discussed, but I didn't see anything similar in the archives.
I very often want something like a try-except conditional expression similar to the if-else conditional. I fear this idea is soon going to extend to all compound statements one by one.
Wouldn't it be smarter to fix the issue once and for all by looking into making Python's compound statements (or even all statements without restrictions) expressions that can return values in the first place? Now I don't know if it's actually possible, but if it is the problem becomes solved not just for try:except: (and twice so for if:else:) but also for while:, for: (though that one's already served pretty well by comprehensions) and with:.
I like this idea a lot.
For some reason this kind of reminds me of BCPL. A function definition looked like: LET func_name(arg1, arg2) = expression so, strictly speaking, no multiline functions. However, there was also the VALOF ... RESULTIS ... block. In Python, the 'return' statement provides the result of a function; in BCPL, the 'RESULTIS' statement provided the result of the VALOF block, which was call from within an expression, like: LET foo(...) = VALOF $( ... RESULTIS expression $)
Unless I am very much mistaken, this is the approach Ruby takes. Everything is an expression. For example, the value of a block is the value of The last expression in the block. I've never understood the need to have a distinction betwen statements and expressions, not when expressions can have side effects. It's like that differentce between procedures and functions in pascal that only serves to confuse K
-----Original Message----- From: python-dev-bounces+kristjan=ccpgames.com@python.org [mailto:python-dev-bounces+kristjan=ccpgames.com@python.org] On Behalf Of Xavier Morel Sent: 6. ágúst 2009 10:25 To: python-dev@python.org Subject: Re: [Python-Dev] (try-except) conditional expression similar to (if-else) conditional (PEP 308)
Wouldn't it be smarter to fix the issue once and for all by looking into making Python's compound statements (or even all statements without restrictions) expressions that can return values in the first place? Now I don't know if it's actually possible, but if it is the problem becomes solved not just for try:except: (and twice so for if:else:) but also for while:, for: (though that one's already served pretty well by comprehensions) and with:.
I believe people now discuss this both on python-dev and python-ideas, though since I'm new to both lists, I can't really tell where this belongs. I played a little with this syntax, my try_ function and @catch decorator (which are at http://mit.edu/~unknot/www/try_cond.py): # x = float(string) except float('nan') if ValueError x = try_(float, string, except_ = float('nan'), if_ = ValueError) @catch(ValueError = float('nan')) def x1(): return float(string) # y = float(string) except ValueError: float('nan') y = try_(float, string, { ValueError: float('nan') }) @catch({ValueError: float('nan')}) def y1(): return float(string) # try: # z = open(string, 'r') # except IOError as e: # if e.errno == 2: # z = 'not_exist' # else: # raise # z = try_(open, string, 'r', iocatcher({2: 'no file!'})) @catch(iocatcher({2: 'nothing!'})) def z1(): return open(string, 'r') Here are my overall feelings: (1) it would be interesting to come up with syntax for except/if clause, but it's not obvious how to make one and this fact itself may kill the idea. (2) the more reasonable approach to things like this is by defining a separate block and then performing a "catch" operation with it. Unfortunately, this looks very clumsy as currently this can only be done by defining a separate function. I think code blocks are a good direction to explore. 2009/8/7 Kristján Valur Jónsson <kristjan@ccpgames.com>:
Unless I am very much mistaken, this is the approach Ruby takes. Everything is an expression. For example, the value of a block is the value of The last expression in the block.
I've never understood the need to have a distinction betwen statements and expressions, not when expressions can have side effects. It's like that differentce between procedures and functions in pascal that only serves to confuse
K
-----Original Message----- From: python-dev-bounces+kristjan=ccpgames.com@python.org [mailto:python-dev-bounces+kristjan=ccpgames.com@python.org] On Behalf Of Xavier Morel Sent: 6. ágúst 2009 10:25 To: python-dev@python.org Subject: Re: [Python-Dev] (try-except) conditional expression similar to (if-else) conditional (PEP 308)
Wouldn't it be smarter to fix the issue once and for all by looking into making Python's compound statements (or even all statements without restrictions) expressions that can return values in the first place? Now I don't know if it's actually possible, but if it is the problem becomes solved not just for try:except: (and twice so for if:else:) but also for while:, for: (though that one's already served pretty well by comprehensions) and with:.
_______________________________________________ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/ilya.nikokoshev%40gmail.co...
-- http://www.ironpythoninaction.com On 7 Aug 2009, at 12:06, ilya <ilya.nikokoshev@gmail.com> wrote:
I believe people now discuss this both on python-dev and python-ideas, though since I'm new to both lists, I can't really tell where this belongs.
It definitely belongs on the ideas list... Michael
I played a little with this syntax, my try_ function and @catch decorator (which are at http://mit.edu/~unknot/www/try_cond.py):
# x = float(string) except float('nan') if ValueError x = try_(float, string, except_ = float('nan'), if_ = ValueError)
@catch(ValueError = float('nan')) def x1(): return float(string)
# y = float(string) except ValueError: float('nan') y = try_(float, string, { ValueError: float('nan') })
@catch({ValueError: float('nan')}) def y1(): return float(string)
# try: # z = open(string, 'r') # except IOError as e: # if e.errno == 2: # z = 'not_exist' # else: # raise # z = try_(open, string, 'r', iocatcher({2: 'no file!'}))
@catch(iocatcher({2: 'nothing!'})) def z1(): return open(string, 'r')
Here are my overall feelings:
(1) it would be interesting to come up with syntax for except/if clause, but it's not obvious how to make one and this fact itself may kill the idea. (2) the more reasonable approach to things like this is by defining a separate block and then performing a "catch" operation with it. Unfortunately, this looks very clumsy as currently this can only be done by defining a separate function. I think code blocks are a good direction to explore.
2009/8/7 Kristján Valur Jónsson <kristjan@ccpgames.com>:
Unless I am very much mistaken, this is the approach Ruby takes. Everything is an expression. For example, the value of a block is the value of The last expression in the block.
I've never understood the need to have a distinction betwen statements and expressions, not when expressions can have side effects. It's like that differentce between procedures and functions in pascal that only serves to confuse
K
-----Original Message----- From: python-dev-bounces+kristjan=ccpgames.com@python.org [mailto:python-dev-bounces+kristjan=ccpgames.com@python.org] On Behalf Of Xavier Morel Sent: 6. ágúst 2009 10:25 To: python-dev@python.org Subject: Re: [Python-Dev] (try-except) conditional expression similar to (if-else) conditional (PEP 308)
Wouldn't it be smarter to fix the issue once and for all by looking into making Python's compound statements (or even all statements without restrictions) expressions that can return values in the first place? Now I don't know if it's actually possible, but if it is the problem becomes solved not just for try:except: (and twice so for if:else:) but also for while:, for: (though that one's already served pretty well by comprehensions) and with:.
_______________________________________________ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/ilya.nikokoshev%40gmail.co...
_______________________________________________ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/fuzzyman%40voidspace.org.u...
2009/8/7 Kristján Valur Jónsson <kristjan@ccpgames.com>:
Unless I am very much mistaken, this is the approach Ruby takes. Everything is an expression. For example, the value of a block is the value of The last expression in the block.
I've never understood the need to have a distinction betwen statements and expressions, not when expressions can have side effects. It's like that differentce between procedures and functions in pascal that only serves to confuse
If you're interested in understanding it better, research Query-Command Separation (QCS), e.g. starting at http://en.wikipedia.org/wiki/Command-query_separation and links therefrom. Alex
On Fri, 7 Aug 2009 08:22:14 pm Kristján Valur Jónsson wrote:
Unless I am very much mistaken, this is the approach Ruby takes. Everything is an expression. For example, the value of a block is the value of The last expression in the block.
Copying what other languages do is not necessarily a bad thing, but that would fail both "explicit is better than implicit" and "in the face of ambiguity, avoid the temptation to guess". It's not immediately obvious to me why the last expression should be given that privileged rule. Why not the first expression?
I've never understood the need to have a distinction betwen statements and expressions, not when expressions can have side effects. It's like that differentce between procedures and functions in pascal that only serves to confuse
Its been a while, but I don't think it ever confused me. Being unable to return multiple values, *that* confused me, but the distinction between "procedures are for doing something, functions are for getting something back" was perfectly straight-forward. (And then Pascal went and made it slightly more confusing by adding var parameters, so you could get results back from a procedure and have side-effects in a function... oh well.) -- Steven D'Aprano
On 8 Aug 2009, at 08:02 , Steven D'Aprano wrote:
On Fri, 7 Aug 2009 08:22:14 pm Kristján Valur Jónsson wrote:
Unless I am very much mistaken, this is the approach Ruby takes. Everything is an expression. For example, the value of a block is the value of The last expression in the block.
Copying what other languages do is not necessarily a bad thing, but that would fail both "explicit is better than implicit" and "in the face of ambiguity, avoid the temptation to guess". The first objection one might be able to give, you maybe, but the second one? Where's the ambiguity in "compound statements return the result of the last evaluated expression"?
It's not immediately obvious to me why the last expression should be given that privileged rule. Why not the first expression?
Because it wouldn't make any sense? When you're computing something, the value you want is the one at the end of the computation (usually called a result), not some random one somewhere else.
Steven D'Aprano writes:
It's not immediately obvious to me why the last expression should be given that privileged rule. Why not the first expression?
Or the second, for that matter. So find a large body of Lisp code and run "grep -r prog1 | wc", "grep -r prog2 | wc", and "grep -r progn | wc" on it. I think the pragmatic answer will be obvious. Personally, I like functional languages and style. But I admit the *need* for a progn construct (ie, "block") to express procedural style, and see no particular reason why expressing that by making a syntactic distinction between expressions and statements is worse (or better) than the progn construct. That should be kept distinct from the question of whether extended assignment operators or conditional operators are appropriate for a given language.
Jeff McAninch wrote:
I very often want something like a try-except conditional expression similar to the if-else conditional.
I think it may be done currently with the help of next function: def guard(func, *args): try: return func() except Exception, e: for exc_type, exc_func in args: if isinstance(e, exc_type): return exc_func() raise Example usage: a, b, c = 10, 20, 0 result = a + b/c # raise ZeroDivisionError result = a + guard(lambda: b/c, (TypeError, lambda: 10), (ZeroDivisionError, lambda: b/2)) May be not very concise, but it works... -- Best regards, Alexander mailto:alexander.kozlovsky@gmail.com
participants (17)
-
Alex Martelli
-
Alexander Kozlovsky
-
Antoine Pitrou
-
Dino Viehland
-
Dj Gilcrease
-
ilya
-
Jeff McAninch
-
Kristján Valur Jónsson
-
Michael Foord
-
MRAB
-
Nick Coghlan
-
P.J. Eby
-
Raymond Hettinger
-
Russell E. Owen
-
Stephen J. Turnbull
-
Steven D'Aprano
-
Xavier Morel