(if <predicate> <consequent> <alternative>)
(cond (<p1> <e1>)
(<p2> <e2>)
..........
(<pn> <en>))
if和cond之间的一个小区别是,cond__'s表达式部分在cond子句中可能是一个表达式序列.
我想知道为什么方案语言的设计者使if和cond的表达式不同。
这个设计的目的是什么?
发布于 2022-10-02 12:17:55
在一种并非纯功能性的语言中,允许在语法上有空间的情况下使用一系列表达式通常是有用的:例如,在一个过程的主体中,等等。因此,例如,纯函数式Lisp可能有一个函数的语法,
(λ (<arg> ...)
<expression>)但是计划允许
(λ (<arg> ...)
<expression-1>
<expression-2>
...)除了最后一个表达式之外,所有的值都被忽略了:它们只是因为副作用而发生。而且由于语法上有这方面的空间,Scheme允许这样做。
但是,在if的语法中,根本就没有这种情况的空间(见下文)。
在语法没有空间的情况下设计多向条件表达式是可能的,这可能是这样的:
(kond
a 1
b 2
c 3
else 4)例如,(在这里,else对kond是神奇的:我不记得SICP的方案是否有此功能)。
但是,如果您考虑一下cond的实际语法是什么:
(cond
(a 1)
(b 2)
(c 3)
(else 4))然后很明显,现在语法上有空间在每个子句的结果位置上写一个表达式序列。因此,计划容许这样做,因为根本没有理由不这样做。所以而不是
(cond
(<t> <e>)
...)你可以写
(cond
(<t> <e1> <e2> ...)
...)例如:
(cond
(world-has-ended
(displayln "The world has ended: rain of fire imminent")
(rain-fire-from-sky 'yes-really))
...)实际上,Scheme有一个操作符,begin,它的全部目的是允许只允许一个表达式序列。因此,例如,如果您想拥有一个表达式序列(其中自然只有一个),则可以使用begin
(if world-has-ended
(begin
(displayln "The world has ended: rain of fire imminent")
(rain-fire-from-sky 'yes-really))
(begin
(displayln "World has not yet ended, sorry for the frogs")
(rain-frogs-from-sky)))然后,您可以将cond定义为if和begin。
(cond
(world-has-ended
(displayln "The world has ended: rain of fire imminent")
(rain-fire-from-sky 'also-rocks))
(world-has-nearly-ended
(displayln "The world has nearly ended")
(rain-frogs-from-sky 'also-some-fire)))是相同的
(if world-has-ended
(begin
(displayln "The world has ended: rain of fire imminent")
(rain-fire-from-sky 'also-rocks))
(if world-has-nearly-ended
(begin
(displayln "The world has nearly ended")
(rain-frogs-from-sky 'also-some-fire))
#f))至于为什么cond的语法被设计成有多个表达式的空间:这是一个历史问题。我认为有两件事有助于解释:
(cond <t1> <e1> <t2> <e2> ...)这样的语法很难阅读,因为您需要计算身体中的表单数量,而(cond (<t1> ...) (<t2> ...) ...)则要容易得多。cond的语法允许这样做。发布于 2022-10-02 12:17:41
如果允许在if中使用任意数量的表达式,如何判断真正的表达式何时结束,而假的表达式是什么时候开始的?对于cond,每一种情况都是一个列表,其中第一个元素是测试表达式,而列表的其余部分则在为true时得到计算。没有歧义。
1:使用begin
(if <test>
(begin <true exprs> ...)
(begin <false exprs> ...))cond通常是一个扩展为
(if <p1>
(begin <e1>)
(if <p2>
(begin <e2>)
...))发布于 2022-10-03 14:48:54
cond 在Scheme中有隐式,这是由于60年代LISP!的母语言中的意外设计造成的。
如果不是设计cond或if的方案的设计者。cond是McCarhty论文的原始条件,他的eval不支持多个后续表达式。基本上,如果你要写一个以上的结果,它只会做第一个。if在那篇文章中并不存在,而且自从它拥有算术if之后,它在Fortran中也不存在。
在括号中包装每个术语是为lisp的新版本打开的,它实际上允许多个后续的结果,最后一个是尾表达式。想象一下,他并没有这么做,而是提出了这样的建议:
; a and c are predicates
(cond a b
c d
t e)问题在于,只有我的格式才能帮助确定什么是什么。如果我把它写成一行,几乎不可能读到这段简单的简短代码:
(cond a b c d t e)加入父母是一种把属于自己的东西组合在一起的方法。当if出现时,它不支持相同形式的两个分支,当lisp变得命令式时,progn cond由于意外设计而隐式,而if需要progn形式,因此只保留了3个操作数。
你可能对lisp的根感兴趣
顺便说一句。我的平面cond示例非常类似于Paul的lisp语言弧中if的实现:
(if p1 c1
p2 c2
c3)https://stackoverflow.com/questions/73925436
复制相似问题