3 ms·
I wish bash would have a nicer way to address a character in a string though. How hard would it be to use the same syntax as for arrays for it? Yes it would be
by chubot 5y ago
I wish bash would have a nicer way to address a character in a string though. How hard would it be to use the same syntax as for arrays for it?
Yes it would be nicer if ${s[i]} worked, instead of needing ${s:i:1}. But there's a pretty fundamental reason for that: bash doesn't have dynamic types of strings and arrays like Python or JavaScript.
Instead everything is basically one kind of string-or-array value. Roughly speaking, strings are values with one element, and arrays are values with more than one.
And ${array} is equivalent to ${array[0]}, which is very confusing. Conversely, you can do ${s[0]} on anything you declared to be a string, and you'll get the whole value back.
Rather than having types attached to values, bash has weird "flags" on the LOCATION for a value. And even that's not the whole story! Evaluation of a variable in bash depends on three things:
1. the contents of the "cell" / location
2. the flag on the cell (-a -A)
3. the operation, e.g. echo $x or echo foo > $x
I might make a blog post about this.
Oil does it more like Python or JavaScript, which is noted here, but this section could use a lot of elaboration:
https://www.oilshell.org/release/0.9.7/doc/known-differences.html#values-are-tagged-with-types-not-cells https://www.oilshell.org/release/0.9.7/doc/known-differences...
- shmerl 5y agoInteresting, thanks! Is there a reason for such awkward design of handling variables and types or it's simply some historic choice that's stuck?
- chubot 5y agoYeah it's definitely a historical thing. Bourne shell / POSIX shell doesn't have arrays, and ksh added arrays and bash adopted the same semantics. ksh did it in the most "backward compatible" way, with the least amount of work, but which leads to very confusing semantics. They just "extended" every string so it can have an array part, and then changed a FEW parts of the evaluator, not ALL parts of it. So arrays "decay" to strings in most contexts. They didn't have to touch that code. It's hard to explain but if you write an interpreter you'll get a feel for this O(M x N) explosion between data types and operations. The amount of work explodes as you add more of either, and shell already has a ton of operations. As mentioned, the evaluation rules for the word $x in 'echo $x' and 'echo foo > $x' are completely different. There are ways to avoid this, like Python has PyObject and a bunch of protocols. Similarly, Clojure has more protocols than Racket, which the Racket authors have noted -- it works on abstractions and not "concretions". As far as I remember, these come directly from Java interfaces. So yes Java actually adds something to Lisp :)