20175, "lydia-duncan", "FCF fields and the nothing type", "2022-07-07T22:22:19Z"
Summary of Problem
I tried making a field that stores a first class function use the nothing
type and the compiler was unhappy. It outputs the following:
saveInField-nothing.chpl:10: In initializer:
saveInField-nothing.chpl:11: error: could not find a copy initializer ('init=') for type 'shared chpl__fcf_type_int64_t_chpl_bool' from type 'nothing'
$CHPL_HOME/modules/internal/SharedObject.chpl:255: note: this candidate did not match: _shared.init=(pragma"nil from arg"in take: owned)
saveInField-nothing.chpl:11: note: because actual argument #1 with type 'nothing'
$CHPL_HOME/modules/internal/SharedObject.chpl:255: note: is passed to formal 'in take: owned'
saveInField-nothing.chpl:11: note: other candidates are:
$CHPL_HOME/modules/internal/SharedObject.chpl:281: note: _shared.init=(pragma"nil from arg"const ref src: _shared)
$CHPL_HOME/modules/internal/SharedObject.chpl:303: note: _shared.init=(src: borrowed)
note: and 2 other candidates, use --print-all-candidates to see them
The details block has the actual scenario that motivated me to find this, for the curious:
I was playing around with storing a hasher function in my attempt at the DistributedMap implementation (so that users can have control over which locale the key hashes to). Because the key and value type fields make any hashing of them generic, I can't write a default function to use that lives outside of the DistributedMap type, and I can't make a field that stores a fcf of a method, because the field initialization doesn't know about the methods on the type yet. So what I was hoping to do was have the hasher field be set to `none` when it is relying on the default hasher function and just call a method I've defined instead. That ran into this problem, which I've boiled down into a simpler test case.
Steps to Reproduce
Source Code:
record Foo {
var funcStored = false;
var funcField: func(int, bool) = none;
proc init(x: func(int, bool)) {
funcStored = true;
funcField = x;
}
proc init() {
this.complete();
}
proc callTheField(arg: int) {
if (funcStored) {
if (funcField(arg)) {
writeln("fcf with arg ", arg, " successful");
} else {
writeln("fcf with arg ", arg, " unsuccessful");
}
} else {
writeln("no fcf stored");
}
}
}
proc bar(x: int): bool {
if (x * 3 > 15) {
return true;
} else {
return false;
}
}
var f1 = new Foo(bar); // field is a fcf
f1.callTheField(2);
f1.callTheField(6);
var f2 = new Foo(); // field is none
f2.callTheField(17);
Compile command:
chpl foo.chpl
Execution command:
N/A
Associated Future Test(s):
test/functions/firstClassFns/saveInField-nothing.chpl
#TBD
Configuration Information
- Output of
chpl --version
: 1.28.0 (pre-release)