2011-02-07 117 views
3

我有一个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实际上占用了许多许多行代码。我真的不想重复他们。有没有更有效的方法来调用它?

基本上我想要做的是一个一元 - 如果在函数而不是值。如果你熟悉C或它的变种,基本上我正在寻找的概念是:

((ismin ? min : max) COMPLEX_EXPRESSION_1 COMPLEX_EXPRESSION_2) 

一息尚存,我有条件地选择其工作的参数发送给。这有意义吗?

+1

我不记得Lisp语言的语法,所以我不会尝试去猜测与代码确切的答案,但答案你“有没有更有效的方法打电话给这个?“问题是“绝对是”。您需要创建一个返回min或max函数的函数。 – DVK 2011-02-07 20:46:30

回答

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

恭喜您打破2k这个答案! :-D – 2011-02-07 21:06:07

0

这是Lisp非常擅长的事情之一。您可以将函数分配给变量,然后使用applyfuncall将参数传递给它们(并且在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))))))