D needs a type expression syntax

Nick Treleaven nick at geany.org
Wed May 10 13:30:10 UTC 2023


On Saturday, 6 May 2023 at 16:20:56 UTC, Quirin Schroll wrote:
>> It could be trailing return type syntax:
>> ```d
>> function(ref int i) -> ref int refIdPtr;
>> ```
>> Then we don't need the `alias A = ref T` rule, and we can keep 
>> parentheses for expressions (including tuples in future).
>
> I agree that trailing return types (TRT) are really well 
> readable – in a language designed around them, which D isn’t. I 
> find it irritating that the `-> Type` is followed by the 
> variable name. In languages that have them, variables are 
> declared by a keyword, then follows the name, then a separator 
> and then comes the type. In that order, TRT makes sense.

It's the same pattern as `int var;` - `Type identifier;`. Do you 
think it would cause parsing ambiguities? If not, maybe you read 
it as naming the return type? In languages that have named return 
types, I think a named return would be written with parentheses: 
`-> (Type identifier)`.

> I put parts of a declaration in their own line when they’re 
> getting big: Big return type → own line. 1 big (template)

OK but that wastes vertical space, particularly in an IDE popup 
window with a long list of overloads.

> TRT are are a much greater language change, though, compared to 
> making a token at a very specific place optional. Their grammar 
> must really be implemented and maintained separately.

Conceptually I think it would be simple:

```
(function | delegate) ParameterList Attributes? -> StorageClass 
Type
StorageClass Identifier ParameterList Attributes? -> StorageClass 
Type
```
```d
const method() -> int;
```

> Also, we get the same as C++: Two ways to declare a function.

Modern C++ may be moving toward using TRT, at least Herb Sutter 
recommends it. The idea is to move to TRT over time. Linters 
could enforce it.

>>> ```d
>>>  const Object  function()  f0; // Make this an error …
>>> const (Object  function()) f1; // … and require this!
>>> (const Object) function()  f2; // To differentiate from this.
>>>  const(Object) function()  f3; // (Same type as f2)
>>> ```
>>
>> I don't get what the issue is with f0 and f3, aren't they 
>> clear enough?
>
> With `f0`: Does `const` apply to the return value or the 
> variable `f0`? I’m quite adept with D and I’m only 95% sure it 
> applies to `f0`. 95 is not 100, and frankly, when it comes to 
> syntax, it should be 100.

You're right, `f1` is better. I thought I was used to const 
applying to the variable/parameter, but I just confused myself 
trying to get a parameter to work:

```d
void f(const ref int function() p);
```
(I started thinking if the function could have leading const, ref 
would parse). Although if leading const on functions was 
deprecated there might be less confusion for the parameter case.

> With `f3`: Less of an issue, but basically the same. To someone 
> new to D, it might be odd that `const` applies to something 
> different if a parenthesis follows.

OK. I'm not sure if parenthesized types would complicate parsing.


More information about the Digitalmars-d mailing list