20111102

lambda过程作为返回值的例子-分析,及一个作用域的例子

lambda过程作为返回值的例子-分析,及一个作用域的例子

1. 昨天的例子的分析

昨天整完lambda过程作为返回值的例子就被二猫叫走了,没来得及分析.

以下是分析及另一个的例子(似乎出自SICP,记不大清了).

以下混用过程和函数.

: guile> (define (foo x)
: (cond ((= x 1) (lambda (y) (+ y 10)))
: ((= x 2) (lambda (y) (+ y 20)))
: (else (lambda (y) (+ y 0)))))

这段代码可以理解为

(define (foo x) (啥啥东西))

这意味着,定义了一个过程名为foo,有一个参数.

我们再看 (啥啥东西) 的里面

: (cond ((= x 1) (lambda (y) (+ y 10)))
: ((= x 2) (lambda (y) (+ y 20)))
: (else (lambda (y) (+ y 0))))

一个条件判断,有三种可能,每种可能都形如

: ((= x 1) (lambda (y) (+ y 10)))

其中 (= x 1) 是 判断条件部分,后面的 (lambda (y) (+ y 10)) 是整个表达式
的值,即foo这个过程的返回值.

这个返回值是什么呢?

: (lambda (y) (+ y 10))

这个返回值是一个函数,匿名,有一个参数,函数体是 (+ y 10),即把这个参数
加10以后返回.

整理一下.
1.foo这个函数返回值是一个函数;
2.这个作为返回值的函数,函数体是 (+ y 10).

我们再测试一下.

: guile> (foo 1)
: #<procedure #f (y)>

意思是:foo这个函数传参数值为1,返回值是个函数,有一个参数.

: guile> ((foo 1) 23)
: 33

当foo的参数为1的时候,cond求值为
: ((= x 1) (lambda (y) (+ y 10)))

(lambda (y) (+ y 10)) 的参数是
: guile> ((foo 1) 23)
中的23.

即,把(foo 1)代换为(lambda (y) (+ y 10)),这正是对(foo 1)求值的结果.

那么 ((foo 1) 23) 就成了 ((lambda (y) (+ y 10)) 23).

在一个参数的函数上,传参(apply)值为23,所以值为(+ 23 10),即33.

以下例子请作为练习分析.

: guile> ((foo 2) 23)
: 43
: guile> ((foo 3) 23)
: 23
: guile> ((foo 2) 33)
: 53

2. 新的例子.

2.1

: guile>(define (f x y)
: ((lambda (a b)
: (+ (* x (* a a)) (* y b) (* a b)))
: (+ 1 (* x y))
: (- 1 y)))

即 (define (f x y) (啥啥东西) )

定义函数f,有两个参数.

啥啥东西是:

: ((lambda (a b)
: (+ (* x (* a a)) (* y b) (* a b)))
: (+ 1 (* x y))
: (- 1 y))

这是什么呢?

这是 ((lambda (a b) (又一个啥啥东西))
(东西1)
(东西2))

这是什么意思呢?

这是 (一个匿名函数 (参数1) (参数2)).

其中 参数1 = 东西1; 参数2 = 东西2.

请先回顾一下,然后我们继续.

所以这是什么呢?这是给有两个参数的一个匿名函数传参,求值.

这个匿名函数是什么呢?(lambda (a b) (又一个啥啥东西)

原文是 (+ (* x (* a a)) (* y b) (* a b)).

2.2

所以,我们退回去一些,下式得到了解释.

: ((lambda (a b)
: (+ (* x (* a a)) (* y b) (* a b)))
: (+ 1 (* x y))
: (- 1 y))

它的意思是"这是给有两个参数的一个匿名函数传参,求值."

再往回退一点,第2节提到的式子,如下,得到了解释.

: (define (f x y)
: ((lambda (a b)
: (+ (* x (* a a)) (* y b) (* a b)))
: (+ 1 (* x y))
: (- 1 y)))

我们定义了一个函数名为f,两个参数,这个函数f的作用是 给两个参数的一个匿
名函数传参求值.

我们测试一下.

: guile>(f 1 2)
: 4

2.3

这个例子的求值,一个关键因素是那些 x、y、a、b 的值,或者说,它们的作用域。

在没有被覆盖的情况下,lambda里面的x、y就是f里面的x、y。请看下面的等价测
试。

: guile> (define x 1) (define y 2) (define a 3) (define b -1)
:
: guile> (+ (* x (* a a)) (* y b) (* a b))
: 4

No comments: