很容易表达and
,or
和(not
在if
本地绑定的帮助下or
)。我想知道反过来是不是真的。我天真的第一次尝试:
(if test conseq altern) => (or (and test conseq) altern)
但是,如果test
是 非#f
并且conseq
是#f
,则翻译结果为altern
,这是不正确的。
是否有一个翻译可以评估为正确的值,同时保持 的短路性质if
?
很容易表达and
,or
和(not
在if
本地绑定的帮助下or
)。我想知道反过来是不是真的。我天真的第一次尝试:
(if test conseq altern) => (or (and test conseq) altern)
但是,如果test
是 非#f
并且conseq
是#f
,则翻译结果为altern
,这是不正确的。
是否有一个翻译可以评估为正确的值,同时保持 的短路性质if
?
听起来您有一个很好的解释,为什么if
要做的比and
和多一点or
。但是,如果您可以作弊并添加 alambda
以延迟实际结果:
(define-syntax-rule (if c t e) ((or (and c (lambda () t)) (lambda () e))))
尝试(or (and test conseq) (and (not test) altern))
作为一般模式。通过test
在第二个中取反and
,它确保外部析取将是conseq
∨#f
如果test
为真,或#f
∨altern
如果test
为假。
这与 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 中添加语法的原因。