2017-06-19 101 views
1

是否可以重寫下面的表達式,以便(foo)只出現一次?現在它並不可怕,但是這些重複的呼叫(foo)使代碼難以閱讀。簡化條件表達式

(cond 
(a 
    (x) 
    (foo)) 
(b 
    (y) 
    (foo)) 
(else 
    (z) 
    (bar))) 

回答

1

不一定更可讀:)但這會工作。

(cond ((or a b) ((cond (a (x)) (b (y))) (foo)) (else (z) (bar))) 
1

是,

(cond 
    ((cond 
    (a 
     (x) 
     #t) 
    (b 
     (y) 
     #t) 
    (else 
     (z) 
     #f)) (foo)) 
    (else (bar))) 

這不會引入額外的測試,萬一ab是複雜的表達式。

2

我不確定這在技術上是「回答你的問題」,但我不同意對foo的重複調用使代碼「難以閱讀」。事實上,我會聲稱他們讓更容易閱讀。具體來說,在重構版本中,您有條件分支和尾部代碼(對foo的調用)。這意味着作爲讀者,我必須記住,當我閱讀有條件的事實時,會發生更多的事情。更重要的是,在重構代碼中查看foo,我們無法確定在此代碼之前執行了哪些代碼;原來的一個沒有這個問題。

當大塊代碼重複時,會使代碼難以閱讀和易碎。當重複一次調用時,就像這裏一樣,它通常會使代碼更易於閱讀,特別是如果函數具有有意義的名稱。

在這裏,讓我再次縮進,對你:

(cond 
    [a (x) 
    (foo)] 
    [b (y) 
    (foo)] 
    [else (z) 
     (bar)]) 
2

如果(foo)你的意思是複雜的,我建議:

(let() 
    (define (f) (foo)) 
    (cond 
    (a  (x) (f)) 
    (b  (y) (f)) 
    (else (z) (f)))) 

(let ((f (lambda() (foo)))) 
    (cond 
    (a  (x) (f)) 
    (b  (y) (f)) 
    (else (z) (f)))) 
+0

不應該僅僅是'(let((f foo))...'? –

+0

這取決於情況。如果a和b有影響foo的副作用,那麼你會得到不同的結果。 – soegaard

+0

我明白了。我傾向於忘記副作用,因爲我從來沒有使用過它們。 –

1

還有另一個選擇:

(let ((myfoo (lambda (x) (x) (foo)))) 
    (cond (a (myfoo x)) 
     (b (myfoo y)) 
     (else (z) (bar))))