Help shorten Lisp function

I have a Lisp function that returns either MAX of two values, or MIN of two values. Right now, my code has relatively complex expressions for evaluating VALUE1 and 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)))))

The problem is that COMPLEX_EXPRESSION_1 and COMPLEX_EXPRESSION_2 actually occupy many different lines of code. I would really like not to repeat them. Is there a more efficient way to call it?

Essentially, I'm trying to do this, but not for values, but for unary if functions. If you are familiar with C or its variants, then, in fact, I'm looking for:

((ismin ? min : max) COMPLEX_EXPRESSION_1 COMPLEX_EXPRESSION_2)

At the same time, I conditionally choose which function to send arguments to. It makes sense?

+3
source share
4 answers
(defun treemax (bilist &optional ismin)
    (funcall (if ismin #'min #'max) 
             (COMPLEX_EXPRESSION_1) 
             (COMPLEX_EXPRESSION_2)))
+9
source

Of course, this is better:

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

#'min 2, min.

(, .)

+9

, , , .

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

This is one of the things Lisp is very good at. You can assign functions to variables and then pass arguments to them with applyor funcall(and in the diagram, this is actually even simpler). Here is an example:

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

(Of course, you could just bind variables COMPLEX_EXPRESSION_1and COMPLEX_EXPRESSION_2variables, but it will still create more repetitions.)

0
source

Source: https://habr.com/ru/post/1790545/


All Articles