MIT/GNU Scheme 参考手册 (2021-11-04,每天一页,认真学习)

Ch2 特殊形式

        特殊形式是具有特殊求值规则的表达式。本章将讲述 Scheme 中的基本特殊形式。

Sec 2.1 Lambda 表达式

            lambda  formals expr  expr   ...                            [ extended standard special form ]   

        lambda表达式的计算结果为过程。计算 lambda 表达式时的有效环境被作为过程的一部分被记住。它被称为封闭环境。当随后使用一些参数调用该过程时,封闭环境将通过与形式参数中的变量绑定而扩展到新位置,同时,这些参数根据对应规则填充到相应的位置。这个过程创建的新环境称为调用环境。这个过程创建的新环境称为调用环境。

        一旦调用环境被构建,lambda 体中的表达式将在其中按顺序计算。这意味着被 lambda 表达式绑定的变量区域是主体中的所有表达式。计算结果是主体中的最后一个表达式,它的值将作为过程调用的结果返回。

        Formals, 即形式参数列表,通常被称为 lambda 列表。

        将形式参数与参数匹配的过程有些复杂。有三种类型的参数,匹配将按顺序处理每种参数:

Required                首先将所有的必须参数与参数进行匹配。如果所给参数少于要求的必须参数,

                               则会出现错误信息,类型为:condition-type:wrong-number-of-arguments;

                               如果所给参数多于必须参数,而此处又没有其他类型参数,则也会发出此错

                               误信号。

Optional                  一旦必须参数全部匹配完成,可选参数将和剩余参数进行对应匹配。如果剩

                               余的参数比可选参数少,没有被匹配的可选参数将与被称为默认对象的特殊

                               对象绑定。如果剩余参数比可选参数多,且此处没有其他类型的参数了,则

                               会发出错误信号,类型为:condition-type:wrong-number-of-arguments。

                                谓词 default-object?仅适用于默认对象,可用于确定哪些参数是提供了值

                                的,哪些是默认参数值。

Rest                        最后,如果有一个 rest 参数(只能有一个),则所有剩余的参数都将被放入

                                一个列表中,并且该列表将绑定到 rest 参数。(如果没有剩余参数,则 rest

                                参数与空列表绑定。)不像其他 Lisp 的实现,在 Scheme 中,rest 参数绑定

                                的列表总是新分配的。它有无限的范围,可以在不影响过程调用的情况下进

                                行修改。

        专门的识别关键字把形式参数分为以上三类。这里所用的关键字为 ' #!optional ',' . ' 和 ' #!rest '。请注意, 只用 '.' 是在标准 Scheme 里定义的, 其它两个是 MIT/GNU Scheme 扩展的。'#!rest' 和 ' . ' 在形式上具有相同意义。

        这些关键字的使用最好通过例子来解释。下面是典型的 lambda 列表,后面是关于哪些参数是必须的、可选的和剩余的描述。我们将在这些例子中使用' #!rest ' ,但在它出现的任何地方都可以使用 ' . ' 替换。

(a  b  c)                                a,b 和 c 都是必须参数。过程必须正好传递这三个参数。

(a  b  #!optional  c)              a,b 是必须参数,c 是可选参数。过程可以传递两个或三个参数。

(#!optional  a  b  c)              a,b 和 c 都是可选参数。过程可以传递 0 -- 3 之间任意数量的参数。

a

(#!rest  a)                              这两个例子等价。 a 是一个 rest 参数。过程可以传递任意多数量的参

                                             数。注意:这是唯一一种不能用 ' . ' 替代 ' #!rest ' 的情况。(这个情况

                                             指的是过程只有一个形式参数,且这个形式参数是 Rest 型。

(a b #!optional  c  d  #!rest  e)

                                              a 和 b 是必须参数,c 和 d 是可选参数,e 是 rest 参数。过程可以传

                                              递两个或更多参数。

一些 lambda 表达式的例子:

(lambda (x) (+ x x))             =>    #[compound-procedure 53]
 ((lambda (x) (+ x x)) 4)         =>    8

 (define reverse-subtract
    (lambda (x y)
        (- y x)))
 (reverse-subtract 7 10)          =>    3

 (define foo
    (let  ((x 4))
       (lambda (y) (+ x y))))
 (foo 6)                          =>    10

      named-lambda        formals  expression expression  ...                [special  form]

         特殊形式 named-lambda lambda 相似,除了参数列表中的第一个必须参数不是参数,而是结果过程的名字;也就是说,必须至少含有一个参数。这个名字没有语义含义,但是包含在过程的外部表示中,因此在调试中非常有用。在 MIT/GNU Scheme 中,lambda 就像 named-lambda 的无命名方式一样运行。

(named-lambda  (f x)  (+ x x))        =>    #[compound-procedure 53 f]
 (named-lambda  (f x)  (+ x x))  4)    =>    8

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值