List initialisation

Hello,

This code:

var lst3 : list(list(string)) = [["this", "that", "the other"],["one","two","three"]];

triggers a compilation error:

$CHPL_HOME/modules/standard/List.chpl:519: In method '_commonInitFromIterable':
$CHPL_HOME/modules/standard/List.chpl:522: error: unresolved call 'list(list(string,false),false).pushBack([domain(1,int(64),one)] string)'
$CHPL_HOME/modules/standard/List.chpl:890: note: this candidate did not match: ref list.pushBack(other: [?d] eltType)
$CHPL_HOME/modules/standard/List.chpl:890: note: because an argument was incompatible
$CHPL_HOME/modules/standard/List.chpl:522: note: other candidates are:
$CHPL_HOME/modules/standard/List.chpl:820: note:   ref list.pushBack(pragma"no auto destroy"in x: this.eltType)
$CHPL_HOME/modules/standard/List.chpl:868: note:   ref list.pushBack(other: list(eltType, ?p))
$CHPL_HOME/modules/standard/List.chpl:914: note:   ref list.pushBack(other: range(eltType, ?b, ?d))
  $CHPL_HOME/modules/standard/List.chpl:455: called as (list(list(string,false),false))._commonInitFromIterable(iterable: [domain(1,int(64),one)] [domain(1,int(64),one)] string) from method 'init='
  list_1.chpl:11: called as (list(list(string,false),false)).init=(other: [domain(1,int(64),one)] [domain(1,int(64),one)] string)
note: generic instantiations are underlined in the above callstack

So, how does one initialise a list of lists?

Thanks,
Roger

Hi Roger,

Lists don't have native syntactic sugar to declare them - what you have
on the right hand side of the = is an array of arrays. Instead, you'll
want to explicitly call the list initializer that takes in an array, e.g.:

var lst3: list(list(string)) = new list([new list(["this", "that", "the
other"]),new list(["one","two","three"])]);

It is definitely a little confusing, given that lists print like that
syntax would work. If it would help, we could look into ways to adjust
the printing of lists to make their declaration syntax more clear, but
that's probably best discussed on a Github issue.

Thanks,
Lydia

Hi Roger,

A coworker pointed out that since there is already an init= for
arrays, you could also write

var lst3: list(list(string)) = [new list(["this", "that", "the
other"]),new list(["one","two","three"])];

and let it convert the array of lists into a list of lists. This
implied to us that the language itself would be able to allow what you
originally wrote, we just need to do some work on our end to support it.

Would you be willing to open a feature request on Github about it, so
that we can prioritize it? It also would hopefully be pretty
straight-forward to implement, using the init= function defined at

as a starting point and limiting it to only work when the list is a list
of lists rather than a list of arrays. But only if you wanted to do it
yourself and contribute it back, which we would totally understand being
too much effort.

Thanks,
Lydia

Hi Lydia,

I opened an issue. I think implementing it myself is beyond my skills at the moment. I know there is a way to do what I want, no need to prioritise this.

Thanks,
Roger

For those who may be following this discussion but not the related issue, I believe that @jabraham implemented this in Allow creating a list of lists from an array of arrays by jabraham17 · Pull Request #24278 · chapel-lang/chapel · GitHub. Thanks Jade!

And thanks for proposing the convenience initializer and filing the issue, Roger.

-Brad