Thread overview
[Issue 2954] [tdpl] Allow to set associative array key value only using expression AA key type is constructable from
Nov 06, 2018
Stanislav Blinov
Dec 17, 2022
Iain Buclaw
August 09, 2014
https://issues.dlang.org/show_bug.cgi?id=2954

hsteoh@quickfur.ath.cx changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |hsteoh@quickfur.ath.cx

--
August 09, 2014
https://issues.dlang.org/show_bug.cgi?id=2954

--- Comment #11 from hsteoh@quickfur.ath.cx ---
Which of the following cases should/shouldn't be valid?

Case 1:

int[string] aa;
char[] key;
aa[key] = 1;

Case 2:

int[string] aa;
char[] key;
if (aa[key] == 1) { ... }
auto p = key in aa;


It seems to me that we should allow case 2, but prohibit case 1.

--
August 10, 2014
https://issues.dlang.org/show_bug.cgi?id=2954

--- Comment #12 from Andrei Alexandrescu <andrei@erdani.com> ---
(In reply to hsteoh from comment #11)
> Which of the following cases should/shouldn't be valid?
> 
> Case 1:
> 
> int[string] aa;
> char[] key;
> aa[key] = 1;

This shouldn't compile, although we ought to make it work in the future (e.g. by defining and using a protocol). The problem with this is efficiency:

int[string] aa;
char[] key = ...;
aa[key.idup] = 1;
// Alternatively
aa[to!string(key)] = 1;

This is correct but less efficient than it could - it compulsively allocates a new string even when not needed (i.e. the key is already there).

> Case 2:
> 
> int[string] aa;
> char[] key;
> if (aa[key] == 1) { ... }
> auto p = key in aa;
> 
> 
> It seems to me that we should allow case 2, but prohibit case 1.

Yah, lookup should always work with any type that allows comparison.

--
November 06, 2018
https://issues.dlang.org/show_bug.cgi?id=2954

Stanislav Blinov <stanislav.blinov@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |stanislav.blinov@gmail.com

--- Comment #13 from Stanislav Blinov <stanislav.blinov@gmail.com> ---
Bump.

A user in Learn recently ran into this (even though the thread itself is about
a different question):
https://forum.dlang.org/thread/mailman.4778.1541282050.29801.digitalmars-d-learn@puremagic.com

The AA's indexing operations should:

1) If the key type is a pointer or a class instance, only accept pointers to
immutable and immutable references respectively.
2) If the key type is an array, accept non-immutable arrays, but .idup them if
the operation results in insertion (i.e. [], require(), update())

Side observation: what is this 'blocker' bug blocking, exactly? It's approaching it's 10th birthday...

--
November 06, 2018
https://issues.dlang.org/show_bug.cgi?id=2954

--- Comment #14 from hsteoh@quickfur.ath.cx ---
Look at the history. Apparently it blocked issue #1934, but that has somehow been fixed since, so this bug isn't a blocker for it after all?

In any case, yeah, this is a stupid long-standing bug that has taken far too long and still no fix in sight. :-/

--
December 17, 2022
https://issues.dlang.org/show_bug.cgi?id=2954

Iain Buclaw <ibuclaw@gdcproject.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Priority|P2                          |P1

--
March 27
https://issues.dlang.org/show_bug.cgi?id=2954

Steven Schveighoffer <schveiguy@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |schveiguy@gmail.com

--- Comment #15 from Steven Schveighoffer <schveiguy@gmail.com> ---
This oddity just came up with a related bug in std.net.curl (to be fixed shortly). I can't believe this is still a problem, almost 15 years later!

For my 2 cents:

1. aa[idx] = value; should only accept idx that is implicitly convertible to
the key type.
2. Other operations such as `idx in aa` or `aa[idx]` (which are not setting
values/keys) should be fine as long as the key type can convert to the idx.

We also lack some sort of mechanism to say "look up using this key, and if not present, use this *conversion routine* to convert the key before assigning the new value". `aa.update` only allows different paths for the value.

But maybe this is such a niche problem that it's not worth adding a mechanism.

--
March 27
https://issues.dlang.org/show_bug.cgi?id=2954

Steven Schveighoffer <schveiguy@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           See Also|                            |https://issues.dlang.org/sh
                   |                            |ow_bug.cgi?id=24458

--
March 27
https://issues.dlang.org/show_bug.cgi?id=2954

--- Comment #16 from hsteoh@qfbox.info ---
Niche or not, this problem ought to be fixed. It's been how long now, and we still haven't gotten our act together on AA's.

Lookups should be permissive and allow types that are comparable with the key type (e.g., using a char[] to lookup a T[string] should be fine).

Assignment, however, must be much stricter because of aliasing issues; it should only allow types implicitly convertible to the key type (it's illegal to assign a char[] key to T[string], because if the key is subsequently modified via the mutable reference, the AA breaks.)

--
March 27
https://issues.dlang.org/show_bug.cgi?id=2954

--- Comment #17 from Steven Schveighoffer <schveiguy@gmail.com> ---
(In reply to hsteoh from comment #16)
> Niche or not, this problem ought to be fixed. It's been how long now, and we still haven't gotten our act together on AA's.

You may misunderstand, what I'm talking about is an update-like function, but allows you to tell it how to store the key as well as the value. It's not as easy to model as the current `update` function, because on create, you need to give it both key and value. so something like:

`void updateWithKey(V[RealKey] aa, RealKey function(LookupKeyType k)
makeKeyOnCreate, V function() valueOnCreate, V function(RealKey)
valueOnUpdate)`

This issue itself is not niche and needs to be fixed as the P1 that it is. I was just talking about a piece of missing functionality to avoid double lookups in this situation (wanting to only do an expensive thing -- e.g. allocate -- when creating a new key/value pair).

--