有没有办法在Chapel中where子句的函数中使用非标量值?

时间:2018-04-23 23:15:32

标签: chapel

过去一年左右,我一直在尝试Chapel。我过去曾经简单地使用过C和C ++,但我最近的经验是使用Python,Ruby和Erlang这样的动态语言。

在接触到Erlang及其功能条款之后,我很高兴能够找到Chapel中的子句。但是,我在使用它时遇到了障碍。在Y分钟内学习Chapel包含以下代码,演示如何使用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子句的用处是有限的。

1 个答案:

答案 0 :(得分:4)

  

我有什么遗漏会导致这种情况发生......?

是的,问题在于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索引表达式可以被视为完全展开循环:

{
  param n = 1;
  whereProc(n);
}
{
  param n = 2;
  whereProc(n);
}
...
{
  param n = 10;
  whereProc(n);
}

因此,当类型可能从一个迭代到下一个迭代(如异构元组)不同时,这可能是迭代事物的有用习惯。