【问题标题】:Help reducing a Lisp function帮助减少一个 Lisp 函数
【发布时间】:2011-02-07 20:34:42
【问题描述】:

我有一个 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)))))

这里的问题是 COMPLEX_EXPRESSION_1 和 COMPLEX_EXPRESSION_2 实际上占用了很多很多行代码。我真的不想重复它们。有没有更有效的调用方式?

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

((ismin ? min : max) COMPLEX_EXPRESSION_1 COMPLEX_EXPRESSION_2)

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

【问题讨论】:

  • 我不记得 Lisp 语法,所以我不会尝试用代码猜测确切的答案,而是回答您的“有没有更有效的调用方式?”问题是“绝对是的”。您需要创建一个返回最小值或最大值函数的函数。

标签: lisp common-lisp


【解决方案1】:
(defun treemax (bilist &optional ismin)
    (funcall (if ismin #'min #'max) 
             (COMPLEX_EXPRESSION_1) 
             (COMPLEX_EXPRESSION_2)))

【讨论】:

  • 恭喜你用这个答案打破了 2k! :-D
  • @Chris Jester-Young:谢谢,我已经保存了好久了 :)
【解决方案2】:

当然,这样更好:

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

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

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

【讨论】:

    【解决方案3】:

    一般来说,如果你需要多次编写相同的代码,使用一个函数来捕获代码,然后多次调用它。

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

    【讨论】:

      【解决方案4】:

      这是 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 绑定到变量,但这仍然会产生更多重复。)

      【讨论】:

        猜你喜欢
        • 2021-01-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-10-12
        • 1970-01-01
        • 2012-11-20
        • 2014-07-27
        相关资源
        最近更新 更多