1

我是 Scheme 的新手,我正在尝试通过阅读Structure and Interpretation of Computer Programs来熟悉这门语言。我对排序有点困惑。

首先,我知道begin引入关键字是为了允许排序,因此需要更容易地对可变结构进行操作。我不明白的是,有时他们使用如下排序(受 SCIP 第 268 页上的示例启发):

(define (stuff-0)
   (+ 1 2)
   (+ 1 3)
   'ok)

而同样可以使用begin

(define (stuff-1)
  (begin
    (+ 1 2)
    (+ 1 3)
    'ok))

这两者之间是否存在语义差异,或者第一个只是第二个的语法糖?

其次,除了实际重要性之外,我们在理论上是否需要begin构造?我想对于我们需要的每个序列,我们可以编写实现该序列的级联程序。这当然是不切实际的,但我只是对没有begin结构的语言的表现力感兴趣。

4

3 回答 3

3

这很简单:在一个过程中,总是有一个隐含 begin的. 所以这:

(define (f x)
  (begin
    <expression 1>
    <expression 2>
    <returned value>))

...完全等价于这个:

(define (f x)
  <expression 1>
  <expression 2>
  <returned value>)

不,没有任何语义差异,上面的第二种形式只是第一种形式的语法糖。并且begin形式是必要的,因为必须有一种方法来执行一系列表达式,只是为了它们以指定的顺序产生效果。请记住:在 a 中begin(或就此而言,在过程中 - 它是相同的)所有表达式都按照它们出现的顺序执行,它们的结果值基本上被忽略了,最后只返回最后一个表达式的值。

于 2013-05-16T00:01:22.280 回答
1

每个 define special from 都包含一个隐式的 begin 子句。

对于新手来说,第二个例子更清楚,但对于有经验的人来说,它只是噪音。

一个经常需要 begin 构造的地方是 if 语句的 then 或 else 子句。您还需要在匿名函数中使用它。

于 2013-05-16T00:02:01.967 回答
1

begin不需要显式。如果您需要对某些内容进行排序,但没有begin,那么您可以这样做:

((lambda () <body1> <body2> ...))

实际上,以上内容正是您将如何实现begin为宏的方式。以下是 R7RS 的语法定义:

 (define-syntax begin
    (syntax-rules ()
      ((begin exp ...)
       ((lambda () exp ...)))))

因此,您的陈述“我知道begin引入关键字是为了允许排序”并不是真正正确的。 begin被引入作为基本排序结构的句法糖lambda

于 2013-05-16T04:30:17.940 回答