Christopher D. Long
Christopher D. Long

Reputation: 326

Function Return an Associative Array

How can you have a function return an associative array in Chapel? This is what's natural, but doesn't seem to work:

type keys = domain(int);
type arr = [keys] int;

proc factor(q): arr {
...
}

The error output I get is:

error: unresolved call 'chpl__ensureDomainExpr(type DefaultAssociativeDom(int(64),true))'
$CHPL_HOME/modules/internal/ChapelArray.chpl:642: note: candidates are: chpl__ensureDomainExpr(const ref x: domain)
$CHPL_HOME/modules/internal/ChapelArray.chpl:649: note:                 chpl__ensureDomainExpr(x ...)

Upvotes: 4

Views: 374

Answers (1)

mppf
mppf

Reputation: 1845

Here is a working program that does this:

proc returnsAssocArray() {
  var AssocDom:domain(int);
  var AssocArray:[AssocDom] int;
  AssocArray[1] = 100;
  return AssocArray;
}

var A = returnsAssocArray();
for (key,value) in zip(A.domain, A) {
  writeln("A[", key, "] = ", value);
}

The above is the pattern that I would use and probably does what you want.

Note that arrays and domains in Chapel have a runtime relationship, and that the type of an array includes the runtime domain. So while the code you posted might one day work, generally speaking to specify an array type one needs to specify a domain that is available at runtime.

Supposing you wished to share a single domain (aka set of keys) among all of the associative arrays returned, you could do this:

var AssocDom:domain(int);
AssocDom += 1; // add index 1 to the associative domain
type AssocArrayType = [AssocDom] int;

proc returnsAssocArray(): AssocArrayType {
  var AssocArray:AssocArrayType;
  AssocArray[1] = 100;
  return AssocArray;
}

var A = returnsAssocArray();
for (key,value) in zip(A.domain, A) {
  writeln("A[", key, "] = ", value);
}

But, if returnsAssocArray wanted to add 2 to the domain (say), things might not work as you expect:

  • adding 2 to AssocDom will resize any other arrays created over that domain
  • just doing AssocArray[2] = 100 will add to the domain only if there are no other arrays sharing that domain.

It's likely that future versions of Chapel will have a Map type to simplify such use cases and present a more familiar interface for maps. Additionally, the rule about adding to the associative domain if no other arrays share it may well go away.

Upvotes: 4

Related Questions