help-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Help-bash] Why bash does not recoganize array type smartly?


From: Dan Douglas
Subject: Re: [Help-bash] Why bash does not recoganize array type smartly?
Date: Wed, 16 Mar 2016 01:12:18 +0000

On Tue, Mar 15, 2016 at 8:54 PM, Stephane Chazelas
<address@hidden> wrote:
> 2016-03-15 10:49:07 +0000, Dan Douglas:
>> On Thu, Mar 10, 2016 at 4:16 AM, Peng Yu <address@hidden> wrote:
>> > Is there any rationale why bash is defined in this way. Wouldn't it
>> > better to allow users define associative array just by using something
>> > like `x=([a]=1 [b]=2)` without having to declare it?
>>
>> That's how it works in ksh93, but that's the only exception. In ksh93
>> an initializer list that specifies indicies for sub-assignments is
>> implicitly an associative array of strings until given another type. A
>> compound assignment that's just a space-separated list of words is
>> implicitly an arithmetic indexed array of strings.
>>
>> Everywhere else, it's always an indexed array unless you give it a type.
>
> but in ksh93
>
> a=()
>
> declares a compound variable instead of an array unlike in all
> other shells (bash, zsh, yash, rc, es)
>
> a=(a=b b=c)

Yes that's another quirk. I find always specifying `typeset` (or
another type you've defined, or one of the default aliases) plus `-A`
or `-a` gives the least surprising results most of the time, though
there are still plenty of surprises.

> zsh's syntax to define an associative array as a whole is a lot
> saner:
>
> typeset -A a
> a=(
>   key1 value1
>   key2 value2
> )
>
> That means, you can easily define associative arrays based on
> the output of some command, or copy one array to another or
> merge two arrays:
>
> copy_of_a=("${(@kv)a}")
>
> merge_of_a_and_b=("${(@kv)a}" "${(@kv)b}")
>
> or
>
> a+=("${(@kv)b}")
>
> Note that since 5.1, zsh supports
>
> typeset -A a=(k1 v1 k2 v2)

Oh I see. That's kind of nice but unintuitive. Namerefs also provide
some simple ways to accomplish those same things that are less
difficult to use portably IMO.

If we're being honest, neither of these are particularly "sane". A
sane language just lets you zip two lists together and cast to the
desired mapping type, or call whatever methods are supported by a
particular collection interface. e.g. LINQ

 $ csharp -pkg:dotnet -e '
new[] { "foo", "bar", "baz", "bleh", "Blerg" }
    .Select((x, num) => new KeyValuePair<string, int>(x, num))
    .ToDictionary(x => x.Key, x => x.Value);'
{{ "foo", 0 }, { "bar", 1 }, { "baz", 2 }, { "bleh", 3 }, { "Blerg", 4 }}

Or the dynamic langs of course have equivalents...
`python -c 'print(dict(enumerate(["foo", "bar", "baz", "bleh",
"Blerg"])))'` etc.

I don't think it would be too much of a strech for ksh to add
interfaces and iterators. It needs to clean up its type system a bit
and expose more of the shell's functionality through it.

Bash could do the same with some extra syntax to represent glib
collections it could do a lot without having to re-invent the wheel.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]