Re: zsh style associative array assignment bug

2021-03-28 Thread Oğuz
28 Mart 2021 Pazar tarihinde Eric Cook  yazdı:
>
> 1) For consistency sake with the shell the idea was borrowed from mostly.


That an idea was borrowed from another shell doesn't mean it should be
implemented the same kludgy way. Besides, bash doesn't offer compatibility
with zsh.


> 2) Prior to this extension bash required specifying the key and value for
> AA assignments, so it seems weird to silently ignore that a value wasn't
> given now.


The oldest version of Bash I ever used is 4.4.20, and if my memory serves
me right, it didn't regard omission of a value inside a compound assignment
(like `foo=([bar]=)`) an error. If otherwise and it actually did, that was
a mistake.


> 2.5) I subjectively think passing an odd number of elements to declare is
> more often
> than not to be a mistake that the user would be interested in knowing
> about.
>
> With the way it is now, you could save a few characters to do a seen array.
> $ while read -r key; ... seen+=("$key") ...
> but not really much else.


I believe bash will eventually (if hasn't already done in devel) allow `$@'
and the like to expand to multiple words inside a compound assignment to an
associative array. Being forced to trim an array to an even number of
elements before using it inside such an assignment would be really
annoying, in my opinion.


-- 
Oğuz


Re: zsh style associative array assignment bug

2021-03-28 Thread Ilkka Virta
On Sun, Mar 28, 2021 at 10:16 AM Oğuz  wrote:

> That an idea was borrowed from another shell doesn't mean it should be
> implemented the same kludgy way. Besides, bash doesn't offer compatibility
> with zsh.
>

You don't think the realm of POSIX-ish shells already has enough
incompatibilities
and minor quirks between the different shells? :)

The oldest version of Bash I ever used is 4.4.20, and if my memory serves
> me right, it didn't regard omission of a value inside a compound assignment
> (like `foo=([bar]=)`) an error. If otherwise and it actually did, that was
> a mistake.
>

But this is an error:

   a=([foo]=123 [bar])

Now, the syntax is different so it's not a fair comparison, really. But
spinning up an
empty word where none exists is not something the shell usually does
anywhere
else, so why should it do that here?

I believe bash will eventually (if hasn't already done in devel) allow `$@'
> and the like to expand to multiple words inside a compound assignment to an
> associative array. Being forced to trim an array to an even number of
> elements before using it inside such an assignment would be really
> annoying, in my opinion.
>

 I wonder, what would the use case be? I could understand assigning the
words
from "$@" to the keys of an associative array might be useful, but where
would
you want to fill the keys and values, while at the same time silently
allowing a
missing value? Or silently dropping one. Shouldn't a script treat that as
an error
and have the user recheck what they're doing, the same as in any case where
a tool gets too many or too few arguments?


Re: zsh style associative array assignment bug

2021-03-28 Thread Oğuz
28 Mart 2021 Pazar tarihinde Ilkka Virta  yazdı:

> On Sun, Mar 28, 2021 at 10:16 AM Oğuz  wrote:
>
>> That an idea was borrowed from another shell doesn't mean it should be
>> implemented the same kludgy way. Besides, bash doesn't offer compatibility
>> with zsh.
>>
>
> You don't think the realm of POSIX-ish shells already has enough
> incompatibilities
> and minor quirks between the different shells? :)
>

> The oldest version of Bash I ever used is 4.4.20, and if my memory serves
>> me right, it didn't regard omission of a value inside a compound
>> assignment
>> (like `foo=([bar]=)`) an error. If otherwise and it actually did, that was
>> a mistake.
>>
>
> But this is an error:
>
>a=([foo]=123 [bar])
>

As it should be. `[bar]' doesn't qualify as an assignment without an equals
sign, the shell thinks you're mixing two forms of associative array
assignment there.

In the new form, that a key is listed inside a compound assignment alone
implies that it was meant to be assigned a value. In my mind, `a=(foo 123
bar)' translates to `a=([foo]=123 [bar]=)'. It makes sense.


>
> Now, the syntax is different so it's not a fair comparison, really. But
> spinning up an
> empty word where none exists is not something the shell usually does
> anywhere
> else, so why should it do that here?
>

Pairing separate words for further processing is not something the shell
usually does anywhere else either. So why shouldn't it?


