有没有办法在 Chapel 的 where 子句函数中使用非标量值?
Is there a way to use non-scalar values in functions with where clauses in Chapel?
在过去一年左右的时间里,我一直在断断续续地试用 Chapel。我过去曾短暂地使用过 C 和 C++,但我的大部分经验是使用 Python、Ruby 和最近的 Erlang 等动态语言。
在接触了 Erlang 及其函数子句之后,我很兴奋地发现了 Chapel 中的 where 子句。但是,我 运行 对它们的使用遇到了障碍。在 Y 分钟内学习教堂包含以下代码,演示了 where 子句的用法:
proc whereProc(param N : int): void
where (N > 0) {
writeln("N is greater than 0");
}
proc whereProc(param N : int): void
where (N < 0) {
writeln("N is less than 0");
}
whereProc(10);
whereProc(-1);
这将为两个标量值 10 和 -1 中的每一个生成预期输出。但是,我曾尝试编写在范围或数组上迭代的类似程序。我什至尝试过递归。在所有情况下,我都会得到基本相同的错误:
whereproc2.chpl:12: error: unresolved call 'whereProc(int(64))'
whereproc2.chpl:1: note: candidates are: whereProc(param N: int)
whereproc2.chpl:6: note: whereProc(param N: int)
产生此特定错误的代码是:
proc whereProc(param N : int): void
where (N > 0) {
writeln("N is greater than 0");
}
proc whereProc(param N : int): void
where (N <= 0) {
writeln("N is less than or equal to 0");
}
for n in 1..10 do
whereProc(n);
是否有我遗漏的东西会导致它起作用,或者它是否会起作用?我注意到在 Y 分钟内学习教堂它说所有信息都需要在编译时知道。有限范围或初始化数组的内容在编译时是否未知?在我看来,如果 where 子句仅适用于标量值,它的用处是有限的。
Is there something I'm missing that will cause this to work...?
是的,问题是在你的 for
循环中:
for n in 1..10 do
whereProc(n);
在遍历范围时,循环索引变量 n
是一个执行时常量,这会阻止编译器对其进行推理。为了获得您想要的行为,您需要请求编译器将其设为 param
(编译时常量)。这可以使用语法来完成:
for param n in 1..10 do
whereProc(n);
这具有使 n
成为 param
值的效果,使编译器能够推断其值。 Try this version of the code online(范围更有趣)。
像这样使用参数索引表达式可以看作是完全展开循环:
{
param n = 1;
whereProc(n);
}
{
param n = 2;
whereProc(n);
}
...
{
param n = 10;
whereProc(n);
}
因此,当类型可能从一次迭代到下一次迭代(如异构元组)不同时,这可能是一个有用的习惯用法来迭代事物。
在过去一年左右的时间里,我一直在断断续续地试用 Chapel。我过去曾短暂地使用过 C 和 C++,但我的大部分经验是使用 Python、Ruby 和最近的 Erlang 等动态语言。
在接触了 Erlang 及其函数子句之后,我很兴奋地发现了 Chapel 中的 where 子句。但是,我 运行 对它们的使用遇到了障碍。在 Y 分钟内学习教堂包含以下代码,演示了 where 子句的用法:
proc whereProc(param N : int): void
where (N > 0) {
writeln("N is greater than 0");
}
proc whereProc(param N : int): void
where (N < 0) {
writeln("N is less than 0");
}
whereProc(10);
whereProc(-1);
这将为两个标量值 10 和 -1 中的每一个生成预期输出。但是,我曾尝试编写在范围或数组上迭代的类似程序。我什至尝试过递归。在所有情况下,我都会得到基本相同的错误:
whereproc2.chpl:12: error: unresolved call 'whereProc(int(64))'
whereproc2.chpl:1: note: candidates are: whereProc(param N: int)
whereproc2.chpl:6: note: whereProc(param N: int)
产生此特定错误的代码是:
proc whereProc(param N : int): void
where (N > 0) {
writeln("N is greater than 0");
}
proc whereProc(param N : int): void
where (N <= 0) {
writeln("N is less than or equal to 0");
}
for n in 1..10 do
whereProc(n);
是否有我遗漏的东西会导致它起作用,或者它是否会起作用?我注意到在 Y 分钟内学习教堂它说所有信息都需要在编译时知道。有限范围或初始化数组的内容在编译时是否未知?在我看来,如果 where 子句仅适用于标量值,它的用处是有限的。
Is there something I'm missing that will cause this to work...?
是的,问题是在你的 for
循环中:
for n in 1..10 do
whereProc(n);
在遍历范围时,循环索引变量 n
是一个执行时常量,这会阻止编译器对其进行推理。为了获得您想要的行为,您需要请求编译器将其设为 param
(编译时常量)。这可以使用语法来完成:
for param n in 1..10 do
whereProc(n);
这具有使 n
成为 param
值的效果,使编译器能够推断其值。 Try this version of the code online(范围更有趣)。
像这样使用参数索引表达式可以看作是完全展开循环:
{
param n = 1;
whereProc(n);
}
{
param n = 2;
whereProc(n);
}
...
{
param n = 10;
whereProc(n);
}
因此,当类型可能从一次迭代到下一次迭代(如异构元组)不同时,这可能是一个有用的习惯用法来迭代事物。