2011-02-04 66 views
4

根據if(在or的本地綁定的幫助下),很容易表達and,ornot。我想知道是否相反。我天真的第一次嘗試:在Scheme中,如果可以表示爲布爾運算符的組合?

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

但是,如果test是非#fconseq#f,翻譯結果爲altern,這是不正確。

是否有翻譯結果在保持if的短路特性的前提下達到了正確的數值?

+0

也許(或(和test(或conseq #t))交替)? – knivil 2011-02-04 16:06:11

+0

啊,但是`(如果#t #f #t)`會評估爲`#t`。不過,這些都是我正在考慮解決它的那種技巧。 – acfoltzer 2011-02-04 16:13:26

回答

4

聽起來像你有一個很好的解釋爲什麼if做的比andor多一點點。但是,如果你能欺騙並添加lambda推遲實際結果:

(define-syntax-rule (if c t e) ((or (and c (lambda() t)) (lambda() e)))) 
+0

不錯;我喜歡增加一絲懶惰的想法。有沒有作弊可能會有什麼想法? – acfoltzer 2011-02-04 19:21:12

2

嘗試(or (and test conseq) (and (not test) altern))的一般模式。通過在第二and否定test,它確保外脫節將conseq#f如果任test爲真,或#faltern如果test是假的。

1

這是一樣的禮Barzilay的答案,但不是在一個lambda包裝它,我在1元列表

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

順便說包裹它,Python的2.5之前有這種確切的問題。沒有好的方法來編寫條件表達式(即C中的test ? conseq : altern,這是Scheme中的if)。最簡單的嘗試是

test and conseq or altern 

在大多數情況下工作,但失敗時conseq在Python被認爲是假的(即假,0,空單,空字符串,等等)。這是你在上面發現的確切問題。此修復程序是包裝在一個列表(非空列表總是如此),並再次將其解壓縮:

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

看起來醜陋。這就是爲什麼他們在Python 2.5中添加了語法conseq if test else altern