On Wed, 18 Oct 2023 at 22:19, Zachary Santer <zsan...@gmail.com> wrote:
> On Tue, Oct 17, 2023 at 5:56 PM Emanuele Torre <torreemanue...@gmail.com> > wrote: > > > bash-5.1$ letters=( {a..z} ); echo "${letters["{10..15}"]}" > > k l m n o p > ... > So how important is it to maintain undocumented behavior? > This is the expected outcome of doing brace expansion *followed by* variable expansion, with separate parsing phases. Bash does not generally document what happens when you combine features if it can reasonably be inferred from the documentation of the individual features. First, brace expansion translates: "${foo["{10..15}"]}" into "${foo["10"]}" "${foo["11"]}" "${foo["12"]}" "${foo["13"]}" "${foo["14"]}" "${foo["15"]}" and then the variables are expanded individually. Then there's the question "Was that even supposed to work like that?" Supposed to? Yes. A good idea? Probably not. Useful? Definitely, but there should be a better way to do it. If so, you'd think it would generalize to being able to pass a series of > whitespace-delimited indices to an array expansion. > That does not follow. The shell grammar is characterised by having a large number of phases, which means brace expansion occurs without regard for the grammatical validity of "${var[" as its prefix or "]}" as its suffix; when the brace expansion occurs, the prefix and suffix are not yet considered as being a variable expansion. Putting an array or list inside the [] won't be expanded until after the outer variable expansion has begun, so it would require entirely new rules for handling array subscripts that are "lists". And that *would* need to be separately documented. Of course, I would love to see something like "${array[10..15]}" work "properly", unlike the current behaviour of "${array[@]:10:6}" (The latter unnecessarily exposes the user to the implementation details of "array". Whenever I complain about this, the responses justifying the current behaviour as "sensible" tacitly rely on "it's a list, not an array", which is quite perverse given that all the documentation is about "arrays".) Why does "${#@}" expand to the same thing as "${#}"? You're right, we don't need ${#} and we should get rid of it. </jest> ${#@} follows the pattern of correspondence between ${array[@]} and ${@}; they both take all the same modifiers, including the # prefix for "count". Ignoring which one came first, $# can be seen simply as a required shorthand for ${#@}. > Why is $[ ] equivalent to $(( ))? Because POSIX was too slow choosing which one to endorse (there were several proposals), by which time Bash had already implemented $[...], and people had started using it. (And from a language design choice, $[...] is simpler to get right; no need to look ahead for '))' to see if it's actually a command substitution.) Does that stuff need to continue to work forever? > For some combination of default modes, yes, it must. There are still scripts out there running that haven't been modified this millennium. That's not to say that there shouldn't be a "lint" mode which warns about obsolete features, or a "strict" mode which aborts if they're used, but they can't just be removed from the default. -Martin