Statements as expressions [was Re: Undefined behaviour in C]
Steven D'Aprano
steve+comp.lang.python at pearwood.info
Tue Mar 29 04:26:14 EDT 2016
On Monday 28 March 2016 12:40, Paul Rubin wrote:
> Steven D'Aprano <steve at pearwood.info> writes:
>> if condition:
>> print(1)
>> print(2)
>> else:
>> print(3)
>> print(4)
>> what value should it return? Justify your choice.
>
> It could whatever value that the last call to print() returns. Lisp
> has worked like that since the 1950's.
"Lisp did it" isn't much of a justification.
The point is that sticking a return value onto a conditional branch with two
blocks is rather arbitrary. Why return the last value rather than the first?
Why not return a list of all the values generated in the block? Or
True/False depending on which branch was taken?
Or for that matter, a random number?
The point is that there's nothing intrinsically obvious or right about
"return the value of the last statement in the block".
>> What should be the return value of this statement?
>>
>> while True:
>> x += 1
>> if condition: break
>
> It could return None, or break(val) could return val.
Another arbitrary choice. It *could* return anything. But what *should* it
return?
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.
But a statement is a statement because it doesn't have a return value. To
give it one, we have to more-or-less arbitrarily force it to have one, but
that doesn't make it terribly natural.
del x
Should it return None? The string 'x'? How about the value that x had just
before it was deleted? 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.
>> I don't think that "every statement is an expression" is conceptually
>> simpler at all. I think it is more difficult to understand.
>
> It hasn't been a problem in Lisp or its descendants, Erlang, Haskell,
> etc. I don't know about Ruby or Javascript.
Maybe, maybe not. But certain statements, at least, are definitely a problem
in C/C++ :
int war = false; if(war = true) { launchnuke(); }
The way I see it, all expressions are meaningful as statements (although
possibly not terribly useful if they don't have side-effects) but not all
statements are meaningful as expressions.
If other languages choose differently, well, that's their right to do so,
but I don't agree with their choice. On the other hand, I am tempted by the
thought of a language where all statements return 42.
>> But it is even harder to understand what it might mean for a while
>> loop to be a value, and the benefit of doing so seems significantly
>> less than compelling.
>
> It means that you get to use an incredibly simple and beautiful
> evaluation model. Have you ever used Lisp or Scheme? Give it a try
> sometime. Excellent free book:
> https://mitpress.mit.edu/sicp/full-text/book/book.html
I've tried to get into Lisp a couple of times, and it doesn't speak to me.
If you want my opinion, Forth has a more natural evaluation model.
--
Steve
More information about the Python-list
mailing list