Discussion:
Fate of lambda, Functional Programming in Python...
(too old to reply)
510046470588-0001
2004-08-21 07:54:49 UTC
Permalink
[lambda x, y: x+y, lambda x, y: x*y, ... (etc.)]
I don't say it's impossible, but largely superfluous. (Note that this
*particular* case can be (better) solved by operator.*.)
i find infix notation disgusting, thus refuse to use it globally.

may map, filter, reduce be implemented in pure python if they
weren't built-in? scheme e.g. does not have built-in filter,
but may implement it on the fly.


may lambda be implemented with exec if it isn't built-in?
i've seen something like this done in php4 by E. Ellingsen.
would that work in crippled python, too?

Klaus Schilling
Michael J. Fromberger
2004-08-21 22:49:43 UTC
Permalink
In article
<87y8k9hqnq.fsf at debian.i-did-not-set--mail-host-address--so-shoot-me>,
may map, filter, reduce be implemented in pure python if they weren't
built-in? scheme e.g. does not have built-in filter, but may
implement it on the fly.
I do not see any reason why not. Simple map and filter implementations
for lists are almost trivial given list comprehensions. But, you do
have to be slightly careful of return types; I think the following
implementations are correct:

def map(fn, *lsts):
assert(len(lsts) > 0)

return [ fn(*args) for args in zip(*lsts) ]

def filter(fn, seq):
if fn is None:
out = [ x for x in seq if x ]
else:
out = [ x for x in seq if fn(x) ]

if isinstance(seq, str):
return str.join('', out)
else:
return type(seq)(out)

Reduce is a little bit harder to get exactly right, because of the
semantics of the initial value. However, I do think the following does
most of what reduce() is supposed to, even though it is not quite
equivalent to the existing reduce():

def reduce(fn, seq, init = None):
seq = iter(seq)

if init is None:
try:
init = seq.next()
except StopIteration:
raise TypeError("reduce() of empty sequence "
"with no initial value")

for elt in seq:
init = fn(init, elt)

return init

To perfectly emulate the built-in reduce, you would have to declare it
as reduce(fn, *args), to distinguish between the case when the user
omitted the init argument, and when they actually specified it as None.
That makes the code nastier, of course.
may lambda be implemented with exec if it isn't built-in?
Not directly; the lambda form is currently wired into the syntax, and
there is no macro system. Scheme (and other Lisp dialects) can get away
with a lot fewer built-in special forms because of the relative ease of
writing macros. Macros for an infix language are not impossible, by any
means, but they are definitely not easy (and definitely not "Pythonic").

I would prefer to see an expression-level function constructor to remain
in the language. I don't care if it's called "lambda" per se, and I
don't care if the syntax changes, but I would definitely like to keep
the functionality around. Now that there ARE nested scopes, it seems
that Guido's initial objections to the construct are mostly moot.

-M
--
Michael J. Fromberger | Lecturer, Dept. of Computer Science
http://www.dartmouth.edu/~sting/ | Dartmouth College, Hanover, NH, USA
Peter Kleiweg
2004-08-20 19:12:15 UTC
Permalink
Nobody is talking about removing the ability to pass functions, just
the actual "lambda" form.
You can still build a GUI by doing
return 5+parrot
return eggs
You just can't do
return lambda foo: 5+parrot
What a silly idea to remove a much used core feature from a
language.
--
Peter Kleiweg L:NL,af,da,de,en,ia,nds,no,sv,(fr,it) S:NL,de,en,(da,ia)
info: http://www.let.rug.nl/~kleiweg/ls.html
Dan Schmidt
2004-08-21 16:02:46 UTC
Permalink
Jeff Sandys <sandysj at juno.com> writes:

| How about this use of lambda?
| (from another post 'RE: How to sort this kind of list easily?' today)
|
| | Or if you want to sort only on your Id, use a lambda:
| | l.sort(lambda x,y: cmp(x[0],y[0]))

