问题描述
q编程语言具有一项功能(this tutorial称为“函数投影”),其中可以使用比所需数量少的参数来调用两个或多个参数的函数,但结果是中间对象,并且直到所有其余参数都通过后,该函数才会执行;一种查看方法是函数的行为类似于多维数组,因此(f[x])[y]
等效于f[x;y]
。例如...
q)add:{x+y}
q)add[42;]
{x+y}[42;]
q)add[42;][3]
45
q)g:add[42;]
q)g[3]
45
由于q没有词法作用域,因此此功能通过将必要的变量作为部分参数列表传递给内部函数来获得词法作用域行为变得非常有用。例如可以使用此功能构造打印参数装饰器:
q)printParameterDecorator:{[f] {[f;x] -1 "Input: ",string x; f x}f};
q)f: printParameterDecorator (2+);
q)f 3
Input: 3
5
我的问题:
解决方法
术语“功能投影”是标准术语吗?还是在功能编程文献中此功能使用其他名称?
不,您通常将其称为partial application。
是否有各种LISP实现此功能?哪一个?
实际上,所有Lisp都允许您部分应用函数,但是通常您需要显式地编写闭包。例如在Common Lisp中:
(defun add (x y)
(+ x y))
alemandria 中的实用函数curry
可用于创建闭包:
USER> (alexandria:curry #'add 42)
#<CLOSURE (LAMBDA (&REST ALEXANDRIA.1.0.0::MORE) :IN CURRY) {1019FE178B}>
USER> (funcall * 3) ;; asterisk (*) is the previous value,the closure
45
产生的关闭等效于以下内容:
(lambda (y) (add 42 y))
某些功能语言(例如OCaml)仅允许函数具有单个参数,但是在语法上,您可以定义多个参数的函数:
(fun x y -> x + y)
以上等同于:
(function x -> (function y -> x + y))
另请参阅What is the difference between currying and partial application?
Nb。实际上,q documentation将其称为部分应用:
,符号上,投影是部分应用程序,其中提供了一些参数,而省略了其他参数
我认为这是另一种方式:
q)f:2+
q)g:{"result: ",string x}
q)'[g;f]3
"result: 5"
这是复合函数,将3传递给f,然后将f的结果传递给g。 我不确定是否是LISP,但是它可以达到相同的结果。