4

很容易表达and,or和(notif本地绑定的帮助下or)。我想知道反过来是不是真的。我天真的第一次尝试:

(if test conseq altern) => (or (and test conseq) altern)

但是,如果test是 非#f并且conseq#f,则翻译结果为altern,这是不正确的。

是否有一个翻译可以评估为正确的值,同时保持 的短路性质if

4

3 回答 3

5

听起来您有一个很好的解释,为什么if要做的比and和多一点or。但是,如果您可以作弊并添加 alambda以延迟实际结果:

(define-syntax-rule (if c t e) ((or (and c (lambda () t)) (lambda () e))))
于 2011-02-04T16:27:52.417 回答
2

尝试(or (and test conseq) (and (not test) altern))作为一般模式。通过test在第二个中取反and,它确保外部析取将是conseq#f如果test为真,或#faltern如果test为假。

于 2011-02-04T16:47:45.460 回答
1

这与 Eli Barzilay 的回答相同,只是我没有将其包装在 lambda 中,而是将其包装在 1 元素列表中

(if test conseq altern) => (car (or (and test (list conseq)) (list altern)))

顺便说一句,2.5 之前的 Python 就有这个问题。在 Python中没有很好的方法来编写条件表达式(即test ? conseq : altern在 C 中,if在 Scheme 中就是这样)。最简单的尝试是

test and conseq or altern

这在大多数情况下都有效,但conseq在 Python 中被认为是错误的(即 False、0、空列表、空字符串等)时失败。这是您在上面发现的确切问题。修复方法是将其包装在一个列表中(非空列表始终为真)并再次提取它:

(test and [conseq] or [altern])[0]

看起来很难看。这就是他们conseq if test else altern在 Python 2.5 中添加语法的原因。

于 2011-02-04T19:28:03.303 回答