In 2.4, you actually don't need a lambda:

l.sort( key = operator.itemgetter( 0 ) )

but I too would be very sad to see anonymous functions go away,
although I find the current syntax pretty ugly.

Dan
--
http://www.dfan.org
Reinhold Birkenfeld
2004-08-20 20:37:07 UTC
Permalink
| > > Hi,all
| > >
| > > [(1,'xxxxx'),(7,'ppppp'),(4,'gggggg'),...]
| > >
| > > I want to sort this list according to the id of each element.
| > >
| > > [(1,'xxxxx'),(4,'gggggg'),(7,'ppppp')...]
| >
| > list.sort sorts tuples by first argument, then second &c. If you
want
| > a custom sort order, look at the decorate-sort-undecorate pattern.
|
| l.sort(lambda x,y: cmp(x[0],y[0]))
|
| To force sorting on just the nth element of the tuples, replace 0
with
| n in the above.
|
I think that lambda should be unlimited and expanded. It already has
the
colon, block delimiter, so allow lambda to be a multistatement and
multiline
indented block!
So in what point exactly is this different from a def(), then?

Reinhold
--
Wenn eine Linuxdistribution so wenig brauchbare Software wie Windows
mitbr?chte, w?re das bedauerlich. Was bei Windows der Umfang eines
"kompletten Betriebssystems" ist, nennt man bei Linux eine Rescuedisk.
-- David Kastrup in de.comp.os.unix.linux.misc
Marek Baczyński
2004-08-20 21:26:50 UTC
Permalink
Post by Reinhold Birkenfeld
I think that lambda should be unlimited and expanded. It already has
the
colon, block delimiter, so allow lambda to be a multistatement and
multiline
indented block!
So in what point exactly is this different from a def(), then?
1) Lambda is anonymous.
2) Lambda evaluates to a function (or rather can be used as an expression.)

Try this without lambda:

[lambda x, y: x+y, lambda x, y: x*y, ... (etc.)]

I don't say it's impossible, but largely superfluous. (Note that this
*particular* case can be (better) solved by operator.*.)
--
Marek Baczy?ski :: UIN 57114871 :: GG 161671 :: JID imbaczek at jabber.gda.pl
He who knows best best knows how little he knows. -- Thomas Jefferson
John Roth
2004-08-21 13:22:18 UTC
Permalink
"Reinhold Birkenfeld" <reinhold-birkenfeld-nospam at wolke7.net> wrote in
Post by Reinhold Birkenfeld
| > > Hi,all
| > >
| > > [(1,'xxxxx'),(7,'ppppp'),(4,'gggggg'),...]
| > >
| > > I want to sort this list according to the id of each element.
| > >
| > > [(1,'xxxxx'),(4,'gggggg'),(7,'ppppp')...]
| >
| > list.sort sorts tuples by first argument, then second &c. If you
want
| > a custom sort order, look at the decorate-sort-undecorate pattern.
|
| l.sort(lambda x,y: cmp(x[0],y[0]))
|
| To force sorting on just the nth element of the tuples, replace 0
with
| n in the above.
|
I think that lambda should be unlimited and expanded. It already has
the
colon, block delimiter, so allow lambda to be a multistatement and
multiline
indented block!
So in what point exactly is this different from a def(), then?
def() is a statement. It can't be used in an expression. That's
the crux of the problem, and always has been the crux of
the problem.

John Roth
Post by Reinhold Birkenfeld
Reinhold
Bernhard Herzog
2004-08-21 16:44:10 UTC
Permalink
Post by Dan Schmidt
How about this use of lambda?
(from another post 'RE: How to sort this kind of list easily?' today)
[...]
Post by Dan Schmidt
| l.sort(lambda x,y: cmp(x[0],y[0]))
@l.sort
def sort_on_zeroth(x, y):
return cmp(x[0], y[0])

Gives a whole new meaning to decorate-sort-undecorate ;-)

