-
-
Notifications
You must be signed in to change notification settings - Fork 98
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
DIP4242 (?): Argument dependent attributes (ADAs) #198
base: master
Are you sure you want to change the base?
Conversation
// Argument is not a delegate or function pointer | ||
void err2(int arg) @safe(arg); | ||
// Argument is not a delegate or function pointer | ||
void err3(int arg) @safe(0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The index version is quite confusing because of implicit boolean conversion (this looks like @safe(false)
to me)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Didn't think of that. The reason it's in is to support meta programming, where you really don't want to have to mess with identifiers. Sometimes you declare a function with a type tuple and in this case having ADAs support indexes is quite handy.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Couldn't the same be achieved by allowing @safe(tuple[index])
to refer to the actual parameter inside of a parameter tuple?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see how ? Or is tuple
a keyword here ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given the following function
void foo(T...)(T args) {}
Your current proposal suggests a plain index to specifiy a single parameter:
void foo(T...)(T args) @safe(0) {}
But this would be more expressive:
void foo(T...)(T args) @safe(args[0]) {}
Also a plain index doesn't work well with multiple variadic template parameters:
template bar(A...)
{
void bar(B...)(A a, B b) @safe(1) {} // Might refer to an element of a or b
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hum, those are good points. Index based ADAs are a special case for when an argument has no identifier. Since the grammar allows it, I figured there should be a way to handle it.
But even if that's the intended usage, the semantics should be made clearer. And the tuple example is quite neat and more expressive, I agree. Let me think this over for a bit.
This DIP aims to solve the common problem that arise when mixing delegates and attributes. It describes a language addition which the author feels will be natural to seasoned users that allow describing the relationship between a function's attribute and its callable(s) parameters.
Thanks for the feedback @MoonlightSentinel, comments addressed. |
I had a similar idea. Your DIP proposes a pure addition to the language which avoids breakage. My approach contains breakage (in theory), but immediately works for all templates that are written already. You may want to have a look at it: #199 As it stands, using |
To address this whole paragraph, my expectation is that generic code with use This is of course my intuition / expectation as designer of this feature and first user, and I suspect the best way to convince people is to provide a working PoC, which I'm workin on. I'll also check your DIP shortly. |
This is going to be very nice to have but two things:
|
It might be a late addition, but @tgehr convinced me in several private and public conversations that it’s much more orthogonal and valuable to add “attribute variables”, i.e. a something that (for it to be relevant) occurs two or more times in place of an attribute. As in mathematics, is the same everywhere. D already has something like this with inout₁(int) f(inout₂(bool)[] input, out inout₂(bool)* output) inout₁; I fear something like this is possibly happening with ADAs. Instead of referring to parameter names (or indices), maybe let e.g. void delegate() @safe(a) hof(void delegate() @safe(a) callback) @safe; It says that void hof(void function()[] callbacks) @safe(callbacks); is equivalent to void hof(void function() @safe(a)[] callbacks) @safe(a); Apart from the sugaring, using an attribute variable only once should be an error. If you need the parameter names of packs or unnamed ones, there is |
Just was talking about this on discord, we need a solution for something like: void foo(T)(T val, void delegate() dg) ???
{
val.member();
dg();
} Basically, An alternative that I have been thinking about, what if you just use // you wrote
void toString (scope void delegate(in char[]) sink) const
@safe(sink) pure(sink) nothrow(sink) @nogc(sink)
// I'm thinking:
void toString (scope void delegate(in char[]) @called sink) const
@safe pure nothrow @nogc; I think this works, without double-underscores, because nothing custom can go in that position. |
And you could infer
I'll have to think about it, but I think it's not granular enough. Definitely need to add a section in the DIP about that idea, though. |
Shouldn’t the |
Maybe, but also, you are doing funky things to connect the attributes of the argument to the attributes of the function itself. i.e. it's like a placeholder for the argument that you pass in. If you put it as a parameter attribute, it probably has to be |
This DIP aims to solve the common problem that arise when mixing delegates and attributes.
It describes a language addition which the author feels will be natural to seasoned users
that allow describing the relationship between a function's attribute and its callable(s) parameters.