Sorry if this is a simple question, I am starting to learn chapel, and still strugling with the concept of domains.
I am trying to create overrided functions for arrays, nd-arrays and arrays of arrays.
proc f(x: [?d1] [?d2]) {
writeln("array of array");
}
proc f(x: [?d1]) {
writeln("array");
}
proc f(x: [?d1, ?d2]) {
writeln("2d array")
}
Generating the following errors
main.chpl:21: internal error: RES-CAL-NFO-0083 chpl version 1.20.0
Note: This source location is a guess.
Internal errors indicate a bug in the Chapel compiler ("It's us, not you"),
and we're sorry for the hassle. We would appreciate your reporting this bug --
please see https://chapel-lang.org/bugs.html for instructions. In the meantime,
the filename + line number above may be useful in working around the issue.
and
main.chpl:28: In function 'f':
main.chpl:28: error: cannot query part of a domain
main.chpl:28: error: cannot query part of a domain
I am probably mistaking something.
Is there a correct chapel way to do this?
Thanks in advance
Hi @alanpeixinho: I think that given Chapel's definition, the patterns you are writing are very reasonable, but simply running up against the limits of what our query syntax (?d) can currently handle, unfortunately (I'm actually surprised these patterns made it through the parser, which is where lots of reasonable-looking queries go wrong in practice).
Let me put together a quick counterproposal as a workaround for now, and then we can turn this into a bug (since you should never get internal errors) and/or feature request (if we don't already have them against these patterns, I'll have to check). Please hold.
@alanpeixinho: I've put together two examples for you to show how I'd write these styles of overloading today. I hope this helps and that you'll feel free to ask any clarifying follow-up questions:
the first provides some function overloads that discriminate based on an array argument's rank.
the second provides some overloads that discriminate based on its element type
These patterns could also be mixed and matched to achieve more specific combinations of rank and element type if desired. Alternatively, you could use a more generic routine that just took any array and then distinguish between different ranks or element types using conditionals or select statements within the function.
[If those are helpful, you're welcome to stop reading here. From here, I start picking at your original declarations to discuss what they might mean and why they might not achieve what you intended if they were all in a single file].
Now that I've spent more time looking at your original code, I think the second and third overloads might not do what you wanted, even if our query support was better than it is. Starting with the third:
proc f(x: [?d1, ?d2]) {
writeln("2d array")
}
As you intended, I would consider this to require a 2D array argument due to the pattern expressed. However, note that d1 and d2 would actually be ranges in Chapel rather than domains (e.g., given an array declared over `[1..3, 1..5]`, its domain is `{1..3, 1..5}`, but if we break it up into its dimensions as the pattern suggests, d1 would be the range `1..3` and d2 would be the range `1..5`).
Meanwhile, for this overload:
```chapel
proc f(x: [?d1]) { ... }
d1 binds to x's domain, regardless of the number of dimensions it has (e.g., it could be the 2D domain above, {1..3, 1..5}).
As a result, if you called f(A) where A had a 2D domain, I think it would be ambiguous which of the two functions to call. Perhaps if our pattern matching syntax were better, you could write it out as:
proc f(x: [{?d1}]) { ... }
to make it clear that you're not wanting to query the whole domain, but rather the single range that makes up that domain). And I think this probably makes sense, but it starts to feel a little hard to understand. Or perhaps we should support:
proc f(x: [?d1, ]) { ... }
similar to our 1-tuple syntax to imply that this is a query of the 1D domain (or does it suggest binding d1 to the range that makes up the 1D domain? Or a 2D array where we're not interested in querying the second dimension?)
There's also arguably an ambiguity between your first two overloads:
proc f(x: [?d1] [?d2]) {
writeln("array of array");
}
proc f(x: [?d1]) {
writeln("array");
}
Since the second overload doesn't specify an element type, an array of arrays could legally be passed to it as well as the first. We could change our rules to say that the first is a more specific signature than the second, and therefore preferable / chosen, but I don't believe we do anything like that for such cases like this today (and we already worry that our resolution rules are a bit too convoluted as it stands).
I think I can get the problems with my syntax.
I still dont now much about chapel, but your second proposal would seems clearer.
proc f(x: [?d1, ]) { ... }
Thank you again for all the help.
And despite the problems I had, I must say that chapel has an extremelly well constructed and clear syntax.
Keep up the good work.
Great, thanks! And just to make sure: did the linked TIO examples show some ways for you to make forward progress for now? In the meantime, I'll make sure that the internal error and some of these patterns are reflected in other issues and then probably close this one out.
They were really helpfull. Thanks.
Great! BTW, consider posting future "How do I...?" or "How should I...?" questions (well, at least, ones that don't involve internal errors :) ), to StackOverflow with a "Chapel" tag (which will notify us of them), since over time such questions and their answers can serve as good resources for other users as well (and StackOverflow seems to do better in search engines than GitHub issues).
Hi @alanpeixinho 鈥斅燭hanks again for filing this issue, particularly given the internal error. I was able to reproduce the internal error with Chapel version 1.20, but happily it generates a fairly reasonable user error on master / for next year's Chapel version 1.21. Meanwhile I've filed some feature request issues to capture some of the patterns you'd been hoping to write here:
https://github.com/chapel-lang/chapel/issues/14606
https://github.com/chapel-lang/chapel/issues/14607