On Tue, 29 Mar 2016 10:31 pm, BartC wrote: > On 29/03/2016 09:26, Steven D'Aprano wrote: >> On Monday 28 March 2016 12:40, Paul Rubin wrote: > > >> The point is that there's nothing intrinsically obvious or right about >> "return the value of the last statement in the block". > > But that's exactly what happens inside a typical function: you have > linear sequence of statements, then you a have return statement: at the > end. It's a common pattern.
But return is an *explicit* exit. And not all languages work that way. {My Pascal syntax may be a bit rusty...} function demo(int x): int; begin demo := x + 1; {sets the return value} writeln('x has the value', x); writeln('returning now...'); end; [...] >> An expression naturally and intrinsically should return the value the >> expression calculates. This is such a no-brainer that I feel stupid even >> writing it: "x+1" should return "x+1". It would be crazy to pick >> something else. > > (This is in contradiction to what you say elsewhere, where: > > graph + node > > may be procedural.) Not at all. With operator overloading, the plus operator + ends up as a method call __add__ or __radd__. This method call can have side-effects, and it can return anything it likes, including None. That return value can be ignored, but it is still the return value of the expression: graph + node # returns None, use this expression for the side-effects only Just like print(a, b, c) returns None, and we use if for the side-effects. It's still an expression ("call the print function with these arguments"), it does something (prints) and then returns None. >> But a statement is a statement because it doesn't have a return value. > > Isn't an expression technically a statement in Python? I mean statements which are not legal expressions, like: del x import module from module import name for x in seq: block while condition: block try ... except ... else ... finally etc. I'm sorry that I wasn't pedantic enough to specify "statements (apart from expressions)" each time I contrasted statements and expressions. Can you possibly forgive me for my informal use of language? > Therefore a > statement could have a value. But take this example: > > if cond1: x=a1 > elif cond2: x=a2 > elif cond3: x=a3 > else: x=a4 > > Clearly this would be better expressed as (not valid Python): > > x = if cond1: a1 > elif cond2: a2 > elif cond3: a3 > else: a4 x = a1 if cond1 else a2 if cond2 else a3 if cond3 else a4 We can split it over multiple lines too: x = ( a1 if cond1 else a2 if cond2 else a3 if cond3 else a4 ) > (Actually 'del is a rather odd language feature. And I can't figure out > how it's implemented; how does it manage 'del x[i]'? Anyway that's > another matter.) del x[i] calls x.__delitem__(i) >> True if that allowed the value to be garbage >> collected, False if it wasn't? Or the other way around? None of these >> suggests feel either useful or obviously right. > > It doesn't need to give a useful value. Hence my suggestion that all statements (apart from expressions) return 42. > Its 'value' lies in being able to have it in a sequence or block: > > z = del x; y In a hypothetical Python where `del x` returns None, that would set z to None and then evaluate y, doing nothing with the result. -- Steven -- https://mail.python.org/mailman/listinfo/python-list