哇! Python和Lisp真的有LAMBDA吗? [英] Whoa! Do Python and Lisp really have LAMBDA ?

查看:87
本文介绍了哇! Python和Lisp真的有LAMBDA吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

早些时候Ed Schofield(谢谢,男人)警告我们


flist = []


for i in range(3)

f = lambda x:x + i

flist.append(f)


[f(1)for f in flist]


给出[3,3,3]。对于最小惊喜的原则这么多!


在Lisp中做同样的事情(用列表代替数组),


(setf flist(循环为i从0到2

collect(lambda(x)(+ xi))))


(fl中f的循环

collect(funcall f 1))


我有(4 4 4)。


Lisp有很多陷阱,我只是还没准备好这个。

(Google为lisp gotchas - 有人在1995年向cll发布了一个全面的

列表。每个Lisper应该阅读它)


我肯定Haskell做得对。 Scheme和ML怎么样?

解决方案

< mi ***** @ ziplip.com>写道:

+ ---------------

|在Lisp中做同样的事情(用列表而不是数组),

|

| (setf flist(循环为i从0到2

| collect(lambda(x)(+ xi))))

|

| (循环为f in flist

| collect(funcall f 1))

|

|我得到了(4 4 4)。

|

| Lisp有很多陷阱,我只是还没准备好这个。

+ ---------------


为什么这应被视为陷阱?它正在按照你要求的那样完成:所有三个lambdas都关闭*相同的*变量

绑定,它被保留为3。当循环结束。以这种方式试试

而你可能得到你想要/期望的东西:

(defparameter flist(循环为i从0到2
)收集(让((ui))

(lambda(x)(+ xu)))))

FLIST(fl中的f循环
collect( funcall f 1))

(1 2 3)




在这种情况下,lambdas关闭* distinct * bindings。

-Rob


-----

Rob Warnock< rp ** @ rpw3.org>

627 26th Avenue< URL:http://rpw3.org/>

San Mateo,CA 94403 (650)572-2607


On Sun,2003年10月26日02:53:58 -0600, rp**@rpw3.org (Rob Warnock)写道:

< mi ***** @ ziplip.com>写道:
+ ---------------
| Lisp有很多陷阱,我只是还没准备好这个。
+ ---------------

为什么要把它当成一个gotcha?




因为他是一个巨魔。


> (setf flist(循环为i从0到2

collect(lambda(x)(+ xi))))
(循环for f in flist
collect(funcall f) 1))

我得到了(4 4 4)。


是的,这是令人惊讶的,虽然一旦你意识到它们都绑定到同一个i,它会在循环中发生变异时更有意义。

我肯定Haskell做得对。那么Scheme和ML呢?




Scheme中的等价物(名为let)为每个

迭代引入了一个新的绑定,所以它做了什么你期待。


(定义flist

(让循环((i 0)(r''()))

(cond((> i 2)(反向r))

(否则(循环(+ 1 i)

(缺点(lambda(x)(+ xi) )r))))))


(让循环((l flist)(r''()))

(cond((null? l)(反向r))

(否则(循环(cdr l)

(缺点((车l)1)r)))))


与flist的Lisp版本不同,Scheme循环为每个

迭代绑定一个新的i。因此,每个闭包都有自己的i。

我的Scheme版本比上面的Lisp版本更加冗长。也许

更有经验的阴谋家可以向你展示一个不那么冗长的版本

仍然可以做你想要的。我一直都喜欢函数式语言,但是我最近才有机会和他们一起工作,所以

我还在学习。

-

Bradd W. Szonye
http://www.szonye.com/bradd

我的Usenet电子邮件地址暂时被禁用。

请访问我的网站获取备用地址。


Earlier Ed Schofield (thanks, man) warned us that

flist = []

for i in range(3)
f = lambda x: x + i
flist.append(f)

[f(1) for f in flist]

gives [3, 3, 3]. So much for the principle of minimum surprise!

Doing the same in Lisp (with lists instead of arrays),

(setf flist (loop for i from 0 to 2
collect (lambda (x) (+ x i))))

(loop for f in flist
collect (funcall f 1))

I got (4 4 4).

Lisp has many gotchas, I just wasn''t ready for this one.
(Google for "lisp gotchas" - someone posted a comprehensive
list to c.l.l. in 1995. Every Lisper should read it)

I''m sure Haskell does this right. What about Scheme and ML?

解决方案

<mi*****@ziplip.com> wrote:
+---------------
| Doing the same in Lisp (with lists instead of arrays),
|
| (setf flist (loop for i from 0 to 2
| collect (lambda (x) (+ x i))))
|
| (loop for f in flist
| collect (funcall f 1))
|
| I got (4 4 4).
|
| Lisp has many gotchas, I just wasn''t ready for this one.
+---------------

Why should this be considered a "gotcha"? It''s doing exactly what
you asked it to: all three lambdas are closed over the *same* variable
binding, which was left holding "3" when the loop finished. Try it
this way instead and you might get what you wanted/expected:

(defparameter flist (loop for i from 0 to 2 collect (let ((u i))
(lambda (x) (+ x u)))))
FLIST (loop for f in flist collect (funcall f 1))
(1 2 3)



In this case the lambdas are closed over *distinct* bindings.
-Rob

-----
Rob Warnock <rp**@rpw3.org>
627 26th Avenue <URL:http://rpw3.org/>
San Mateo, CA 94403 (650)572-2607


On Sun, 26 Oct 2003 02:53:58 -0600, rp**@rpw3.org (Rob Warnock) wrote:

<mi*****@ziplip.com> wrote:
+---------------
| Lisp has many gotchas, I just wasn''t ready for this one.
+---------------

Why should this be considered a "gotcha"?



Because he''s a troll.


> (setf flist (loop for i from 0 to 2

collect (lambda (x) (+ x i))))
(loop for f in flist
collect (funcall f 1))

I got (4 4 4).
Yes, that is suprising, although it makes more sense once you realize
that they all bind to the same i, which is mutated during the loop.
I''m sure Haskell does this right. What about Scheme and ML?



The equivalent in Scheme (named let) introduces a new binding with each
iteration, so it does what you expect.

(define flist
(let loop ((i 0) (r ''()))
(cond ((> i 2) (reverse r))
(else (loop (+ 1 i)
(cons (lambda (x) (+ x i)) r))))))

(let loop ((l flist) (r ''()))
(cond ((null? l) (reverse r))
(else (loop (cdr l)
(cons ((car l) 1) r)))))

Unlike the Lisp version of flist, the Scheme loop binds a new i for each
iteration. Therefore, each closure has its own i.

My Scheme version is much wordier than the Lisp version above. Perhaps
the more experienced schemers can show you a less verbose version that
still does what you want. I''ve always been fond of functional languages,
but I''ve only recently had the chance to work with them extensively, so
I''m still learning.
--
Bradd W. Szonye
http://www.szonye.com/bradd
My Usenet e-mail address is temporarily disabled.
Please visit my website to obtain an alternate address.


这篇关于哇! Python和Lisp真的有LAMBDA吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