-
-
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
DIP: Function pointers and Delegate Parameters Inherit Attributes fro… #170
Conversation
|
What happens if the user doesn't want inherited attributes? @safe/@trusted/@System are easy and trivial to "revert", but the same can't be said for |
Discussed on line 113. Also, |
|
I don't know how I missed that, sorry. |
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.
Only functions are mentioned here, nothing about templates functions.
Templated functions usually have their attributes inferred, and taking a delegate affect this inference. Given the prevalence of templated functions, how useful is this ?
Additionally, it is more magic to explain to the prospective user. I am not looking forward to explain the difference between the following:
/// Example 1
alias DG = void delegate (scope const char[]) @nogc;
void toString (scope DG sink) @safe;
/// Example 2
void toString (scope void delegate (scope const char[]) @nogc sink) @safe;
/// Example 3+4
@safe:
void toString (T) (const ref T val, scope void delegate (scope const char[]) @nogc sink);
void toString (T) (const ref T val, scope DG sink);In this case, example 1 behaves differently from example 2, but the same as example 3 and 4.
Finally, one of the main problem we have encountered with delegates is not copy pasting attributes from the function to the delegate parameter, but the inability to have a non-templated function define its attributes as depending on the delegate.
Take the classic toString sink example from Throwable:
class Throwable
{
void toString(scope void delegate(in char[]) sink) const { ... }
}What I want, as a user, is the ability to pass a @safe delegate and for the compiler to understand toString is @safe. Likewise, if I pass a pure @nogc delegate, and so on. This is the real problem that is preventing many use cases. On the other hand, having to duplicate some attributes has never been a problem, and this DIP doesn't give us any new feature, it just brings a doubtful benefit for a corner case.
|
@Geod24 The case you describe with Throwable's The sink issue could be solved by slightly changing what the attributes mean. In the current state, a I've thought about that some time ago and the edge cases of nested function types are a little mess. By nested function types, imagine if the sink parameter of It would still break some code: If an always- |
|
Function for an arbitrary number of lazy parameters work the same when the delegates are constructed by the compiler. If you write the delegate out yourself, it doesn't work. alias Dg = int delegate() @nogc @safe pure nothrow;
void funcWithLazies(Dg[] dgs...) @nogc @safe pure nothrow { }
int global = 10;
int func() @safe
{
import std.stdio;
writeln("func FTW!");
return global++;
}
void main() @safe
{
static assert( __traits(compiles, funcWithLazies( func))); // 1
static assert(!__traits(compiles, funcWithLazies(() => func))); // 2
}In this example, 1 compiles because whether the call to func is e.g. I have no knowledge of how the compiler handles attributes, but if it can do something like this already ( is checked as if it were Calling I have no idea, how the compiler handles attributes, but this is what's already happening for line 1. Basically, the compiler would only allow you to use some of its magic. |
Template functions do have their limitations, such as they can't be virtual.
I don't see a difference.
That is, indeed, precisely what templates are for, and this behavior (inference from templates) is relied on by much of Phobos.
I encountered it in Phobos when I was trying to replace lazy parameters in order to avoid the problems lazy has with more advanced pointer tracking. I expect it will come up repeatedly with trying to obsolete lazy.
It gives a path to replacing lazy, which has a murky specification, with a well-specified construct. It will render lazy obsolete, with an easy replacement. |
|
@Bolpat I'm not sure what you're really proposing. Adding more attributes looks simple, but they always seem to cause unexpected problems. I'd like to try really hard to avoid new attributes. |
👍
Sorry, I realize I was missing the attribute on the function.
I'm just going to quote you:
We had this discussion during out last meeting. @atilaneves seemed to have experienced the problem as well.
In the DIP, |
…m Function