根据and
(or
的本地绑定的帮助)来表达not
,if
和or
很容易。我想知道反过来是否正确。我天真的第一次尝试:
(if test conseq altern) => (or (and test conseq) altern)
但是,如果test
不是#f
且conseq
是#f
,则翻译的结果为altern
,这是不正确的。
是否存在评估为正确值的转换,同时保持if
的短路性质?
答案 0 :(得分:4)
听起来你有一个很好的解释,为什么if
的作用比and
和or
多一点。但是如果你可以作弊并添加lambda
来推迟实际结果:
(define-syntax-rule (if c t e) ((or (and c (lambda () t)) (lambda () e))))
答案 1 :(得分:2)
尝试(or (and test conseq) (and (not test) altern))
作为一般模式。通过否定第二个test
中的and
,如果conseq
为真,则确保外部分离为#f
∨test
,或#f
如果altern
为假,则{∨test
。
答案 2 :(得分:1)
这与Eli Barzilay的答案相同,除了将其包装在lambda中之外,我将其包装在1个元素的列表中
(if test conseq altern) => (car (or (and test (list conseq)) (list altern)))
顺便说一下,2.5之前的Python有这个确切的问题。没有很好的方法可以在Python中编写条件表达式(即C中的test ? conseq : altern
,这是Scheme中的if
)。最简单的尝试是
test and conseq or altern
在大多数情况下有效,但在Python中conseq
被视为false时失败(即False,0,空列表,空字符串等)。这是您在上面发现的确切问题。修复是将它包装在一个列表中(非空列表始终为true)并再次提取它:
(test and [conseq] or [altern])[0]
看起来很难看。这就是为什么他们在Python 2.5中添加了语法conseq if test else altern
。