Order argument parameters in Lisp

I am interested in the swap-arg operator, which takes as input signal 1) a function f of n variables and 2) an index k, and then returns the same function, except for the first and kth input, the variables are swapped. for example (in mathematical notation):

(swap-arg (f, 2)) (x, y, z, w) = f (z, y, x, w)

Now my first idea is to implement this with rotatef as follows:

(defun swap-args (fk) 
  (lambda (L) (f (rotatef (nth k L) (car L)))))

However, this seems inelegant since it uses rotatef on input. Furthermore, it is O (n) and may be O (n ^ 2) in practice if applied repeatedly to reindex everything.

This seems like a common problem that people have already thought about, but I could not find anything. What a good way to replace data like this? Is there a standard method that people use?

+3
source share
2 answers

Using APPLY:

(defun create-swapped-arg-function (f k)
  "Takes as input a function f of n variables and an index k.
Returns returns a new function with the first and kth input variables swapped,
which calls the function f."
  (lambda (&rest args)
    (apply f (progn
                (rotatef (nth k args) (first args))
                args))))

Example:

CL-USER 5 > (funcall (create-swapped-arg-function #'list 2) 0 1 2 3 4 5 6)
(2 1 0 3 4 5 6)

Another way to do this is to create the source code for such a function, compile it at runtime, and return it. This would be useful if these functions were not created often, but often called.

+3
source

For completeness only, functions can also accept keyword arguments (named) using this function, which can be called with any order of keyword arguments.

+2

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


All Articles