Thread overview
[Issue 24169] Confusion between array literal and associative array literal
Sep 29, 2023
Walter Bright
Sep 29, 2023
Walter Bright
Sep 29, 2023
Dennis
Sep 29, 2023
Walter Bright
Sep 29, 2023
Dennis
Jun 29
Dlang Bot
September 29, 2023
https://issues.dlang.org/show_bug.cgi?id=24169

--- Comment #1 from Walter Bright <bugzilla@digitalmars.com> ---
The fault appears to lie with init.ArrayInitializer.isAssociativeArray(), which is way too eager to conclude it's an associative array.

I suggest that it be amended to require, for an associative array:

1. all keys are present

2. the key type is not integrably promotable to size_t

    -or-

the range of key values is more than twice the number of entries

--
September 29, 2023
https://issues.dlang.org/show_bug.cgi?id=24169

--- Comment #2 from Walter Bright <bugzilla@digitalmars.com> ---
The key values should also all be positive for an array literal.

--
September 29, 2023
https://issues.dlang.org/show_bug.cgi?id=24169

Dennis <dkorpel@live.nl> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |dkorpel@live.nl

--- Comment #3 from Dennis <dkorpel@live.nl> ---
> 1. all keys are present

Sounds reasonable

> 2. the key type is not integrably promotable to size_t

Associative arrays with integer key types are valid, changing the inferred type of the literal to an integer array is a breaking change.

> the range of key values is more than twice the number of entries

This is trying to be clever, when the rule should be simple. It would be surprising when adding a key to an existing associative array suddenly turns it into an integer array or vice versa.

--
September 29, 2023
https://issues.dlang.org/show_bug.cgi?id=24169

--- Comment #4 from Walter Bright <bugzilla@digitalmars.com> ---
> It would be surprising when adding a key to an existing associative array suddenly turns it into an integer array or vice versa.

The change to add associative array literals did exactly that. It silently switched code from generating an array literal to an associative array literal. (The penalty is slow access, as array indexing is much faster.)

I discovered this via testing.

--
September 29, 2023
https://issues.dlang.org/show_bug.cgi?id=24169

--- Comment #5 from Dennis <dkorpel@live.nl> ---
(In reply to Walter Bright from comment #4)
> The change to add associative array literals did exactly that.

A change in the past had an unfortunate side effect. How does this justify adding a new confusing rule? Imagine someone wrote this:

```
auto x =
[
0: 10,
4: 40,
];

void main()
{
    x.byKeyValue.each!writeln;
}
```

Then one day someone adds an entry:
```
auto x =
[
0: 10,
4: 40,
5: 50,
];
```

With the proposed scheme, x would suddenly change type resulting in errors like `Error: none of the overloads of template `object.byKeyValue` are callable using argument types `!()(int[])`. How is the programmer supposed to know what happened here?

--
June 29
https://issues.dlang.org/show_bug.cgi?id=24169

Dlang Bot <dlang-bot@dlang.rocks> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |pull

--- Comment #6 from Dlang Bot <dlang-bot@dlang.rocks> ---
@ntrel created dlang/dmd pull request #16635 "Fix Bugzilla 24169 - Confusion between array literal and associative …" fixing this issue:

- Fix Bugzilla 24169 - Confusion between array literal and associative array literal

  Infer an array initializer as an array if there are missing indexes.

https://github.com/dlang/dmd/pull/16635

--