Bernhard
--
Intevation GmbH http://intevation.de/
Skencil http://sketch.sourceforge.net/
Thuban http://thuban.intevation.org/
&quot;Elveto, artiste-ingénieur en némotechnique&quot;
2004-08-21 10:48:46 UTC
Permalink
In a comment off a post on lambda-the-ultimate, I noticed this little
'''IIRC GvR is going to kill the various lambda, map,filter & reduce
leaving just generator expressions/list comprehension.'''
The real reason is political neutrality. lambda & al revealed to provide just
too much access to Guido's famed time machine, when python 1.5.2 itself
manifested blind patriotism after 9/11, eg
filter(lambda W : W not in 'ILLITERATE','BULLSHIT')
'BUSH'
Anthony Baxter
2004-08-20 19:45:51 UTC
Permalink
In a comment off a post on lambda-the-ultimate, I noticed this little
'''IIRC GvR is going to kill the various lambda, map,filter & reduce
leaving just generator expressions/list comprehension.'''
First point: lambda, map, filter and reduce won't go away before Python 3.0,
at the very least. And, to be honest, I suspect map/filter/reduce are much more
likely to die than lambda, as they can nearly always be expressed more clearly
as listcomps or genexprs.

Having said that, and donning my interpreting-Guido-hat, the major problem
with lambda is the scoping issue. Nested scopes make this less of a problem.
In addition, the name 'lambda' was a poor poor choice.
Reinhold Birkenfeld
2004-08-20 20:37:32 UTC
Permalink
In a comment off a post on lambda-the-ultimate, I noticed this little
'''IIRC GvR is going to kill the various lambda, map,filter & reduce
leaving just generator expressions/list comprehension.'''
NO!!!!111eins

Don't you think of the whole Python obfuscation lot?

Reinhold
--
Wenn eine Linuxdistribution so wenig brauchbare Software wie Windows
mitbr?chte, w?re das bedauerlich. Was bei Windows der Umfang eines
"kompletten Betriebssystems" ist, nennt man bei Linux eine Rescuedisk.
-- David Kastrup in de.comp.os.unix.linux.misc
Beeyah
2004-08-21 01:09:01 UTC
Permalink
I can't think of a situation where you _really_ need the second (and
much more limited) form.
Well, obviously the truth is you don't, however brevity tends to be a
programmer's best friend (the other edge of the sword, of course,
typically being the lack of readability.) The fact is that lambas
aren't really difficult understand, but occasionally you have to
linger on the line for a second or two longer to grasp what the
programmer is saying (provided you know how lambdas work -- a simple
feat)
From what I've seen, the argument always either starts or ends with
the "it deters newbies" bandwagon, and I must say I don't agree. If
anything it sparks their curiosity as to what the keyword does, and
taking it out of the language would deter the demographic that banks
on it.

The other problem is how widely its used (a fact that's confirmed by
the defense lambda's receiving,) a lot of applications would have to
be changed and extended to accommodate the lack of our favorite
one-liner ;\

Beeyah
Chas Emerick
2004-08-20 19:37:32 UTC
Permalink
Nobody is talking about removing the ability to pass functions, just
the actual "lambda" form.
You can still build a GUI by doing
return 5+parrot
return eggs
You just can't do
return lambda foo: 5+parrot
I can't think of a situation where you _really_ need the second (and
much more limited) form.
Well, there's a couple issues here. First, I'd rather see the ability
to do a multiline lambda form. I'm still not clear on why that wasn't
dropped in from the start.

But even given the way things are now, lambdas are not just a slight
reordering of syntax -- they're sometimes the only way to get things
done quickly and cleanly. Especially in UI's and in certain simulation
environments, being able to build up a function table of super-simple
functions mapped to particular environment parameters is critical.
Having to explicitly define these sorts of things is a huge pain. A
good corollary to python lambdas seems to be anonymous classes in Java,
especially in a Swing application (the ugly, very gimpy cousin of the
lambda). If anonymous classes weren't available in Java, Swing would
be even worse than it is already; python without lambdas would be a
huge loss to the language IMO.