> I believe bash will eventually (if hasn't already done in devel) allow `$@'
>> and the like to expand to multiple words inside a compound assignment to
>> an
>> associative array. Being forced to trim an array to an even number of
>> elements before using it inside such an assignment would be really
>> annoying, in my opinion.
>>
>
>  I wonder, what would the use case be? I could understand assigning the
> words
> from "$@" to the keys of an associative array might be useful, but where
> would
> you want to fill the keys and values, while at the same time silently
> allowing a
> missing value? Or silently dropping one. Shouldn't a script treat that as
> an error
> and have the user recheck what they're doing, the same as in any case where
> a tool gets too many or too few arguments?
>

The shell already allows missing values in assignments, `a=' is not an
error.


-- 
Oğuz


Re: zsh style associative array assignment bug

2021-03-28 Thread Eric Cook

On 3/28/21 7:02 AM, Oğuz wrote:

As it should be. `[bar]' doesn't qualify as an assignment without an equals 
sign, the shell thinks you're mixing two forms of associative array assignment 
there.

In the new form, that a key is listed inside a compound assignment alone 
implies that it was meant to be assigned a value. In my mind, `a=(foo 123 bar)' 
translates to `a=([foo]=123 [bar]=)'. It makes sense.


That is the point that i am making, in typeset -A ary=([key]=) an explicit 
empty string is the value, but in the case of typeset -A ary=([key]) it was 
historically an error. So why should an key without a value now be acceptable?





Re: zsh style associative array assignment bug

2021-03-28 Thread Oğuz
On Sun, Mar 28, 2021 at 9:02 PM Eric Cook  wrote:

> in typeset -A ary=([key]=) an explicit empty string is the value


No. An "explicit" empty string would be '', "", or something like that.
After `=' a value is expected but it's not there, so `[key]' is assigned
the empty string. `typeset -A ary=(key)' is similar, the value is not there
and the empty string is taken as the value instead.

but in the case of typeset -A ary=([key]) it was historically an error
>

Irrelevant. See above


Re: zsh style associative array assignment bug

2021-03-28 Thread Robert Elz
Date:Sun, 28 Mar 2021 22:01:14 +0300
From:=?UTF-8?B?T8SfdXo=?= 
Message-ID:  


  | No. An "explicit" empty string would be '', "", or something like that.

No, not in sh it isn't - all quotes do is hide the effects of special
characters (and prevent some uses, eg: as a reserved word).   There are
no "string" (enclosed in quotes) data types in sh, a and 'a' and "a" and \a
are all the exact same thing.   That applies to empty values too, the only
difference is that there needs to be some reason to believe that the empty
value exists, rather than is not present at all.

  | After `=' a value is expected but it's not there

It is there.   It is just empty.

How this applies to associative array init's I neither know nor care.

kre




Re: zsh style associative array assignment bug

2021-03-28 Thread Greg Wooledge
On Sun, Mar 28, 2021 at 10:01:14PM +0300, Oğuz wrote:
> On Sun, Mar 28, 2021 at 9:02 PM Eric Cook  wrote:
> 
> > in typeset -A ary=([key]=) an explicit empty string is the value
> 
> No. An "explicit" empty string would be '', "", or something like that.
> After `=' a value is expected but it's not there, so `[key]' is assigned
> the empty string.

Consider this assignment command:

x=

It's syntactically valid, and it assigns the empty string to the variable x.

It's perfectly reasonable, therefore, for

a=([key]=)

to assign the empty string to a[key].  You don't need '' or "" or whatever.

Now, as far as hash=(a b c) goes, I don't have a strong opinion about it.
Some of the other languages that have such a feature treat it as an error.
We've already heard from zsh.  Here's Tcl:

% array set hash {a b c}
list must have an even number of elements

Perl does what bash does, kinda:

unicorn:~$ perl -e 'use Data::Dumper; %hash=qw(a b c); print Dumper(\%hash);'
$VAR1 = {
  'a' => 'b',
  'c' => undef
};

Python is different:

>>> y = ["a", "b", "c", "d"]
>>> dict(zip(y[::2], y[1::2]))
{'a': 'b', 'c': 'd'}
>>> x = ["a", "b", "c"]
>>> dict(zip(x[::2], x[1::2]))
{'a': 'b'}

It seems to discard the last (unmatched) value.  Also, dear gods, what
is that horrible syntax they forced me to google for... and it took MANY
tries to find it, too.

So, that's 2 votes for error, 2 votes for using the empty string (or
null/undef) as the last value, and 1 vote for silently dropping the
last key.  Definitely not a consensus.