The following code fails at compilation (using chapel 1.33):
proc g(a: [] real): real {
var s = 0.0;
for e in a do {
s += e ;
}
return s;
}
proc f(ref a: [] real, const g: proc(x: [] real)) {
if g(a) > 0.0 then {
writeln("sum is positive");
}
else if g(a) == 0.0 then {
writeln("sum is zero");
}
else {
writeln("sum is negative");
}
}
var a = [1.0,2.0,-3.0];
f(a,g);
because a in g is an array argument (from the chapel documentation):
"A function is generic if any of the following conditions hold:
...
The type of some formal argument is an array type where either the
element type is queried or omitted or the domain is queried or
omitted."
Hence g is generic and not a first-class function, and cannot be used as argument in another function f
I have found however that this alternative works fine:
record vla {
var dom: domain(1);
var arr: [dom] real;
proc ref this(k:int) ref {
return arr[k];
}
}
proc g(ref a: vla): real {
var s = 0.0;
for i in a.dom do {
s += a[i];
}
return s;
}
proc f(ref a: vla, const g: proc(ref x: vla)) {
if g(a) > 0.0 then {
writeln("sum is positive");
}
else if g(a) == 0.0 then {
writeln("sum is zero");
}
else {
writeln("sum is negative");
}
}
var a = new vla({1..3},[1.0,2.0,-3.0]);
f(a,g);
This is very useful, since in numerical methods there are times when you need to say something like f(a,g) where a is an array that will be used by g (think of Runge-Kutta to solve systems of ODEs). I think that this approach is good enough for my needs, and may help others as well, so I decided to post it here. Merry Xmas,
Nelson