www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - So how do you create an associative array with an immutable value,

reply FeepingCreature <feepingcreature gmail.com> writes:
`assocArray` famously complains that it needs a mutable value 
type. You can't set values. You could write a literal, but that 
only works for a finite number of keys, and there's no way to 
merge two associative arrays.

Internally, we use librebindable, so we can create a 
`Rebindable!(immutable V)[K]`, which is mutable, and cast it to 
`immutable V[K]` without breaking anything. But I'm not sure how 
I'd propose getting that into Phobos without including 
librebindable outright. But I also don't see another way to do it?

Any ideas?
Oct 06 2022
parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 10/7/22 2:58 AM, FeepingCreature wrote:
 `assocArray` famously complains that it needs a mutable value type. You 
 can't set values. You could write a literal, but that only works for a 
 finite number of keys, and there's no way to merge two associative arrays.
 
 Internally, we use librebindable, so we can create a 
 `Rebindable!(immutable V)[K]`, which is mutable, and cast it to 
 `immutable V[K]` without breaking anything. But I'm not sure how I'd 
 propose getting that into Phobos without including librebindable 
 outright. But I also don't see another way to do it?
 
 Any ideas?
`require` should work, since it effectively only assigns a value if it doesn't already exist. If it doesn't, then maybe it can be fixed so it does. We can't allow just general assignment to compile, as you may have an already existing value. -Steve
Oct 07 2022
parent reply FeepingCreature <feepingcreature gmail.com> writes:
On Friday, 7 October 2022 at 13:58:52 UTC, Steven Schveighoffer 
wrote:
 `require` should work, since it effectively only assigns a 
 value if it doesn't already exist.

 If it doesn't, then maybe it can be fixed so it does.

 We can't allow just general assignment to compile, as you may 
 have an already existing value.

 -Steve
Can confirm that `require` doesn't work at present: ``` void main() { immutable(int)[int] aa; aa.require(5, 5); assert(aa[5] == 5); } ``` /dlang/dmd/linux/bin64/../../src/druntime/import/object.d(3453): Error: cannot modify `immutable` expression `*p` onlineapp.d(5): Error: template instance `object.require!(int, immutable(int))` error instantiating It's hard to see how you'd make `require` work but not `assocArray`, since `require` is not exactly a built-in feature either.
Oct 07 2022
parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 10/7/22 11:27 AM, FeepingCreature wrote:
 It's hard to see how you'd make `require` work but not `assocArray`, 
 since `require` is not exactly a built-in feature either.
