On Sat, 30 Aug 2025, 01:48 Chet Ramey, <chet.ra...@case.edu> wrote: > > > > What was the rationale for preferring $((…)) over $[…] back when they > had a > > free choice? > > See if the POSIX rationale answers your question. > > > https://pubs.opengroup.org/onlinepubs/9799919799/xrat/V4_xcu_chap01.html#tag_23_02_06_04
Somewhat. *In early proposals, a form $[expression] was used. It was functionally equivalent to the "$(())" of the current text, but objections were lodged that the 1988 KornShell had already implemented "$(())" and there was no compelling reason to invent yet another syntax. Furthermore, the "$[]" syntax had a minor incompatibility involving the patterns in case statements.* The "no compelling reason" seems odd, like nobody was bothered to think about it. Also considering that unmatched parentheses in case statements are one of the things that make $() parsing particularly messy, citing patterns in case statements as a reason to prefer $(()) over $[] seems somewhat disingenuous. "A conforming application shall ensure that it separates the "$(" and '(' > into two tokens (that is, separate them with white space) in a command > substitution that starts with a subshell." > > If the application is non-conforming, all bets are off. > The standard requires the shell to parse the contents of the $((...)) as > an arithmetic expression, only treating it as a command substitution > containing a subshell command if that fails. "If that falls" generally implying that the parser has to support arbitrary backtracking, and should still try to perform command substitution starting with $((, notwithstanding the stated requirement that conforming applications not be written that way. Backtracking is never a good sign in language design. Shells approach that with differing levels of rigor. > POSIX doesn't really `deprecate' things. It removes things from the standard I guess what I'm talking about is removing this bit: *An example such as:* *echo $((echo hi);(echo there))* *should not be misinterpreted by the shell as arithmetic because attempts to balance the parentheses pairs would indicate that they are subshells.* Although that precise example is clear, the unbalanced parentheses in case/esac blocks make this distinction non trivial in general. *However, as indicated by XBD 3.85 Control Operator, a conforming application must separate two adjacent parentheses with white space to indicate nested subshells.* On its own this second sentence would effectively be the deprecation notice I seek, but when combined with the first sentence, it seems like it's still requiring the shell to "play nice" with non conforming applications. I would like POSIX to give full leeway to shells to assume anything starting with $(( cannot be a command substitution, and to give up if it can't find a matching )), including in the example given above, rather than implying that it should backtrack and try to parse as a command substitution. To put it another way, I'd like POSIX to be clear that parser backtracking is not required. -Martin