Input Lisp中函数参数的重新排序

Input Lisp中函数参数的重新排序,input,lisp,arguments,swap,Input,Lisp,Arguments,Swap,我对一个操作符“swap arg”感兴趣,它将1)一个包含n个变量的函数f和2)索引k作为输入,然后返回一个相同的函数,除了交换第一个和第k个输入变量。例如(用数学表示法): (交换参数(f,2))(x,y,z,w)=f(z,y,x,w) 现在我的第一个想法是使用rotatef实现它,如下所示 (defun swap-args (f k) (lambda (L) (f (rotatef (nth k L) (car L))))) (取消交换参数(f k) (lambda(L)(f(rota

我对一个操作符“swap arg”感兴趣,它将1)一个包含n个变量的函数f和2)索引k作为输入,然后返回一个相同的函数,除了交换第一个和第k个输入变量。例如(用数学表示法):

(交换参数(f,2))(x,y,z,w)=f(z,y,x,w) 现在我的第一个想法是使用rotatef实现它,如下所示

(defun swap-args (f k) (lambda (L) (f (rotatef (nth k L) (car L))))) (取消交换参数(f k) (lambda(L)(f(rotatef(nth k L)(car L‘‘‘)’)) 然而,这似乎不雅观,因为它在输入上使用rotatef。另外,它是O(n),如果反复应用以重新索引所有内容,实际上可能是O(n^2)

这似乎是人们已经考虑过的一个常见问题,但我什么也没找到。像这样交换输入的好方法是什么?是否有人们使用的标准方法?

使用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))))
例如:

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

另一种方法是为这样一个函数构建源代码,在运行时编译并返回它。如果这些函数不是经常创建的,而是经常调用的,这将非常有用。

为了完整性,函数也可以使用关键字(命名)参数,使用此函数,可以使用其关键字参数的任意顺序调用函数。

您的函数f不是n个变量。在你的例子中,它是作为一个单参数函数调用的。我想你是对的,它以列表作为参数。我们可以这样称呼它,(f(xyzw))我不想这样称呼它,一些交换文字参数的东西,例如(fxyzw)->(fzyxw)也不错。如果x是一个函数,你可以这样称呼它。如果没有,你会得到一个错误。这基本上就是我在OP中试图写的,除了没有bug。(:尽管如此,问题仍然存在-这是O(N),因为调用了N'th,并且在输入上使用了rotatef,这将改变它们(如果我理解正确的话)@mazemaster255:使用FUNCALL调用时不会更改输入。使用APPLY调用时可能会更改输入。如果要避免这种情况,请使用复制列表创建一个新的复制列表。当然,在运行时速度会很慢。请参阅我答案的最后一段以了解其他方法。
CL-USER 5 > (funcall (create-swapped-arg-function #'list 2) 0 1 2 3 4 5 6)
(2 1 0 3 4 5 6)