【问题标题】:Using define in a conditional expression in Scheme在 Scheme 的条件表达式中使用 define
【发布时间】:2020-01-18 16:57:56
【问题描述】:

在Scheme中,过程定义的一般形式是:

(定义(名称> 参数>)正文>)

body> 接受一系列表达式,允许这种过程定义:

> (define (f) 1 2 3)
> (f)
3

同样,条件表达式的一般形式是:

(cond (predicate> consequent>) (predicate> consequent>) … (谓词> 后继>))

where consequent> 在每个子句中接受一系列表达式,允许这种条件表达式:

> (cond (#t 1 2 3))
3

但为什么我不能像在过程定义的主体中那样在条件表达式的子句后件中使用define

比较:

> (define (f) (define x 1) (define y 1) (define z 1) (+ x y z))
> (f)
3

与:

> (cond (#t (define x 1) (define y 1) (define z 1) (+ x y z)))
ERROR on line 1: unexpected define: (define x 1)

注意。 — 我在 MacOS 10.15.2 上使用 Chibi-Scheme 0.8.0 实现。

【问题讨论】:

  • 这应该可以。 R7RS 规范说cond 的子句是expression definition* expression*。但看起来他们实际上是在实施 R6RS 规范,该规范不允许在开始时进行定义。
  • @Barmar 您在规范中的什么地方看到了这一点?我在第 4.2.1 段看到了这一点:“(⟨test⟩ ⟨expression1⟩ ...)”。您是否在另一个符合 R7RS 的实现上尝试过?
  • 我的错误。 cond 子句引用<tail expression>,而不是<tail body>
  • 所以原因是定义不是表达式。定义只能放置在某些地方,例如程序主体的开头和let 主体的开头。

标签: scheme naming conditional-operator


【解决方案1】:

正如@Barmar 所说,定义 不是表达式,但在两种情况下两者都是允许的(参见R7RS 的第 5.1 节,强调我的) :

  • 在程序的最外层;
  • 在正文的开头。

Scheme 程序包含一个或多个导入声明,后跟一系列表达式和定义。导入声明指定程序或库所依赖的库;库导出的标识符子集可供程序使用。表达式在第 4 章中描述。定义可以是变量定义、语法定义或记录类型定义,所有这些都将在本章中进行解释。 它们在某些(但不是全部)允许表达式的上下文中有效,特别是在⟨program⟩的最外层和⟨body⟩的开头。

这就是为什么define 允许在过程定义的主体中,但不允许出现在条件表达式的子句的结果中,因为它不是主体。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-12-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-19
    • 1970-01-01
    • 1970-01-01
    • 2016-07-23
    相关资源
    最近更新 更多