You can either cast (which is reasonable, considering that the assignment only happens when it didn't already exist) or make a new hook. -Steve
Oct 07 2022
parent reply FeepingCreature <feepingcreature gmail.com> writes:
On Friday, 7 October 2022 at 16:03:49 UTC, Steven Schveighoffer 
wrote:
 On 10/7/22 11:27 AM, FeepingCreature wrote:
 It's hard to see how you'd make `require` work but not 
 `assocArray`, since `require` is not exactly a built-in 
 feature either.
You can either cast (which is reasonable, considering that the assignment only happens when it didn't already exist) or make a new hook. -Steve
`cast` is not sufficient because `immutable struct S` cannot by any means be made mutable.
Oct 07 2022
parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 10/7/22 12:11 PM, FeepingCreature wrote:
 On Friday, 7 October 2022 at 16:03:49 UTC, Steven Schveighoffer wrote:
 On 10/7/22 11:27 AM, FeepingCreature wrote:
 It's hard to see how you'd make `require` work but not `assocArray`, 
 since `require` is not exactly a built-in feature either.
You can either cast (which is reasonable, considering that the assignment only happens when it didn't already exist) or make a new hook.
`cast` is not sufficient because `immutable struct S` cannot by any means be made mutable.
`copyEmplace` appears to work: ```d import core.lifetime; immutable struct S { int x; } void main() { S s = S(5); ubyte[S.sizeof] buf; copyEmplace(s, *cast(S*)buf.ptr); } ``` -Steve
Oct 07 2022
parent reply FeepingCreature <feepingcreature gmail.com> writes:
On Friday, 7 October 2022 at 18:00:56 UTC, Steven Schveighoffer 
wrote:
 `copyEmplace` appears to work:

 ```d
 import core.lifetime;
 immutable struct S
 {
     int x;
 }
 void main()
 {
     S s = S(5);
     ubyte[S.sizeof] buf;
     copyEmplace(s, *cast(S*)buf.ptr);
 }
 ```

 -Steve
Yeah, if I could get the associative array to give me a pointer to an uninitialized value for a key, that would do it, I think.
Oct 07 2022
parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 10/7/22 3:20 PM, FeepingCreature wrote:
 
 Yeah, if I could get the associative array to give me a pointer to an 
 uninitialized value for a key, that would do it, I think.
Have you looked at the implementation for require? That's exactly what it does. For reference: https://github.com/dlang/dmd/blob/f4c21ccd6a73fee7abdea39cc38e8c64b627ffe1/druntime/src/object.d#L3457 -Steve
Oct 07 2022
parent reply FeepingCreature <feepingcreature gmail.com> writes:
On Friday, 7 October 2022 at 20:04:48 UTC, Steven Schveighoffer 
wrote:
 On 10/7/22 3:20 PM, FeepingCreature wrote:
 
 Yeah, if I could get the associative array to give me a 
 pointer to an uninitialized value for a key, that would do it, 
 I think.
Have you looked at the implementation for require? That's exactly what it does. For reference: https://github.com/dlang/dmd/blob/f4c21ccd6a73fee7abdea39cc38e8c64b627ffe1/druntime/src/object.d#L3457 -Steve
Yeah okay so it's definitely possible, but I do feel it's kinda questionable to call barely documented internal implementation-dependent (?) runtime functions from user code...
Oct 08 2022
next sibling parent reply Nick Treleaven <nick geany.org> writes:
On Saturday, 8 October 2022 at 17:09:39 UTC, FeepingCreature 
wrote:
 Yeah okay so it's definitely possible, but I do feel it's kinda 
 questionable to call barely documented internal 
 implementation-dependent (?) runtime functions from user code...
What's missing from the docs? Besides object there's also the AA docs: https://dlang.org/spec/hash-map.html#inserting_if_not_present
Oct 08 2022
parent FeepingCreature <feepingcreature gmail.com> writes:
On Saturday, 8 October 2022 at 17:27:58 UTC, Nick Treleaven wrote:
 On Saturday, 8 October 2022 at 17:09:39 UTC, FeepingCreature 
 wrote:
 Yeah okay so it's definitely possible, but I do feel it's 
 kinda questionable to call barely documented internal 
 implementation-dependent (?) runtime functions from user 
 code...
What's missing from the docs? Besides object there's also the AA docs: https://dlang.org/spec/hash-map.html#inserting_if_not_present
Which, again, doesn't work with immutable types...
Oct 08 2022
prev sibling parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 10/8/22 1:09 PM, FeepingCreature wrote:
 On Friday, 7 October 2022 at 20:04:48 UTC, Steven Schveighoffer wrote:
 On 10/7/22 3:20 PM, FeepingCreature wrote:
 Yeah, if I could get the associative array to give me a pointer to an 
 uninitialized value for a key, that would do it, I think.
Have you looked at the implementation for require? That's exactly what it does. For reference: https://github.com/dlang/dmd/blob/f4c21ccd6a73fee7abdea39cc38e8c64b627ffe1/druntime/src/object.d#L3457
Yeah okay so it's definitely possible, but I do feel it's kinda questionable to call barely documented internal implementation-dependent (?) runtime functions from user code...
Perhaps you misunderstand -- I think druntime's `require` should be updated to make this work. -Steve
Oct 08 2022
parent FeepingCreature <feepingcreature gmail.com> writes:
On Saturday, 8 October 2022 at 20:58:09 UTC, Steven Schveighoffer 
wrote:
 On 10/8/22 1:09 PM, FeepingCreature wrote:
 On Friday, 7 October 2022 at 20:04:48 UTC, Steven 
 Schveighoffer wrote:
 Have you looked at the implementation for require? That's 
 exactly what it does.

 For reference: 
 https://github.com/dlang/dmd/blob/f4c21ccd6a73fee7abdea39cc38e8c64b627ffe1/druntime/src/object.d#L3457
Yeah okay so it's definitely possible, but I do feel it's kinda questionable to call barely documented internal implementation-dependent (?) runtime functions from user code...
Perhaps you misunderstand -- I think druntime's `require` should be updated to make this work. -Steve
Oh! Yeah, that seems like it should be viable.
Oct 08 2022