2017-06-19 12 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))) 

これはケースaまたはbに、追加検査を導入しない複雑な式です。

2

これは技術的に「あなたの質問に答える」とは確信していませんが、fooへの呼び出しを繰り返すと「読みにくい」というコードになります。確かに、私は彼らがそれをより容易にすると主張するでしょう読むべきです。具体的には、リファクタリングされたバージョンでは、後続のコード(fooの呼び出し)を持つ条件分岐があります。これは、後でもっと多くのことが起こるという事実を条件付きで読んでいる間、読者として私は心に留めなければならないことを意味します。さらに重要なことに、リファクタリングされたコードのfooを見ると、このコードの前にどのコードが実行されたのかを確認することはできません。元のものにはこの問題はありませんでした。

大きなコードブロックが繰り返されると、コードが読みにくく壊れやすくなります。ここでのように、1回の呼び出しが繰り返されると、特に関数が意味のある名前を持つ場合は、コードを読みやすくなります。ここで

は、私はあなたのためのことを字下げしましょう:

(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)))) 
関連する問題