Python from Wise Guy's Viewpoint

Alex Martelli aleax at aleax.it
Mon Oct 20 05:40:40 EDT 2003


Duncan Booth wrote:

> mike420 at ziplip.com wrote in
> news:LVOAILABAJAFKMCPJ0F1IFP5N3JTNUL0EPMGKMDS at ziplip.com:
> 
>> 1. f(x,y,z) sucks. f x y z  would be much easier to type (see Haskell)
>>    90% of the code is function applictions. Why not make it convenient?
> 
> What syntax do you propose to use for f(x(y,z)), or f(x(y(z))), or
> f(x,y(z)) or f(x(y),z) or f(x)(y)(z) or numerous other variants which are
> not currently ambiguous?

Haskell has it easy -- f x y z is the same as ((f x) y) z -- as an
N-ary function is "conceptualized" as a unary function that returns
an (N-1)-ary function [as Haskell Curry conceptualized it -- which
is why the language is named Haskell, and the concept currying:-)].
So, your 5th case, f(x)(y)(z), would be exactly the same thing.

When you want to apply operators in other than their normal order
of priority, then and only then you must use parentheses, e.g. for 
your various cases they would be f (x y z) [1st case], f (x (y z))
[2nd case], f x (y z) [3rd case], f (x y) z [4th case].  You CAN,
if you wish, add redundant parentheses, of course, just like in
Python [where parentheses are overloaded to mean: function call,
class inheritance, function definition, empty tuples, tuples in
list comprehensions, apply operators with specified priority --
I hope I recalled them all;-)].

Of course this will never happen in Python, as it would break all
backwards compatibility.  And I doubt it could sensibly happen in
any "simil-Python" without adopting many other Haskell ideas, such
as implicit currying and nonstrictness.  What "x = f" should mean
in a language with assignment, everything first-class, and implicit
rather than explicit calling, is quite troublesome too.

Ruby allows some calls without parentheses, but the way it disambiguates 
"f x y" between f(x(y)) and f(x, y) is, IMHO, pricey -- it has to KNOW
whether x is a method, and if it is it won't just let you pass it as such
as an argument to f; that's the slippery slope whereby you end up having to
write x.call(y) because not just any object is callable.
"x = f" CALLS f if f is a method, so you can't just treat methods
as first-class citizens like any other... etc, etc...
AND good Ruby texts recommend AVOIDING "f x y" without parentheses,
anyway, because it's ambiguous to a human reader, even when it's
clear to the compiler -- so the benefit you get for that price is
dubious indeed.


Alex





More information about the Python-list mailing list