Statements as expressions [was Re: Undefined behaviour in C]

Marko Rauhamaa marko at pacujo.net
Tue Mar 29 05:23:21 EDT 2016


Steven D'Aprano <steve+comp.lang.python at pearwood.info>:

> 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.

Actually, it would be in my books.

However, Scheme (a Lisp dialect) also has statements that don't return
any particular value. The (if) happens to be an example. Thus,

   (set! x (if #f 3))

Assigns *some* value to x, but the language leaves it open what that
value might be.

Guile (a Scheme implementation) actually provides a distinct
"unspecified" value, which it uses in cases where the language standard
leaves the value unspecified.

> The point is that there's nothing intrinsically obvious or right about
> "return the value of the last statement in the block".

No, but the semantics of a functional language become simpler when you
can assume that every continuation operates on a value.

Consequently, every function in Python returns a value as does every
function in Perl and every command in bash.

> 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.

Forth, too, has nice, simple semantics. Forth has nothing but statements
that operate on the stack and occasionally cause some side effects.

Here's an example of how Python benefits from the functional model:
decorators. You can use the same decorators both for proper functions
and for procedures that ostensibly don't return a value. Python has
defined "None" to be the default return value for procedures so it is
legal to say,

    a = f()

even if f doesn't return a value.

Unfortunately, Python made a bit of a bad choice in the default return
value. Now Python cannot perform effective tail recursion elimination.
If Python had left the default unspecified, tail recursion elimination
would be simple.

Python's choice benefits the interactive console, which doesn't print
out None values.


Marko



More information about the Python-list mailing list