[First Draft] Add @gc as a Function Attribute

Quirin Schroll qs.il.paperinik at gmail.com
Tue Jun 25 08:50:13 UTC 2024


On Saturday, 22 June 2024 at 04:37:01 UTC, Walter Bright wrote:
> On 6/14/2024 9:20 AM, Quirin Schroll wrote:
>> Permalink: 
>> https://github.com/Bolpat/DIPs/blob/8a26c2545b0a6926d799e9d8dc8c3662e58d516b/DIPs/DIP-4NNN-QFS.md
>> 
>> ---
>> 
>> **Abstract:** Add `@gc` as a new function attribute that acts 
>> as the inverse of the `@nogc` attribute.
>> 
>
> I've been thinking about a `@default` attribute, which will 
> reset the state of attributes to the defaults. This will 
> obviate the need for @gc, @impure, @throw, and so forth.

It doesn’t. Having a formal name for the inverse of an attribute 
has several advantages over just saying “default,” e.g. the 
compiler today spells out `@system` when printing function 
(pointer) and delegate types. Likewise, one can declare a 
function (template) explicitly `@system` and it would allow one 
to be explicit about `@gc` things.

If anything, I’d want to see `default` with regards to attributes 
used in a block or label statement with the meaning of changing 
the default attributes, but not touch inference. Something like:
```d
@nogc @safe
{
     void f() { … } // `@nogc @safe` by `@safe` `@nogc` block
     void g(T)() { … } // `@gc`/`@nogc` `@safe`/`@system` 
inference disabled
}
```
```d
default @nogc @safe
{
     void f() { … } // `@nogc @safe` by `default @nogc @safe` block
     void g(T)() { … } // `@gc`/`@nogc` `@safe`/`@system` 
inference enabled
}
```
The `default …` block sets defaults. We can easily define 
`default:` and `default{}` to mean `default @system throw @gc 
impure` (or the module default, see below), but without an 
`impure` keyword, in a `@safe pure:` context, one would have to 
do:
```d
default @safe pure:
…

default // idea: `default impure`, but is actually `default 
impure @system`, therefore ...
{
default @safe: // ... set `@safe` as default again
     …
}
```
to apply impure as the default. That is annoying because 
expressing a simple idea becomes hard. A programming language is 
a language to express ideas human-to-human and incidentally 
human-to-machine.

Applying `default` to a declaration directly goes against the 
whole idea of what a default setting is.

I also see a difference between specifying default attributes for 
a module versus what’s formally a part of a module (even if it 
happens to span the whole module). E.g.
```d
default @safe
module m;
```
would differ from
```d
module m;
default @safe:
```
by how function pointer and delegate types are interpreted:
```d
module m;
@safe: // same as `default @safe:` in this example
void f(void function() callback) { }
```
makes `typeof(&f)` be `void function(void function() @system) 
@safe`, whereas
```d
default @safe
module m;
void f(void function() callback) { }
```
makes `typeof(&f)` be `void function(void function() @safe) 
@safe`.

The type of the function parameter is `@safe`/`@system` based on 
the module’s default and nothing else. I suspect that making any 
attribute the default, higher-order functions will be a big 
hurdle because no matter if a the new language-level default 
affects parameters of function pointer / delegate types or not, 
things break. However, for an individual code base, changing the 
default for a module in this way can make sense and happen to be 
without issues. Making `@safe` the language default *requires* 
something like 
[ADAs](https://github.com/Geod24/DIPs/blob/adas/DIPs/DIP4242.md), 
but allowing for module-specified defaults is orthogonal.


More information about the dip.development mailing list