帮助减少Lisp功能

帮助减少Lisp功能,lisp,common-lisp,Lisp,Common Lisp,我有一个Lisp函数,它返回两个值中的最大值或两个值中的最小值。现在,我的代码有一些相对复杂的表达式来计算VALUE1和VALUE2 (defun treemax (bilist &optional ismin) (cond ;; Compute minimum (ismin (min (COMPLEX_EXPRESSION_1) (COMPLEX_EXPRESSION_2))) ;; Compute maximum (t (max (COMPLEX_

我有一个Lisp函数,它返回两个值中的最大值或两个值中的最小值。现在,我的代码有一些相对复杂的表达式来计算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)))))
这里的问题是,复数表达式1和复数表达式2实际上占用了很多行代码。我真的不想重复。有没有更有效的方法来称呼这个

基本上,我想做的是一元if函数,而不是值。如果您熟悉C或其变体,那么我要寻找的基本概念是:

((ismin ? min : max) COMPLEX_EXPRESSION_1 COMPLEX_EXPRESSION_2)

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

这是Lisp非常擅长的事情之一。您可以将函数分配给变量,然后使用
apply
funcall
将参数传递给它们(在Scheme中,这实际上更容易)。下面是一个例子:

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

(当然,您也可以将
复杂表达式\u 1
复杂表达式\u 2
绑定到变量,但这仍然会产生更多的重复。)

当然,这样更好:

(defun treemax (bilist &optional (op #'max))
  (funcall op (COMPLEX_EXPRESSION_1) (COMPLEX_EXPRESSION_2)))
然后,如果您想使用
min
,只需将
#'min
作为参数2传入即可


(当然,zakovyrya的答案也适用。)

通常,如果您需要多次编写相同的代码,请使用函数捕获代码,然后多次调用它

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


我不记得Lisp语法,所以我不会试图用代码猜出确切的答案,但是对于“有没有更有效的方法来调用它?”的问题,答案是“绝对有”。您需要创建一个返回最小或最大函数的函数。祝贺您用这个答案打破2k!:-D@Chris杰斯特·杨:谢谢,我把它省了不少钱:)
(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))))))