Thread overview
Parametric attributes
Oct 02
Manu
October 02
I feel like we really need parametric attributes...

I constantly have situations like this:
  void f(CallbackFun cb) { cb(); }
Where the attribute-ness of a function depends on the attribute-ness of the
callback.

I want my function to be @nogc, but I don't want to require the user supply a @nogc callback to use my API.

If we're going to have all these attributes, then we really need something
like this:
  void f(CallbackFun cb) @nogc(is(cb : @nogc))

This applies to the classic suite of attributes.

The trouble with this, obviously, is; how do you mangle this function? It's not a template... so...?

That problem feels loosely related to `inout`, which is an innovative hack... I wonder if some generalisation of that concept could be satisfying here, while also satisfying the actual input case (allowing to delete `inout` from the language)...?

It's a whole category of problem that needs some expression... where the attribute-ness of a declaration is dependent on the attribute-ness of some facet of the declaration; and where the declaration is not a template.


October 02
The simplest solution to this is what I call contract invalidation.

When passing in a callback, that has less guarantees on it and does not escape, the function will match it.

Timon wants something a lot more expressive such an effect system, and after last time I discussed with him on it, I haven't bothered to continue down this path.

Realistically somebody needs to make a decision here and run with it.

Are we going effect system like with variability to attributes, or a simpler subset of it.
October 02
On 10/2/24 02:49, Richard (Rikki) Andrew Cattermole wrote:
> The simplest solution to this is what I call contract invalidation.
> 
> When passing in a callback, that has less guarantees on it and does not escape, the function will match it.

As I also mentioned in my DConf talk last year, this just does not compose properly. You literally cannot express function composition.
October 02
On 10/2/24 02:43, Manu wrote:
> I feel like we really need parametric attributes...
> ...

I think so, too.

> I constantly have situations like this:
>    void f(CallbackFun cb) { cb(); }
> Where the attribute-ness of a function depends on the attribute-ness of the callback.
> 
> I want my function to be @nogc, but I don't want to require the user supply a @nogc callback to use my API.
> 
> If we're going to have all these attributes, then we really need something like this:
>    void f(CallbackFun cb) @nogc(is(cb : @nogc))
> ...

Basing the syntax on that of compile-time introspection seems like an interesting idea. However, in terms of implementation, passing around attribute parameters is perhaps simpler to pull off.

> This applies to the classic suite of attributes.
> 
> The trouble with this, obviously, is; how do you mangle this function? It's not a template... so...?
> ...

A simple way involves encoding bound variables by index.
https://en.wikipedia.org/wiki/De_Bruijn_index

> That problem feels loosely related to `inout`, which is an innovative hack... I wonder if some generalisation of that concept could be satisfying here, while also satisfying the actual input case (allowing to delete `inout` from the language)...?
> 
> It's a whole category of problem that needs some expression... where the attribute-ness of a declaration is dependent on the attribute-ness of some facet of the declaration; and where the declaration is not a template.

Yes. It would even be nice to have the option of passing entire type parameters at runtime. (Like the old druntime hooks do, but in a more user-friendly and type safe way.) But I think the most pressing issue is indeed function attributes.
October 02
On 10/2/24 02:43, Manu wrote:
> 
> The trouble with this, obviously, is; how do you mangle this function? It's not a template... so...?

Another interesting question is how it interacts with template instantiation (i.e., you instantiate a template with a type that contains a parametric attribute). One way would be to force local instantiation, another way involves adding parametric attributes to the instance itself.
October 02
On Wednesday, 2 October 2024 at 00:43:44 UTC, Manu wrote:
> I feel like we really need parametric attributes...
>
> I constantly have situations like this:
>   void f(CallbackFun cb) { cb(); }
> Where the attribute-ness of a function depends on the attribute-ness of the
> callback.
>
> [...]

What I like about the

"void f(CallbackFun cb) @nogc(is(cb : @nogc))"

solution is that it's "easy" to do with little work compared to other solutions while still being intuitive and cover most practical use cases.