And finally, with respect to the spirit of your final comment: just
because you don't __need__ a more concise, clearer, and easier-to-use
form doesn't mean that that form has no use, or that switching to a
'lesser' approach (at least within a restricted usage context) has no
costs associated with it.

I did find something about GvM's stance towards lambdas and FP in
Sometimes I've been too quick in accepting contributions, and later
realized that it was a mistake. One example would be some of the
functional programming features, such as lambda functions. lambda is a
keyword that lets you create a small anonymous function; built-in
functions such as map, filter, and reduce run a function over a
sequence type, such as a list.
local and global. This makes writing lambda functions painful, because
you often want to access variables in the scope where the lambda was
defined, but you can't because of the two scopes. There's a way around
this, but it's something of a kludge. Often it seems much easier in
Python to just use a for loop instead of messing around with lambda
functions. map and friends work well only when there's already a
built-in function that does what you want.
This is really funny to me, because it seems like Guido is saying,
essentially, "Python doesn't have proper closures, therefore lambdas
form a temptation that can't really be fulfilled right now, therefore
[given the current rumormill] we should get rid of lambdas." I suppose
it would be silly to ask why the premise of this line of thought
shouldn't be changed, instead of throwing the baby out with the
bathwater. There's been plenty of discussions about closures and
python, so I suppose there's no need to kill that topic again.

-- Chas Emerick
Chas Emerick
2004-08-20 16:50:02 UTC
Permalink
In a comment off a post on lambda-the-ultimate, I noticed this little
offhand remark:

'''IIRC GvR is going to kill the various lambda, map,filter & reduce
leaving just generator expressions/list comprehension.'''

If this is considered generally true (at least in the
straight-from-the-rumor-mill sense) I'm hoping someone here can either
provide the backstory on this or point me in the direction of related
discussions on python-dev (it's **real** hard to do a search on that
list's archives when one's main keywords are lambda, map, filter,
etc...).

I'm quite fond of lambda, and it seems to have plenty of uses aside
from munging lists in connection with map calls (i.e. passing one-off
comparators to cmp()). Of course, my first "real" programming language
was lisp, so perhaps I'm biased. (You should see all the anonymous
classes I throw off in Java!)

Anyway -- back to your regularly scheduled decorator-discussion of the
day. ;-)

-- Chas Emerick
Hans Nowak
2004-08-21 01:52:44 UTC
Permalink
Post by Anthony Baxter
First point: lambda, map, filter and reduce won't go away before Python 3.0,
at the very least. And, to be honest, I suspect map/filter/reduce are much more
likely to die than lambda, as they can nearly always be expressed more clearly
as listcomps or genexprs.
People often lump reduce in with the rest, but there's really no easy way to
express a reduce with list comprehensions. That said, for Python 3.0, these
functions would probably be better off in a separate module with functional
constructs, rather than disappearing entirely...

--
Hans Nowak (hans at zephyrfalcon.org)
http://zephyrfalcon.org/
Michael Hudson
2004-08-23 15:50:44 UTC
Permalink
Post by Hans Nowak
Post by Anthony Baxter
First point: lambda, map, filter and reduce won't go away before
Python 3.0, at the very least. And, to be honest, I suspect
map/filter/reduce are much more likely to die than lambda, as they
can nearly always be expressed more clearly as listcomps or
genexprs.
People often lump reduce in with the rest, but there's really no easy
way to express a reduce with list comprehensions.
You can replace it with a for loop though, and TBH I think the change
is usually an improvement.

