January 12, 2024
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
> void 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.
January 12, 2024
On 12/01/2024 12:09 PM, Jonathan M Davis wrote:
> @nogc doesn't even prevent collections running while a function is called. It just prevents that specific function from triggering the collection (thanks to no allocations triggering it). Another thread could trigger a collection while that function is running. So, yes, in a single-threaded program, it's equivalent to calling GC.disable, but in the general case, it isn't.
> 
> 
> So, anyone actually relying on @nogc preventing collections is arguably asking for trouble even with the current GC - though it seems like the kind of folks who like to use @nogc are often the kind of folks who are likely to avoid the GC entirely, so if @nogc is used everywhere in their code, then they won't end up with either GC allocations or collections. However, anyone using it selectively really can't rely on it to avoid collections unless their program is single-threaded and will always remain so.

Yes.

It is fundamentally an attempt at informed consent at using the GC in selected code.

Which it does a terrible job at.
January 12, 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.
January 12, 2024
On 1/11/24 19:02, deadalnix wrote:
> 
> Sure on the other hand, of the top level languages, very few do have named arguments.
> C, C++, javascript, Jave, C#, Rust, PHP, Go, none of them has named argument.

https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/named-and-optional-arguments

https://stitcher.io/blog/php-8-named-arguments

https://www.jetbrains.com/help/go/inlay-hints.html

Ok, I am cheating with the last one.
January 11, 2024

On Thursday, 11 January 2024 at 18:38:37 UTC, max haughton wrote:

>

On Thursday, 11 January 2024 at 18:23:00 UTC, deadalnix wrote:

>

Yes. Who maintain these for each editor? Nobody because cost > benefits. And for as long as this is the case, the ecosystem will shrink.

Its a protocol. You only need one; there is one https://github.com/Pure-D/serve-d

https://xkcd.com/927/

January 11, 2024
On Thursday, 11 January 2024 at 18:39:29 UTC, H. S. Teoh wrote:
> On Thu, Jan 11, 2024 at 06:24:46PM +0000, deadalnix via Digitalmars-d wrote:
>> On Thursday, 11 January 2024 at 18:20:29 UTC, H. S. Teoh wrote:
>> > It's always more exciting to work on new features, to invent the next thing that will revolutionize D.  Improving the quality of existing features?  Too boring, too tedious, and totally unrewarding.  Guess what gets done, and what doesn't.
>> > 
>> 
>> It looks like management need to start saying no. And do bad if some people quit. The alternative is the whole thing stagnate of sink.
>
> That's what the aforementioned company did, and they went under.
>
> The root of the problem lies in their policy of hiring only the best people, people who are not interested in doing the menial, but necessary work.
>
>
> T

These are clearly not the best people.
January 12, 2024
On 12/01/2024 12:29 PM, Timon Gehr wrote:
>     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
> 
> |int opApply(@called scope int delegate() dg)b{ ... } |
> 
> As syntactic sugar for:
> 
> |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.

Yes.

We'd still need to keep the ``scope`` stuff on the delegate wrt. ``@safe`` as part of the weakening logic.

However I think the main thing is that the function body gets typed checked with the assumption that the most restrictive set holds. And only the caller sees that the contract has been invalidated in the error case.

Now we really only need to come up with a story that can be easily described to the user in both simple and complex cases, and describe it to the compiler also.

January 11, 2024
On Thursday, 11 January 2024 at 19:33:48 UTC, Walter Bright wrote:
> On 1/11/2024 5:07 AM, deadalnix wrote:
> > such as @nogc, has been a productivity disaster
>
> I don't really understand this. Just don't use @nogc?

And don't use any library. Got it.
January 11, 2024
On Thursday, 11 January 2024 at 20:03:36 UTC, Paolo Invernizzi wrote:
> I've no ideas how you can have a list or external created pthreads without horrible hack like hooking pthread_create.
>
> /P

Yes. This is a fairly standard stunt. boehm does it for instance. tsan as well.
January 12, 2024

On Thursday, 11 January 2024 at 23:09:46 UTC, Jonathan M Davis wrote:

>

@nogc doesn't even prevent collections running while a function is called. It just prevents that specific function from triggering the collection (thanks to no allocations triggering it). Another thread could trigger a collection while that function is running. So, yes, in a single-threaded program, it's equivalent to calling GC.disable, but in the general case, it isn't.

So, anyone actually relying on @nogc preventing collections is arguably asking for trouble even with the current GC - though it seems like the kind of folks who like to use @nogc are often the kind of folks who are likely to avoid the GC entirely, so if @nogc is used everywhere in their code, then they won't end up with either GC allocations or collections. However, anyone using it selectively really can't rely on it to avoid collections unless their program is single-threaded and will always remain so.

  • Jonathan M Davis

Indeed. I think that highly experienced D devs understand these subtle distinctions. But to the average dev it looks like an easy out. And IMO, this is the source of much of the angst over @nogc. The name implies that the GC is disabled during execution, and in single threaded programs it effectively is, but step outside of that box and the GC pause magically reappears despite @nogc being applied. So it appears to the average person that the language isn't doing as instructed. What people expect @nogc to do versus what it's specified to do are different things. But because people typically presume that their assumptions are correct they launch rants on the NGs before they bother to read the spec.

To some extent Rikki is right that @nogc might be better as a linter, because what it actually does is more in line with what a linter is expected to do. @nogc is a hygiene feature that can easily be misunderstood as doing something more than that.