digitalmars.dip.development - [First Draft] Add gc as a Function Attribute
- Quirin Schroll (5/5) Jun 14 Permalink:
- Richard (Rikki) Andrew Cattermole (9/16) Jun 14 At some point I wanted to do a DIP that ensured all attributes had a
- ryuukk_ (4/20) Jun 16 Why couldn't attributes accept a parameter, perhaps a flag
- Richard (Rikki) Andrew Cattermole (11/14) Jun 16 Right now we have yes/no, infer(red)/explicit bit fields for some flags.
- Quirin Schroll (33/35) Jun 17 Attributes taking booleans would be a separate DIP. As I wrote in
- Quirin Schroll (34/50) Jun 17 This is like 4 orthogonal proposals.
- jmh530 (3/8) Jun 14 The DIP makes it seem like it is an escape-hatch for @nogc. But
- Quirin Schroll (6/16) Jun 17 You didn’t understand the DIP. It’s not an escape hatch. `@gc` is
- jmh530 (24/34) Jun 17 I said "The DIP makes it seem like it is an escape-hatch". I
- Dom DiSc (5/7) Jun 17 A block is nothing. A block cannot call anything, it's just a
- jmh530 (8/16) Jun 17 My point is that the current behavior is that you know that every
- Quirin Schroll (16/33) Jun 17 It’s similar to how `@safe:` and `@safe{}` don’t mean every
- Mathias Lang (4/9) Jun 17 The rationale is very weak. If the only use case is to support
- Dom DiSc (8/19) Jun 18 I don't think so.
- Quirin Schroll (8/19) Jun 19 It’s exactly as strong or weak as adding `throw` as the inverse
- Walter Bright (4/12) Jun 21 I've been thinking about a `@default` attribute, which will reset the st...
- Dom DiSc (2/5) Jun 22 But will bite us if we ever changing the default :-/
- Quirin Schroll (85/97) Jun 25 It doesn’t. Having a formal name for the inverse of an attribute
- Walter Bright (10/10) Aug 18 Most of your post was about @safe/@trusted/@system. I had neglected to m...
- IchorDev (2/7) Aug 11 Excited to see that this got merged.
- Mike Parker (4/4) Aug 17 This DIP has been submitted for Formal Assessment as DIP 1047:
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.
Jun 14
On 15/06/2024 4: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.At some point I wanted to do a DIP that ensured all attributes had a positive form, a common negated syntax `` !identifier``, changed throwing to be set based `` throws(...)`` and add `` notls``, `` localnogc``. So I'm in support of this proposal, but it doesn't go anywhere near where it needs to in terms of scope. You're welcome to do the proposal instead as I'm busy on other things atm if it interests you.
Jun 14
On Friday, 14 June 2024 at 16:38:09 UTC, Richard (Rikki) Andrew Cattermole wrote:On 15/06/2024 4:20 AM, Quirin Schroll wrote:Why couldn't attributes accept a parameter, perhaps a flag ` gc(:yes | :local)`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.At some point I wanted to do a DIP that ensured all attributes had a positive form, a common negated syntax `` !identifier``, changed throwing to be set based `` throws(...)`` and add `` notls``, `` localnogc``. So I'm in support of this proposal, but it doesn't go anywhere near where it needs to in terms of scope. You're welcome to do the proposal instead as I'm busy on other things atm if it interests you.
Jun 16
On 16/06/2024 8:13 PM, ryuukk_ wrote:Why couldn't attributes accept a parameter, perhaps a flag | gc(:yes | :local)|Right now we have yes/no, infer(red)/explicit bit fields for some flags. The only attribute that we've had consistent desire to have local for is `` nogc`` it doesn't need to be supported for all. As positive/negative state of an annotate are both common things, it should take minimal characters to represent, in this case a single additional ``!``. So I don't think we need to over complicate it by introducing parameters to any attributes other than for the throws set and thats only because we need to be able to represent what a value type exception style exceptional handling mechanism would be returning in the type system.
Jun 16
On Sunday, 16 June 2024 at 08:13:33 UTC, ryuukk_ wrote:Why couldn't attributes accept a parameter, perhaps a flag ` gc(:yes | :local)`Attributes taking booleans would be a separate DIP. As I wrote in my answer to Rikki, local nogc should not be an attribute at all. C++ made `noexcept` take a boolean. C++ also made `noexcept` a unary operator that returns a boolean if the expression inside uses only `noexcept` stuff. D could easily do the same with `nothrow` and `pure` (as those are first-class keywords). It makes less sense for ` safe` (a program is supposed to be UB-free anyways), but it would make sense for ` nogc`. I don’t think D would be clever to follow C++’s syntax with a prefix operator. [My preferred syntax would be postfix](https://issues.dlang.org/show_bug.cgi?id=23797) `is pure`, `is nothrow`, `is nogc`, and yes, even `is safe`. Those would operate on types, though, meaning you’d have to write `typeof({ expression; }) is nogc`. The `typeof` returns a function pointer or delegate type which has attributes inferred and those attributes can be queried using the new syntax. You could use these together: ```d void higherOrderFunction(DG)(scope DG callback) safe(DG is safe) nogc(DG is nogc) { … } ``` As for the query for member function attributes that are also type qualifiers, I’d suggest a syntax similar to the one I proposed in [Issue 20010)](https://issues.dlang.org/show_bug.cgi?id=20010): `DG is ...const`. For example, a template could have an `if (DG is ... const pure)` restriction so that it’s guaranteed the callback’s results can be cached. (If a delegate isn’t `const` it can maintain state in its context, and if it’s not pure, it can maintain state globally.)
Jun 17
On Friday, 14 June 2024 at 16:38:09 UTC, Richard (Rikki) Andrew Cattermole wrote:On 15/06/2024 4:20 AM, Quirin Schroll wrote:This is like 4 orthogonal proposals. I have no clue what ` notls` would do exactly. If anything, `localnogc` should be a pragma (probably named differently) as it provides no actual guarantees. I know from other posts that its intention is to particularly guarantee that array literals and closures present in the function block aren’t GC-allocated. It means nothing for the caller of a function, it only means something for the implementer. The question if a closure is allocated or not is practically the same if the compiler recognizes your specific case. It does not make sense as a function attribute as a caller need not know about it. Set-based exception specifications are controversial. I’m not sure if they’re a win or not, but this proposal is completely unrelated. Zig has them, but Zig has return-based exceptions, where anything other than a white list of possible exceptions is hard to imagine. Java’s are considered a failure and C++ removed them.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.At some point I wanted to do a DIP that ensured all attributes had a positive form, a common negated syntax `` !identifier``, changed throwing to be set based `` throws(...)`` and add `` notls``, `` localnogc``.So I'm in support of this proposal, but it doesn't go anywhere near where it needs to in terms of scope.Yes, the scope of this DIP is to be small and uncontroversial.You're welcome to do the proposal instead as I'm busy on other things atm if it interests you.The `pragma(nogcClosures)` and `pragma(nogcArrayLiterals)` should not even require a DIP. I cannot write anything about `notls` as I don’t know what it means. I can write a DIP for a complete revision of guarantee-making attributes, and that would include things like attribute `inout`s/attribute variables. I once wrote a DIP draft for something like that; ADAs comes close. My takeaway is that very ambitious DIPs generally make it nowhere. My sense is: Let’s first add contravariant inverses (guarantee-absence indicating) for ` nogc` and `pure`. Those solve a very basic non-orthogonality issue. Then let’s talk about guarantee-making attributes taking booleans or variables for guarantee-making attributes.
Jun 17
On Friday, 14 June 2024 at 16:20:02 UTC, 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.The DIP makes it seem like it is an escape-hatch for nogc. But then nogc would no longer be providing any guarantees.
Jun 14
On Friday, 14 June 2024 at 19:19:15 UTC, jmh530 wrote:On Friday, 14 June 2024 at 16:20:02 UTC, Quirin Schroll wrote:You didn’t understand the DIP. It’s not an escape hatch. ` gc` is just an explicit form of the default behavior allowing GC allocations. You can’t call a ` gc` function from a ` nogc` function, the same as you can’t call a ` system` function from a ` safe` function.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.The DIP makes it seem like it is an escape-hatch for nogc. But then nogc would no longer be providing any guarantees.
Jun 17
On Monday, 17 June 2024 at 11:37:22 UTC, Quirin Schroll wrote:On Friday, 14 June 2024 at 19:19:15 UTC, jmh530 wrote:I said "The DIP makes it seem like it is an escape-hatch". I didn't say "The DIP introduces an escape-hatch". It's not that I didn't understand it, so much as I'm doing my best to try to understand what it says and coming to an understanding that is inconsistent with what I think you intend. In the rationale section, you detail the motivation relating to the issue of dealing with adding a function that allocates with the GC to nogc blocks. You then introduce the example ```d nogc { int[] f() => [1]; // Error: array literal in ` nogc` function `f` may cause a GC allocation int[] g() gc => [1]; // Okay, `g` is not ` nogc` } ``` This makes it seem like you can have a function that may cause a GC allocation in a nogc block by adding the gc attribute. Maybe that's not what you intended, but you should spell it out in more detail if you intend something else. If gc means not nogc, then how can the compiler verify that it can be called from a nogc block?[snip] The DIP makes it seem like it is an escape-hatch for nogc. But then nogc would no longer be providing any guarantees.You didn’t understand the DIP. It’s not an escape hatch. ` gc` is just an explicit form of the default behavior allowing GC allocations. You can’t call a ` gc` function from a ` nogc` function, the same as you can’t call a ` system` function from a ` safe` function.
Jun 17
On Monday, 17 June 2024 at 13:02:12 UTC, jmh530 wrote:If gc means not nogc, then how can the compiler verify that it can be called from a nogc block?A block is nothing. A block cannot call anything, it's just a kind of namespace, meaning the same as declaring every function within it as " nogc". Of course nogc functions _cannot_ call a function marked as gc.
Jun 17
On Monday, 17 June 2024 at 13:10:16 UTC, Dom DiSc wrote:On Monday, 17 June 2024 at 13:02:12 UTC, jmh530 wrote:My point is that the current behavior is that you know that every function within ` nogc {}` does not allocate with the GC. Under this DIP, that's no longer guaranteed. So fine, it's not an "escape-hatch" per se, but it means that when you see ` nogc {}` or ` nogc:` it won't mean what it meant before. At the very least, if I can misunderstand it, then others could too.If gc means not nogc, then how can the compiler verify that it can be called from a nogc block?A block is nothing. A block cannot call anything, it's just a kind of namespace, meaning the same as declaring every function within it as " nogc". Of course nogc functions _cannot_ call a function marked as gc.
Jun 17
On Monday, 17 June 2024 at 13:36:25 UTC, jmh530 wrote:On Monday, 17 June 2024 at 13:10:16 UTC, Dom DiSc wrote:It’s similar to how ` safe:` and ` safe{}` don’t mean every function that follows is ` safe` because there can be ` system` or ` trusted` functions, and for `nothrow:`, while not implemented, the DIP adding `throw` as its inverse has been accepted. The general consensus is that guarantee-making attributes (` safe`, `pure`, `nothrow`, and ` nogc`) all should have inverses, and the only question is, what syntax they’ll have. This is answered for two of them already (` system` and `throw`); this DIP answers it for the one of the two remaining ones for which is very easy: ` gc`.On Monday, 17 June 2024 at 13:02:12 UTC, jmh530 wrote:My point is that the current behavior is that you know that every function within ` nogc {}` does not allocate with the GC. Under this DIP, that's no longer guaranteed. So fine, it's not an "escape-hatch" per se, but it means that when you see ` nogc {}` or ` nogc:` it won't mean what it meant before.If gc means not nogc, then how can the compiler verify that it can be called from a nogc block?A block is nothing. A block cannot call anything, it's just a kind of namespace, meaning the same as declaring every function within it as " nogc". Of course nogc functions _cannot_ call a function marked as gc.At the very least, if I can misunderstand it, then others could too.It seems you didn’t actually misunderstand it, I just misunderstood you when you used the term _escape-hatch_ because an example of what I consider an escape-hatch is ` trusted`. I thought, you thought ` gc` would be the ` trusted` equivalent of ` nogc`, which it’s definitely not supposed to be.
Jun 17
On Friday, 14 June 2024 at 16:20:02 UTC, 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.The rationale is very weak. If the only use case is to support bad usage of ` attribute:` or ` attribute {}`, there is no benefit at all to this.
Jun 17
On Monday, 17 June 2024 at 22:01:18 UTC, Mathias Lang wrote:On Friday, 14 June 2024 at 16:20:02 UTC, Quirin Schroll wrote:I don't think so. If a program is all nogc except a single function (or even a unittest), using nogc: is plausible. I wouldn't call this "bad usage". But at the moment there is no way to mark this single test as "not nogc". I find this situation annoying. The same problem arises with pure: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.The rationale is very weak. If the only use case is to support bad usage of ` attribute:` or ` attribute {}`, there is no benefit at all to this.
Jun 18
On Monday, 17 June 2024 at 22:01:18 UTC, Mathias Lang wrote:On Friday, 14 June 2024 at 16:20:02 UTC, Quirin Schroll wrote:It’s exactly as strong or weak as adding `throw` as the inverse of `nothrow` was. The only argument that is different between DIP 1029 and this is that `throw` was already a keyword whereas ` gc` would have to be added. Compare that to the (hypothetical) suggestion of adding `impure` as a keyword to have an inverse of `pure`.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.The rationale is very weak. If the only use case is to support bad usage of ` attribute:` or ` attribute {}`, there is no benefit at all to this.
Jun 19
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.
Jun 21
On Saturday, 22 June 2024 at 04:37:01 UTC, Walter Bright wrote: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.But will bite us if we ever changing the default :-/
Jun 22
On Saturday, 22 June 2024 at 04:37:01 UTC, Walter Bright wrote:On 6/14/2024 9:20 AM, Quirin Schroll wrote: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.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.
Jun 25
Most of your post was about safe/ trusted/ system. I had neglected to mention that default wouldn't apply to that, as there is no purpose to it for those attributes. default would only apply to nothrow, pure, nogc. It would not override inference. For example, nogc default = as if nogc never happened default = no effect default nogc = nogc and so on. This addresses your issues.
Aug 18
On Friday, 14 June 2024 at 16:20:02 UTC, 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.Excited to see that this got merged.
Aug 11
This DIP has been submitted for Formal Assessment as DIP 1047: https://forum.dlang.org/post/ycvbiosyhqfljxaspbqj forum.dlang.org Please consider this thread closed. Further posts will be deleted. Thanks!
Aug 17