KDB+/Q:表示可变数量参数的规范方法?

KDB+/Q: Canonical method to represent a variable number of arguments?

我正在尝试在 kdb+/q 中创建一个模拟函数,它可以有效地将给定函数替换为记录调用等的函数,即

wrap:{[otherFn;params]
  // update called etc.
  :otherFn[params]
}

// function that replaces target fn
someOtherFn :{show x};

// store reference etc.
// use set to replace function
`.extern.someFn set wrap[someOtherFn];

在这种情况下,.extern.someFn 应该替换为 someOtherFn,并且应该可以这样调用:

q) .extern.someFn[1];
      1

这很好,但是当人们试图增加函数参数的数量时,即

q) .extern.someFn[1;3]; // 
      'rank

表示排名错误。 有人可以告诉我如何达到这种效果吗?谢谢

您收到排名错误,因为上面定义的 .extern.someFn 是单个变量的函数。如果你想将 .extern.someFn 应用于多个输入,你可以使用迭代器:

q).extern.someFn each 1 3;

编辑:您可能对以下内容感兴趣:

q)functionWrapper:{[f;args] f . args};
q)testFunction:{x*y};
q)wrappedFunction:functionWrapper[testFunction];
q)wrappedFunction[2 3]
6

注意:args 需要是一个列表。多个参数不以 semi-colons 分隔。在混合列表的一般情况下,以 args:(arg1;arg2;...)

的形式指定 args

做这样的事情有几个(可以说是有效的*)理由。有一天我会在 q

中写一个 printf 替换

最简单的方法是将两个技巧与组合和入伍相结合。

首先入伍的是varadic:

enlist[1;2]
1 2

然后可以使用组合将函数组合在一起。我认为最接近您想要的是:

makeWrapFunc:{[f] (
callerfunc:{[f;params] f . params}f;
'[callerfunc;enlist]
}

现在,无论包装函数的级别如何,enlist 都会在应用之前为您将这些参数捆绑到一个列表中。

出于几乎相同的目的,我在下面的代码中使用了这个技巧。在我的例子中,我想通过现有函数和替换函数 运行 一些输入,并记录输出以供以后比较。 https://github.com/darrenarmstrong85/scientist/blob/master/lib/init.q#L97

有一些方法可以通过检查包装函数的参数数量并使用 null 进行绑定来将其扩展为部分应用程序,但我将把它留作 reader 的练习:-)

* 可以说这也是调试的噩梦。警告开发者。