中国Linux公社 - Scheme 语言介绍Lambda 表达式和环境

来源:百度文库 编辑:神马文学网 时间:2024/04/25 07:54:37
Scheme 的执行环境被表示为所谓的“lambda 表达式”。这个术语起源于 Church 的 lambda 演算(calculus),它充当 MacCarthy 在符号计算上的某些想法的模型。Lambda 表达式开始于一个关键字“lambda”,随后式一个(可能为空)参数的列表和一个表达式序列。当 lambda 表达式应用在正确的上下文中的时候,这些表达式按顺序执行并返回最后的值。
(lambda () "hi there") ;# ( (lambda () "hi there") ) ;"hi there"
在第一个例子中的 lambda 表达式定义过程文字。在第二个 lambda 表达式周围包装了额外的一对括号强制它执行。Lambda 表达式可以接受固定或可变数目的参数。使用不同的语法惯例来指出需要那种参数传递机制。
((lambda (aFriend) ; 函数有一个形式参数: aFriend (DisplayLine "hi there " aFriend)) ‘HappyMole) ; 调用时带有一个实际参数: HappyMole ;hi there HappyMole #t
这里把由 lambda 表达式表示的过程应用到作为它的参数的 "HappyMole"上。这生成一个计算,在其中 DisplayLine 把要求的字符串放置到屏幕上。#t 是最后的显示返回的值,因此它还是整个 lambda 表达式的返回值。如果你在你自己的平台上写过了这个例子,你最有可能忘记引用 HappyMole,导致 Scheme 抱怨另一个 "unbound variable"。得到正确的引用可能需要很多实践,但是不久之后它就会成为“第二天性”。
Scheme 提供两种可供选择的方式来要求可变数目的实际参数。
; lambda 表达式,调用时带有 3 个实际参数 ((lambda someFriends ; 参数周围没有括号 ! (DisplayLine "hi there " someFriends)) ‘mole ‘bear ‘tiger) ;hi there (mole bear tiger) #t ; 调用时带有 0 个实际参数 ((lambda someFriends (DisplayLine "hi there" someFriends)) ) ;hi there () #t
下面的所有参数都绑定到一个表(它可以为空)中并传递给 lambda 表达式。请注意我们必须提供一个不带任何括号的单一的参数来导致这种行为。如果我们想要让我们所有的参数都是可选择的,可以使用
; 一个强制的和一些可选的参数 ((lambda (aFriend . someMore) (DisplayLine "hi there " someMore)) ‘mole ‘bear ‘tiger) ; 三个参数 ;hi there (bear tiger) #t ; mole 现在被绑定到 "aFriend" ((lambda (aFriend . someMore) (DisplayLine "hi there" someMore))) ; 没有参数 ;ERROR: Too few arguments to procedure ;0 arguments supplied - 1 argument expected
这里的 aFriend 将被绑定为 mole,而所有余下的实际参数将再次被组合到一个表中并绑定到 someMore。 当然,我们现在必须提供最少一个实际参数。
Scheme 提供一个谓词(procedure?)来测试一个对象实际上是否为过程。apply 在某些情况下也是有用的,它强制一个过程在当前上下文中的应用。注意 apply 总是期望一个表作为它的单一的参数。
(procedure? (lambda () (display "hello"))) ;#t (apply (lambda (aFriend) (DisplayLine "hello" aFriend)) ‘(mole) ) ;hello mole #t
Lambda 表达式可以包含它们自己的对数据和过程的“局部”定义。因此它们是主要的的环境建造块, Scheme 依据“词法作用域”的概念而有层次的安排它们。使用这种环境来定义在一个计算期间的所有点上(“作用域内”)都是当前可见的对象,早期的 Lisp 系统只支持“动态作用域”,这是导致无数非常难于跟踪的程序错误的一个“特征”。