Chapel: Unexpected behavior on domain.find() method

Created on 12 Feb 2018  路  3Comments  路  Source: chapel-lang/chapel

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)
Libraries / Modules user issue

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.

All 3 comments

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?");
}
Was this page helpful?
0 / 5 - 0 ratings