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