2011-02-07 4 views
3

私は2つの値のMAXか2つの値のMINを返すLisp関数を持っています。今、私のコードにはVALUE1とVALUE2を評価するための比較的複雑な表現がいくつかあります。Lisp関数を減らすのを助ける

(defun treemax (bilist &optional ismin) 
    (cond 
    ;; Compute minimum 
    (ismin (min (COMPLEX_EXPRESSION_1) (COMPLEX_EXPRESSION_2))) 
    ;; Compute maximum 
    (t (max (COMPLEX_EXPRESSION_1) (COMPLEX_EXPRESSION_2))))) 

ここでの問題はCOMPLEX_EXPRESSION_1とCOMPLEX_EXPRESSION_2は、実際のコードの多くの多くの行を取るということです。私は本当にそれらを繰り返さないようにしたいと思います。これを呼び出すより効率的な方法がありますか?

私がしようとしているのは、値ではなく単項のif on関数です。あなたがCまたはその変種に精通している場合は、基本的に私が探しているコンセプトは次のとおりです。

((ismin ? min : max) COMPLEX_EXPRESSION_1 COMPLEX_EXPRESSION_2) 

私は条件付きに引数を送信するために機能するかを選択します。これは理にかなっていますか?

+1

私はコードで正確な答えを推測しようとはしませんので、私は、Lispの構文を覚えていませんが、あなたへの答えは、「そこには、より効率的な方法のですこれを呼びますか? "質問は「絶対にはい」です。結果としてminまたはmax関数を返す関数を作成する必要があります。 – DVK

答えて

9
(defun treemax (bilist &optional ismin) 
    (funcall (if ismin #'min #'max) 
      (COMPLEX_EXPRESSION_1) 
      (COMPLEX_EXPRESSION_2))) 
+0

この回答で2kを破ることにおめでとう! :-D –

+0

@Chris Jester-Young:ありがとう、私はかなりのためにそれを保存していた:) – zakovyrya

0

これはLispが非常に優れていることの1つです。関数を変数に代入して、applyまたはfuncallでそれらに引数を渡すことができます(Schemeでは、実際にはさらに簡単です)。ここでは例です:

(defun treemax (bilist &optional ismin) 
    (let ((op (if ismin #'min #'max))) 
    (funcall op (COMPLEX_EXPRESSION_1) (COMPLEX_EXPRESSION_2)))) 

(。あなたはもちろん、単に変数にCOMPLEX_EXPRESSION_1COMPLEX_EXPRESSION_2を結合することができるが、それはまだ多くの繰り返しを作成します)

9

は確かに、これは良いです:

(defun treemax (bilist &optional (op #'max)) 
    (funcall op (COMPLEX_EXPRESSION_1) (COMPLEX_EXPRESSION_2))) 

代わりにminを使用する場合は、引数2として#'minを渡します。

(もちろん、zakovyryaの答えはあまりにも動作します。)一般的に

2

、あなたは、複数回同じコードを記述したコードをキャプチャして、複数回、それを呼び出すための関数を使用する必要がある場合。

(defun treemax (bilist &optional ismin) 
    (cond 
    (ismin (min (COMPLEX_EXPRESSION_1) (COMPLEX_EXPRESSION_2))) 
    (t  (max (COMPLEX_EXPRESSION_1) (COMPLEX_EXPRESSION_2))))) 

- >

(defun treemax (bilist &optional ismin) 
    (flet ((f1() (COMPLEX_EXPRESSION_1)) 
     (f2() (COMPLEX_EXPRESSION_2)))) 
    (cond 
     (ismin (min (f1) (f2))) 
     (t  (max (f1) (f2)))))) 
関連する問題