Target typed new expressions for D?

Q. Schroll qs.il.paperinik at gmail.com
Mon May 3 23:40:49 UTC 2021


On Saturday, 1 May 2021 at 00:13:08 UTC, Paul Backus wrote:
> On Friday, 30 April 2021 at 16:20:13 UTC, sighoya wrote:
>> Relates to the following:
>>
>> https://devblogs.microsoft.com/dotnet/welcome-to-c-9-0/#target-typed-new-expressions
>>
>> What do you think about?
>
> I'm not a fan of expressions that require context to determine 
> their type.
>
> D already has a few of these for built-in types; for example:
>
> ```D
> int[] a1 = [1, 2, 3];
> double[] a2 = [1, 2, 3];
> ```
> The issue is that, while `[1, 2, 3]` can be either an `int[]` 
> or a `double[]` in "normal" code, it's *always* an `int[]` in 
> generic code. So if you write something as simple as
>
> ```D
> int[3] a1 = [1, 2, 3].staticArray;
> double[3] a2 = [1, 2, 3].staticArray;
> ```
> ...you get a type error:
>
>     Error: cannot implicitly convert expression staticArray([1, 
> 2, 3]) of type int[3] to double[]

Have you ever seen this beauty:
```D
int[] xs = [ 2: 3, 0: 1 ];
assert(xs == [1, 0, 3]);
```
Notice how the size is not clear, like, at all!

In my mind-model, literals are not “expressions that require 
context to determine their type” but rather have their own type 
that's not spelled-out in any way, but has clearly defined 
operations, especially implicit casts. `typeof` won't infer that 
special type, quite to the contrary, `typeof` will give you a 
reasonably general type for the literal. If `lit` is a literal, 
it can happen that, as an expression, using `lit` alone works, 
but `(cast(typeof(lit)) lit)` will fail:

```D
int[] xs = cast(typeof([ 2: 3, 0: 1 ]))[ 2: 3, 0: 1 ]; // error
```

For that reason, one cannot refactor literals into enums like an 
idiot because enums must have a spelled-out type and `enum 
varName = expr;` is identical to `enum typeof(expr) varName = 
expr;`.

```D
enum lit = [ 2: 3, 0: 1 ];
int[] xs = lit; // error: cannot implicitly convert ... 
`int[int]` to `int[]`
```

I don't even think _polysemous_ values (learned the term 
recently) are a bad idea, they're _practically useful_ in many 
cases. I just think the D spec should be more open about it.

Before I forget it: `[ 2: 3, 1 ]` works as an expression for 
`int[]`, but not for `int[int]`, and `typeof([ 2: 3, 1 ])` does 
not compile and neither does D infer a template type for it. 
(It's D's version of “Initializer lists have no type!” by Scott 
Meyers[¹](https://www.youtube.com/watch?v=KAWA1DuvCnQ).) Worse, 
even if a slice type is hinted, it won't compile:
```D
void f(T)(T[]) { pragma(msg, T); }
f([ 2: 3, 1 ]); // expect: T == int, but error
```


More information about the Digitalmars-d mailing list