May 18, 2021

On Tuesday, 18 May 2021 at 09:14:46 UTC, Chris Piker wrote:

>

On Tuesday, 18 May 2021 at 08:22:56 UTC, Ola Fosheim Grostad wrote:

>

The main reason is that D needs better metaprogramming.

That's an interesting take.

So far, with only a month's usage of D I'm seeing so much meta-programming capability that it actually worries me a bit. With string mixins and so many other meta programming features around I'm starting to think that reading other people's D code is going to be quite difficult, similar to perl.

>

Golden design rule: never add language features that can be done as library constructs, ever.

This sounds like a reasonable position. Imagine for a second that AAs were implemented as a library. What would the library equivalent of this:

long[string] aea = ["foo": 5, "bar": 10, "baz": 2000 ];

look like?

It could look the same, but long[string] would now be a shorthand for std.xyz.Map!(long,string) or something like that instead of a special case.

May 18, 2021

On Tuesday, 18 May 2021 at 09:24:02 UTC, Mathias LANG wrote:

>

https://github.com/dlang/druntime/blob/bf21d1bad623c6988d644117c3c0aa4d4f08b771/src/object.d#L2657-L2660

Wait. Are the unittests from that link indicative of the current end-user syntax, or what AA usage would look like under a library scheme? (or both?)

from line: 2892

auto dict = ["k1": 1, "k2": 2];
int sum;
foreach (v; dict.byValue)
   sum += v;
May 18, 2021

On Tuesday, 18 May 2021 at 09:41:06 UTC, Ola Fosheim Grostad wrote:

>

It could look the same, but long[string] would now be a shorthand for std.xyz.Map!(long,string) or something like that instead of a special case.

Hum, that's unfortunate.

Though it's a separate issue, I think this means that the error messages generated by AA associated code would become neigh unreadable, just like many error messages involving templates. I'd probably avoid using a library implementation in that case, because the usability of a construct is tied to the debug-ability of a construct. Unless I'm mistaken*, the hash function used to generate the AA would become part of the data type and thus the decent into Type Hell(tm) would begin...

Maybe in a few months I'll have a different opinion, but D template error messages really made last week more difficult at work, so any library function that encourages dmd to pump out more text-walls is something I'll try to avoid using.

--
*always likely

May 18, 2021

On Tuesday, 18 May 2021 at 10:18:28 UTC, Chris Piker wrote:

>

On Tuesday, 18 May 2021 at 09:41:06 UTC, Ola Fosheim Grostad wrote:

>

It could look the same, but long[string] would now be a shorthand for std.xyz.Map!(long,string) or something like that instead of a special case.

Hum, that's unfortunate.

Though it's a separate issue, I think this means that the error messages generated by AA associated code would become neigh unreadable, just like many error messages involving templates.

Error messages is not a language deficiency, that is an implementation priority. Completely unrelated. There is no reason for error messages to change.

May 18, 2021

On Tuesday, 18 May 2021 at 09:41:06 UTC, Ola Fosheim Grostad wrote:

>

It could look the same, but long[string] would now be a shorthand for std.xyz.Map!(long,string) or something like that instead of a special case.

It would actually be really cool if the AA literal was just rewritten into a constructor call of key, value, key, value, ....

_d_aa_literal(T...)(T args) // pragma(discardable) too would be nice

[4: "hello", 6: "bye"]

_d_aa_literal(4, "hello", 6, "bye")

Then you can construct it at ctfe and it retains the order and the capability of heterogeneous types. It'd be overpowered to an awesome extent... and would fix that annoying static initialization of AA things.

May 18, 2021

On Tuesday, 18 May 2021 at 11:54:45 UTC, Adam D. Ruppe wrote:

>

It would actually be really cool if the AA literal was just rewritten into a constructor call of key, value, key, value, ....

That is an interesting thought. I was thinking more in the direction of a compile time type for literals that could be passed around and comsumed by some destination type. But I have not given this a lot of thought, so maybe your suggestion is sufficient? The only way to gind out is to map out all the usage scenarios and find something that the type system can resolve.

May 18, 2021

On Tuesday, 18 May 2021 at 12:01:39 UTC, Ola Fosheim Grostad wrote:

>

On Tuesday, 18 May 2021 at 11:54:45 UTC, Adam D. Ruppe wrote:

>

It would actually be really cool if the AA literal was just rewritten into a constructor call of key, value, key, value, ....

That is an interesting thought. I was thinking more in the direction of a compile time type for literals that could be passed around and comsumed by some destination type. But I have not given this a lot of thought, so maybe your suggestion is sufficient? The only way to gind out is to map out all the usage scenarios and find something that the type system can resolve.

Here is another idea: a compile time forward range that produces key,value pairs...

May 18, 2021

On Tuesday, 18 May 2021 at 11:54:45 UTC, Adam D. Ruppe wrote:

>

On Tuesday, 18 May 2021 at 09:41:06 UTC, Ola Fosheim Grostad wrote:

>

It could look the same, but long[string] would now be a shorthand for std.xyz.Map!(long,string) or something like that instead of a special case.

It would actually be really cool if the AA literal was just rewritten into a constructor call of key, value, key, value, ....

_d_aa_literal(T...)(T args) // pragma(discardable) too would be nice

[4: "hello", 6: "bye"]

_d_aa_literal(4, "hello", 6, "bye")

Then you can construct it at ctfe and it retains the order and the capability of heterogeneous types. It'd be overpowered to an awesome extent... and would fix that annoying static initialization of AA things.

Yes

May 18, 2021
On 5/18/21 5:34 AM, Chris Piker wrote:
> On Tuesday, 18 May 2021 at 08:54:00 UTC, Mathias LANG wrote:
> 
> Thanks for the description, that was informative :)
> 
>> The following doesn't even compile:
>> ```
>> void main () nothrow
>> {
>>     int[int] aa;
>>     foreach (k, v; aa) {}
>> }
>> ```
> 
> So basically I can use AAs, so long as I don't put them in critical software since they are always going to throw.  No trouble, I can live with that, it's good to know that up front.
> 

No, that's the wrong way to look at it.

`foreach(k, v; aa)` isn't nothrow, because it accepts an opApply-style delegate. This is a language limitation, not a promise that they will throw in some cases.

`foreach(kv; aa.byKeyValue)` is nothrow, (where kv.key and kv.value are used to access the data), because it uses the range interface to foreach.

-Steve
May 18, 2021
On 5/18/21 7:54 AM, Adam D. Ruppe wrote:
> On Tuesday, 18 May 2021 at 09:41:06 UTC, Ola Fosheim Grostad wrote:
>> It  could look the same, but long[string] would now be a shorthand for std.xyz.Map!(long,string) or something like that instead of a special case.
> 
> It would actually be really cool if the AA literal was just rewritten into a constructor call of key, value, key, value, ....
> 
> 
> _d_aa_literal(T...)(T args) // pragma(discardable) too would be nice
> 
> [4: "hello", 6: "bye"]
> 
> _d_aa_literal(4, "hello", 6, "bye")
> 
> 
> Then you can construct it at ctfe and it retains the order and the capability of heterogeneous types. It'd be overpowered to an awesome extent... and would fix that annoying static initialization of AA things.

Let's make that 2 arrays (static or stack-allocated dynamic) to avoid the vararg template cost.

-Steve