digitalmars.dip.ideas - Optional attribute infering for `opApply`
- solidstate1991 (26/26) Mar 30 `opApply` has an attribute hell issue, and the only solution that
- libxmoc (15/41) Mar 30 I don't think adding "yet another" attribute will help solve the
- Richard (Rikki) Andrew Cattermole (39/41) Mar 30 Yes this isn't the right solution to the problem, nor does it reflect
`opApply` has an attribute hell issue, and the only solution that
worked reliably so far is to generate a lot of attribute
overloads with metaprogramming. However, it still didn't solve
the issue with ` trusted` functions, and had to completely leave
out ` trusted` attributes, so I can at least use it reliably in
` safe` and ` system` functions.
However, I think there should be a simpler way to do it. I was
thinking about something like this:
```d
pragma(inferAttributes)
int opApply (int delegate(ref T) dg) {
...
}
//Or something like this if it would be preferred
int opApply (int delegate(ref T) dg) inferAttributes {
...
}
```
This would turn `opApply` into a template, where the non-user
defined attributes are what being changed. There could be even an
argument for it, that would take an array of strings, that
contain the valid combinations of attributes for the given
function. Maybe it could be extended to other functions, that
take one or more delegates or function pointers as an argument.
Rikki on Discord did not like this kind of solution, but I'm
interested in what would others say about it.
Mar 30
On Monday, 30 March 2026 at 09:28:13 UTC, solidstate1991 wrote:
`opApply` has an attribute hell issue, and the only solution
that worked reliably so far is to generate a lot of attribute
overloads with metaprogramming. However, it still didn't solve
the issue with ` trusted` functions, and had to completely
leave out ` trusted` attributes, so I can at least use it
reliably in ` safe` and ` system` functions.
However, I think there should be a simpler way to do it. I was
thinking about something like this:
```d
pragma(inferAttributes)
int opApply (int delegate(ref T) dg) {
...
}
//Or something like this if it would be preferred
int opApply (int delegate(ref T) dg) inferAttributes {
...
}
```
This would turn `opApply` into a template, where the non-user
defined attributes are what being changed. There could be even
an argument for it, that would take an array of strings, that
contain the valid combinations of attributes for the given
function. Maybe it could be extended to other functions, that
take one or more delegates or function pointers as an argument.
Rikki on Discord did not like this kind of solution, but I'm
interested in what would others say about it.
I don't think adding "yet another" attribute will help solve the
current soup D is facing.
The solution may be to stop trying to perfect every attribute in
these overloads and to just skip analysis.
The compiler is being over engineered. opApply is just a
callback, it doesn't need this level of complexity.
I wish these static analysis passes were handled by external
tooling instead, similar to Clippy in Rust, rather than baking
more rigid logic into the compiler itself. Any attempt to fix
something creates a cascade of regressions.
Compiler should stay lean and avoid trying to force fit every
edge case into the language specification.
This is the primary reason I currently cherish -betterC. Not
perfect, but helps strip away the noise.
Mar 30
On 30/03/2026 10:28 PM, solidstate1991 wrote:Rikki on Discord did not like this kind of solution, but I'm interested in what would others say about it.Yes this isn't the right solution to the problem, nor does it reflect the actual issues surrounding attributes. "Attribute soup" exists because of the following two reasons: 1. Inference is NOT implemented using chaotic iteration[1]. This is a consequence of the attributes being in the type system, where the type system was designed to be fast using a simpler analysis algorithm. 2. What I'll be calling effect calculus has no solution in D. Basically its all about how effects in the algebraic effect system combines together. I've tried to find a solution to effect calculus for D, however there is no point in doing so due to TSAA not being chaotic iteration. Timon clued me into this ages ago, but hasn't put forth a design as far as I'm aware and none of mine stood up to basic verification. To understand why your solution wouldn't work its actually pretty easy to test, make your ``opApply`` return ``auto``, this will turn on attribute inference. Yes you can turn on the inference for the function, but once you've done that, that is the attributes on that function set. They are in the type system fixed in place and must be satisfied. You cannot know with these attributes alone, which may be violated and under what condition(s). They cannot express this, nor can the compiler represent and analyze it. We cannot change how inference occurs in semantic analysis, when it comes to the type system. This is a fixed architecture decision. So I want anyone reading this to consider is not all attributes should be classed as inferrable, some need to be explicit in normal usage. A great example of this is `` safe`` `` trusted`` `` system``. These attributes do not suffer these problems, because you want the errors generated by the wrong one picked. The others ``nothrow`` `` nogc`` ``pure`` ``scope`` ``return`` on the other hand need to be analyzed in the context of the caller, a much different situation. Ultimately I see no future for ``nothrow`` `` nogc`` ``pure`` ``scope`` ``return`` as they are implemented today. They are on my todo list to kill off the moment we have an alternative solution to them for future editions. [1] Type System Analysis Algorithms: https://forum.dlang.org/post/waerqsesrohtokjctnyj forum.dlang.org [2] Why we should not enable a slow DFA by default: https://forum.dlang.org/post/xmssfygefvldeiyodfya forum.dlang.org
Mar 30









libxmoc <libxmoc gmail.com> 