Cheers,
mwh
--
For their next act, they'll no doubt be buying a firewall
running under NT, which makes about as much sense as
building a prison out of meringue. -- -:Tanuki:-
-- http://home.xnet.com/~raven/Sysadmin/ASR.Quotes.html
Peter Kleiweg
2004-08-20 21:23:32 UTC
Permalink
Post by Anthony Baxter
In a comment off a post on lambda-the-ultimate, I noticed this little
'''IIRC GvR is going to kill the various lambda, map,filter & reduce
leaving just generator expressions/list comprehension.'''
First point: lambda, map, filter and reduce won't go away before Python 3.0,
at the very least. And, to be honest, I suspect map/filter/reduce are much more
likely to die than lambda, as they can nearly always be expressed more clearly
as listcomps or genexprs.
The Python Cookbook, recipe 1.8, "Finding the Intersection of
Two Dictionaries" shows different methods of doing this
particular thing, among them list comprehension and filter.
Here, using filter is the fastest of all.

Why would you want to do away with something that is useful?
Post by Anthony Baxter
Having said that, and donning my interpreting-Guido-hat, the major problem
with lambda is the scoping issue. Nested scopes make this less of a problem.
In addition, the name 'lambda' was a poor poor choice.
The choice is perfectly logical.
--
Peter Kleiweg L:NL,af,da,de,en,ia,nds,no,sv,(fr,it) S:NL,de,en,(da,ia)
info: http://www.let.rug.nl/~kleiweg/ls.html

The Halloween Documents: http://www.opensource.org/halloween/
Jeff Sandys
2004-08-20 20:26:15 UTC
Permalink
Agreed! I'm currently building a GUI in Tkinter, with event
handlers and callbacks all over the place. The lambda form is an
absolute MUST for this kind of thing!
Nobody is talking about removing the ability to pass functions, just
the actual "lambda" form.
You can still build a GUI by doing
return 5+parrot
return eggs
You just can't do
return lambda foo: 5+parrot
I can't think of a situation where you _really_ need the second
(and much more limited) form.
How about this use of lambda?
(from another post 'RE: How to sort this kind of list easily?' today)

| > > Hi,all
| > > I have a list like [(id,string),...],for example:
| > >
| > > [(1,'xxxxx'),(7,'ppppp'),(4,'gggggg'),...]
| > >
| > > I want to sort this list according to the id of each element.
| > > After sorting,the list will become:
| > >
| > > [(1,'xxxxx'),(4,'gggggg'),(7,'ppppp')...]
| >
| > list.sort sorts tuples by first argument, then second &c. If you
want
| > a custom sort order, look at the decorate-sort-undecorate pattern.
|
| Or if you want to sort only on your Id, use a lambda:
| l.sort(lambda x,y: cmp(x[0],y[0]))
|
| To force sorting on just the nth element of the tuples, replace 0
with
| n in the above.
|

I think that lambda should be unlimited and expanded. It already has
the
colon, block delimiter, so allow lambda to be a multistatement and
multiline
indented block!

Thanks,
Jeff Sandys
Jared Cohen
2004-08-20 17:37:21 UTC
Permalink
Agreed! I'm currently building a GUI in Tkinter, with event handlers
and callbacks all over the place. The lambda form is an absolute MUST
for this kind of thing!
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-list/attachments/20040820/94f5a1cc/attachment.html>
Christopher A. Craig
2004-08-20 19:01:04 UTC
Permalink
Agreed! I'm currently building a GUI in Tkinter, with event handlers and
callbacks all over the place. The lambda form is an absolute MUST for this
kind of thing!
Nobody is talking about removing the ability to pass functions, just
the actual "lambda" form.

You can still build a GUI by doing

def spam(stuff):
def eggs(parrot):
return 5+parrot
return eggs

You just can't do

def spam(stuff):
return lambda foo: 5+parrot


I can't think of a situation where you _really_ need the second (and
much more limited) form.
--
Christopher A. Craig <com-nospam at ccraig.org>
"The shortest distance between two points is usually torn up." Frank Walsh
Continue reading on narkive:
Loading...