If it's empty, it will not return "false". Check it!
var names: domain(string);
var f1 = names.find("bob");
writeln(f1);
if !f1(1) {
writeln("Bob?");
}
names += "bob";
var f2 = names.find("bob");
writeln(f2);
var f3 = names.find("chuck");
writeln(f3);
if !f3(1) {
writeln("Chuck?");
}
Gives you
fnd.chpl:5: error: halt reached - array index out of bounds: (1)
I believe the problem is that names.find
is turning into a promoted expression, because string
has a find
method. The type of f1
is an array of integers.
The expression is really turning into something like:
var f1 : [1..0] int;
for n in names do f1.push_back(n.find("bob"));
In this case names
has zero indices, so f1
has zero elements. This leads to the out-of-bounds error.
I think it would be fair to say "that's really confusing". I've wondered in the past if promotion is sometimes too easy to slip into.
I agree that this is pretty confusing, but I don't think it's a bug. There is no domain.find()
method. The method you expected to call here was array.find()
, but the receiver should have been an array, not a domain.
Since there is no domain.find()
method, the only candidate function for this call is the promoted version of string.find()
, so it is chosen and called.
To test if an index is in a domain, you can use domain.member(index)
.
Here's the original example rewritten to use domain.member()
.
var names: domain(string);
var f1 = names.member("bob");
writeln(f1);
if !f1 {
writeln("Bob?");
}
names += "bob";
var f2 = names.member("bob");
writeln(f2);
var f3 = names.member("chuck");
writeln(f3);
if !f3 {
writeln("Chuck?");
}
Most helpful comment
I think it would be fair to say "that's really confusing". I've wondered in the past if promotion is sometimes too easy to slip into.