Re: Lambdas (was Re: [RFC] Draft Proposal for New Python Syntax)

Guido.van.Rossum@cwi.nl
Mon, 30 May 1994 14:29:43 +0200

> > [steve m]
> > ... I'm sure you wouldn't want to eliminate 'apply' and resort to:
> > ln = len( args )
> > if ln == 1 : return f( args[0] )
> > elif ln = 2 : return f( args[0], args[1] )
> > ...
>
> Before 'apply' was introduced, that's exactly what we did!

I was suprised to see apply() placed in the same category as lambda
and map/filter/reduce. Unlike the others, apply provides
functionality that does not exist otherwise -- the example work-around
can't be made to work for arbitrary large argument lists, and a
solution involving eval() would be "cheating" as well as overkill. On
the other hand, it is trivial to write map/filter/reduce in Python,
and lambda can be replaced either by something using eval() or by
using 'def'. (Note that this is a different argument than "I prefer
the loop version" -- here I'm saying "you can write that function in
Python so it needn't be built in".)

Note that C doesn't have the equivalent of apply, which makes it
hard/impossible to write a *generic* interface to C functions from
Python (this would be useful to create quick-and-dirty hacks using
dynamically loaded libraries).

I also disagree that apply() is any less useful without lambda or
filter/map/reduce.

> for thing in everything:
> if uninteresting(thing): continue
>
> isn't really obnoxious. So how come it irritates us?! I haven't figured
> that out yet.

Doesn't irritate me at all. In fact this is a style I use all the
time.

> JAR made the good point that it _does_ tend to force you _not_ to
> use a pure style (whether OO or functional or imperative), cuz builtins
> come in different flavors (len's a function but not a method, sort's a
> method but not a function, etc). Why _doesn't_ that bother us?! I
> haven't figured that one out yet either.

Probably because we actually LIKE mixing paradigms. Note that infix
operators like +, -, *, / are a third paradigm. These aren't just
popular because we happened to have learned them in school -- they are
also considerably more concise than other notations, and they stress
the associative property of the operations (for those where it
applies). I like to think that len() is a function because it applies
to a wide variety of object types, while sort() is a method because it
only applies to lists. Sure, there are border cases, but for the
majority of situations the choice is not arbitrary!

> > [ (a,x), (b,y), (c,z) ] = [ a, b, c ] "some-operator" [ x, y, x ]
> >
> > might well eliminate half of the 'map' usage and make Guido happy,

I'm not against such an operator, though I suggest that (since it
would apply to more than two arguments as well and might have mixed
argument types) it should be a function and not a method. Funnily
enough, without resorting to map(None, ...), it is remarkably hard to
write in Python:

def zip(*args):
result = []
i = 0
while 1:
item = []
ok = 0
for a in args:
try:
ai = a[i]
except IndexError:
ai = None
else:
ok = 1
item.append(ai)
if not ok:
break
result.append(tuple(item))
i = i+1
return result

def tuple(list):
t = ()
for i in list: t = t + (i,)
return t

I might make something like tuple() a built-in in the next release --
this version is O(N**2), it may be possible to write an O(log N)
version in Python, but in C there an O(N) implementation is trivial!

On the other hand, what's wrong with returning a list of lists,
avoiding the need for list->tuple conversion at all?

And last but not least, is "zip" a good name for this function?

--Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl>
URL: <http://www.cwi.nl/cwi/people/Guido.van.Rossum.html>