在Lisp中重新排序函数参数

时间:2010-10-23 09:51:33

标签: input lisp arguments swap

我对一个运算符“swap-arg”感兴趣,它接受输入1)n个变量的函数f,和2)索引k,然后返回一个相同的函数,除了第一个和第k个输入变量交换。例如(用数学符号表示):

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

然而,这似乎不优雅,因为它在输入上使用了rotatef。此外,它是O(n),如果反复应用以重新索引所有内容,实际上可能是O(n ^ 2)。

这似乎是人们已经考虑过的常见问题,但我找不到任何东西。交换这样的输入有什么好方法?人们使用标准方法吗?

2 个答案:

答案 0 :(得分:3)

使用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)

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

答案 1 :(得分:2)

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