named arguments, string interpolation, please stop.

Timon Gehr timon.gehr at gmx.ch
Thu Jan 11 23:29:16 UTC 2024


On 1/12/24 00:18, Richard (Rikki) Andrew Cattermole wrote:
> 
> On 12/01/2024 12:12 PM, Timon Gehr wrote:
>> On 1/12/24 00:04, Richard (Rikki) Andrew Cattermole wrote:
>>> On 12/01/2024 11:56 AM, Timon Gehr wrote:
>>>> On 1/11/24 23:37, Richard (Rikki) Andrew Cattermole wrote:
>>>>> On 12/01/2024 11:33 AM, Timon Gehr wrote:
>>>>>> If you do that D can no longer correctly implement a higher-order 
>>>>>> function that forms the composed function from its two arguments. 
>>>>>> It looks good on paper for a few minutes, but this is not a good 
>>>>>> solution to apply by default.
>>>>>
>>>>> Unless we get something different that solves the same premise, 
>>>>> opt-in is fine.
>>>>>
>>>>> I'm thinking explicitly for things like ``opApply``. Having giant 
>>>>> mixin templates that handle all combinations is far worse.
>>>>
>>>> Yes, attribute polymorphism is needed for that case, but currently 
>>>> there is no way to abstract over attributes and this is invariably 
>>>> the point where language features become a bit too esoteric for 
>>>> people (both language designers and users) who are not type system 
>>>> experts and then ad-hoc hacks proliferate.
>>>
>>> I am very open to a counter proposal that covers the points you have 
>>> outlined.
>>> ...
>>
>> The way this is usually handled is via generic parameters.
>>
>> First, make attributes first class, so stuff like this just works:
>>
>> alias nice=pure @nogc @safe nothrow;
>>
>> void foo()@nice{}
>>
>> Then, you need generic parameters, I'll indicate them with `[]`:
>>
>> ```d
>> int opApply[functionAttribute a](scope int delegate()a dg)a{
>>      ....
>> }
>> ```
>>
>> Done. Here, everything in `[]` exists only at compile time (think of 
>> it as ghost variables), and there is only one `opApply` function at 
>> runtime.
> 
> What you have presented here is what I mean by template solution (minus 
> the template).
> 
>>> Right now, contract invalidation + finely grained template solution 
>>> for when you need more control is the bar to beat, at least for me.
>>>
>>> Either way, right now this problem is dividing the community and 
>>> causing significant issues with attributes in practice. It needs 
>>> solving. It would be a major pressure release for this subject for 
>>> many people.
>>>
>>
>> I am not saying don't do the ad-hoc hacks, but understand that this is 
>> what you are doing. `inout` was a decent hack, until you need to do 
>> something a bit more involved, e.g. `opApply`. Opt-in invalidation is 
>> a decent option, until you run into the same issue again at a slightly 
>> higher level of abstraction, necessitating the next hack. The mess 
>> that will be left behind will be more complicated than the proper 
>> solution would have been, even though now it may appears that what I 
>> am suggesting is more complicated.
> 
> What I'm wondering now is if we can reframe the problem, so that 
> contract invalidation is an application of the template solution, so 
> that it can scale without further hacks.

Well, you can view

```d
int opApply(@called scope int delegate() dg)b{ ... }
```

As syntactic sugar for:

```d
int opApply[functionAttribute __a37 :> b](scope int delegate()__a37 
dg)__a37{ ... }
```

Where `a :> b` means you can call a `b` function from an `a` context, 
i.e., `__a37` may weaken the guarantees given by `b` and allow function 
types that can type more values into the function.


More information about the Digitalmars-d mailing list