我有一个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)
由此我有条件地选择将参数发送到哪个函数。这有意义吗?
答案 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非常擅长的事情之一。您可以将函数分配给变量,然后使用apply
或funcall
将参数传递给它们(在Scheme中实际上更容易)。这是一个例子:
(defun treemax (bilist &optional ismin)
(let ((op (if ismin #'min #'max)))
(funcall op (COMPLEX_EXPRESSION_1) (COMPLEX_EXPRESSION_2))))
(当然,您也可以将COMPLEX_EXPRESSION_1
和COMPLEX_EXPRESSION_2
绑定到变量,但这仍会产生更多重复。)