在 Lisp 中重新排序函数参数

发布于 2024-09-29 10:26:52 字数 423 浏览 4 评论 0原文

我对一个运算符“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)。

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

I'm interested in an operator, "swap-arg", that takes as input 1) a function f of n variables, and 2) index k, and then returns a the same function except with the first and kth input variables swapped. eg (in mathematical notation):

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

Now my first idea is to implement this using rotatef as follows,

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

However, this seems inelegant since it uses rotatef on the input. Also, it's O(n), and could be O(n^2) in practice if applied repeatedly to reindex everything.

This seems like a common problem people would have already considered, but I haven't been able to find anything. What's a good way to swap inputs like this? Is there a standard method people use?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

残疾 2024-10-06 10:26:52

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

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

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 it would be to build the source code for such a function, compile it at runtime and return it. That would be useful if these functions are not created often, but called often.

萌吟 2024-10-06 10:26:52

为了完整起见,函数还可以采用关键字(命名)参数,使用此函数可以以其关键字参数的任意顺序进行调用。

Just for completeness, functions can also take keyword (named) arguments, using this the function can be called with any order of its keyword arguments.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文