When indexing into an array literal, like [1, 2, 3][1], we seem to get 1 1 1 as the output rather than 2, as expected. My guess is that this is being interpreted as an index-less loop expression for reasons that aren't clear to me (e.g., equivalent to [i in [1, 2, 3]] [1]) and seem incorrect.
Associated Future Test(s):
test/arrays/indexing/arrLitIndexing.chpl #16882
chpl --version: chpl version 1.24.0 pre-release (c3cb383326)This isn't particularly high priority, but I ran across it while reviewing Engin's "index string literal" PR (#16879) and wanted to note it before forgetting.
Trying the issue with chapel-1.22.0, the literal seems to give the expected result when enclosed with ().
Though I have no idea what () does, is it possible that the difference between [literal] and ([literal]) might have some clue for the unexpected behavior of [literal]?
writeln( [1, 2, 3][1] ); // 1 1 1
writeln( ( [1, 2, 3] )[1] ); // 2
writeln( [i in [1, 2, 3]][1] ); // 1 1 1
// writeln( ( [i in [1, 2, 3]] )[1] ); // syntax error: near ')'
// writeln( "hello"[0] ); // syntax error: near '['
writeln( ("hello")[0] ); // h
Hi @ty1027 — Thanks for those observations. I think that this bolsters the theory that the expression is incorrectly being treated as a loop expression, in the sense that the parenthesis would force the [1, 2, 3] expression to be evaluated in isolation first, and made into an array literal. The reason I think it's inappropriate for the compiler to treat [1, 2, 3] as a loop expression is that a loop expression shouldn't support a top-level comma-separated list of expressions. That is, while I can say something like [a in A] I shoud not be able to say something like [elem in A, B, C] and therefore shouldn't be able to say [A, B, C] (dropping the loop index). Instead, in both forms the A, B, C should be put into some sort of collection like a tuple, array, or domain.
I suspect this is probably a fairly simple fix, where something is automatically wrapping them in a collection but shouldn't. But I haven't had time to look into it yet (and wasn't sure I'd be able to before our holiday break starts).
I suspect this is probably a fairly simple fix
It looks like I may have been overly optimistic. It seems that the following rule in the parser:
| TLSBR expr_ls TRSBR expr %prec TFOR
currently handles this [1, 2, 3][1] case, as well as [D] real as a type expression and [D] i as a forall expression. I was hoping that I could change it to:
| TLSBR expr TRSBR expr %prec TFOR
to handle the latter two, causing the former to fall into the normal "array literal" + "indexing" rules, but this results in conflicts (which can also probably be dealt with, but with more effort than I was hoping for).
Most helpful comment
It looks like I may have been overly optimistic. It seems that the following rule in the parser:
currently handles this
[1, 2, 3][1]case, as well as[D] realas a type expression and[D] ias a forall expression. I was hoping that I could change it to:to handle the latter two, causing the former to fall into the normal "array literal" + "indexing" rules, but this results in conflicts (which can also probably be dealt with, but with more effort than I was hoping for).