python 3's adoption

Jonathan Gardner jgardner at
Thu Jan 28 01:12:04 CET 2010

On Jan 27, 12:36 am, Paul Rubin <no.em... at nospam.invalid> wrote:
> Steven D'Aprano <ste... at> writes:
> > Without becoming a purely functional language, you won't get rid of all
> > statements.
> Why not?  GCC lets you use any statement in an expression:
>     #include <stdio.h>
>     main()
>     {
>       int i, x, p=0;
>       x = ({ for (i=1; i<=10; i++) p += i; p;});
>       printf ("x=%d\n", x);
>     }
> and C is certainly not a purely functional language.
> > for, while, if, try, break, yield, return
> > are all used for flow control, and should remain as statements.
> What about assert, import, and pass?

I think you missed the point about what a functional language is and
is not.

Let me see if I can help clear up that confusion a bit.

In a functional language, you don't use statements. For instance, when
you declare a new function, you call the function-declaring-function
with parameters describing the parameters and body of that function.

In such a language, flow control is very, very strange for those not
familiar with it. For instance, how can you call an "if" function that
only evaluates one or the other branches? In such a case, you're not
making a function call, at least not as you know it. What you're doing
is calling a special kind of function that doesn't evaluate its
parameters until later, if at all.

With the above paradigm, you have to start thinking about the
programming task in a completely different light. Rather than
organizing your code into a sequence of evaluated statements, you
organize it into one giant function that will evaluate its parameters
and return some result. This is a difficult paradigm for programmers
to grasp, and is one reason why Lisp and other functional languages
aren't know for being newbie-friendly.

Whether or not a statement can be used as an expression is really
orthogonal to this conversation.

If "yield", "break", and "continue" were functions, then you could
"call" them from within another function and have the call-ee yield,
break, or continue. For instance:

 def do_something():

 while 1:
     # The next line is never reached

This could be useful for some situations, but it is really, really
confusing and so it's not allowed. Such a function would have to rely
on some type of magic so that it is correctly identified as a yield,
break, or continue, and not a typical function call.

"import" is another case. It does something very special. It assigns
to values in the namespace of the code from which it was called. No
function can do that, at least not without some weird magic. It's
better to leave it as a statement and teach new users that it is very,
very special, than to redefine how functions work with the call-ees
namespace, or make it a common task to muck with such things.

If "while", "for", "try", "if", "def", and "class" were functions,
they would have to be written like so:

 if(expr, if-true-expr, if-false-expr)

Note, however, that you can't execute if-true of if-false until AFTER
the if() function is called. That means either we re-define what it
means to call a function, or we have some notation that means "Don't
execute this yet". Either way, it's really, really confusing.

Also, note that statements allow you to combine many statements into
one. Python's rule is that you can't pass statements to a function,
only expression, so you'd have to re-define how that works to allow
some function that would combine multiple statements together.

In the end, print is a great candidate for a function, while the
others are most definitely not. Adding any of them as functions would
mean other, fundamental aspects of Python would have to be re-defined
as well.

I hope this clears up Steve's point about functional languages.

More information about the Python-list mailing list