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