| |
|
Timon Gehr
| 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.
|