帮助减少Lisp函数

时间:2011-02-07 20:34:43

标签: lisp common-lisp

我有一个Lisp函数,它返回两个值的MAX或两个值的MIN。现在我的代码有一些相对复杂的表达式来评估VALUE1和VALUE2。

(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)

由此我有条件地选择将参数发送到哪个函数。这有意义吗?

4 个答案:

答案 0 :(得分:9)

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

答案 1 :(得分:9)

当然,这更好:

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

然后,如果您想使用#'min,只需将min作为参数2传递。

(当然,zakovyrya的答案也有效。)

答案 2 :(得分: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))))))

答案 3 :(得分: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绑定到变量,但这仍会产生更多重复。)