Jump to page: 1 2
Thread overview
Feedback Thread: DIP 1032--Function pointers and Delegate Parameters...--Community Review Round 1
Apr 03, 2020
Mike Parker
Apr 03, 2020
Walter Bright
Apr 03, 2020
Dukc
May 20, 2020
Walter Bright
Apr 03, 2020
Jonathan Marler
May 20, 2020
Walter Bright
Apr 03, 2020
Jonathan Marler
May 20, 2020
Walter Bright
Apr 07, 2020
Piotr Mitana
May 20, 2020
Walter Bright
Apr 19, 2020
Mike Parker
April 03, 2020
This is the feedback thread for the first round of Communnity Review of DIP 1032, "Function pointers and Delegate Parameters Inherit Attributes from Function".

===================================
**THIS IS NOT A DISCUSSION THREAD**

Posts in this thread must adhere to the feedback thread rules outlined in the Reviewer Guidelines (and listed at the bottom of this post).

https://github.com/dlang/DIPs/blob/master/docs/guidelines-reviewers.md

That document also provides guidelines on contributing feedback to a DIP review. Please read it before posting here. If you would like to discuss this DIP, please do so in the discussion thread:

https://forum.dlang.org/post/ovllntpiebixbtrbiuxj@forum.dlang.org

==================================

You can find DIP 1032 here:

https://github.com/dlang/DIPs/blob/0c99bd854302ade3e6833080410e9050fddec346/DIPs/DIP1032.md

The review period will end at 11:59 PM ET on April 17, or when I make a post declaring it complete. Feedback posted to this thread after that point may be ignored.

At the end of this review round, the DIP will be moved into the Post-Community Round 1 state. Significant revisions resulting from this review round may cause the DIP manager to require another round of Community Review, otherwise the DIP will be queued for the Final Review.

==================================
Posts in this thread that do not adhere to the following rules will be deleted at the DIP author's discretion:

* All posts must be a direct reply to the DIP manager's initial post, with only two exceptions:

    - Any commenter may reply to their own posts to retract feedback contained in the original post

    - The DIP author may (and is encouraged to) reply to any feedback solely to acknowledge the feedback with agreement or disagreement (preferably with supporting reasons in the latter case)

* Feedback must be actionable, i.e., there must be some action the DIP author can choose to take in response to the feedback, such as changing details, adding new information, or even retracting the proposal.

* Feedback related to the merits of the proposal rather than to the contents of the DIP (e.g., "I'm against this DIP.") is allowed in Community Review (not Final Review), but must be backed by supporting arguments (e.g., "I'm against this DIP because..."). The supporting arguments must be reasonable. Obviously frivolous arguments waste everyone's time.

* Feedback should be clear and concise, preferably listed as bullet points (those who take the time to do an in-depth review and provide feedback in the form of answers to the questions in this document will receive much gratitude). Information irrelevant to the DIP or is not provided in service of clarifying the feedback is unwelcome.
April 03, 2020
This is a significant breaking change.

This is very common:
struct S
{
   private int delegate() _dg;
   @property void dg(int delegate() newdg) @safe pure nothrow { _dg = newdg; }
   @property auto dg() @safe pure nothrow inout { return _dg; }
}

The breaking changes and deprecations seems to downplay this scenario, reporting a very obscure "save these to a global" scenario.

The D world is full of types that store delegates, with setters and getters.

I would recommend having an opt-in attribute for this. Something like auto:

@safe pure nothrow @nogc
int foo(int delegate() auto dg, int function() auto fp)

There is also no discussion of templates, which infer attributes. What happens there? It's more complicated than at first glance, as the delegates passed can currently influence the template attribute detection.

e.g.:

T foo(T)(T delegate() dg, T function()) { return dg() + fp(); }

@system nothrow @nogc
{
  int delegate() dg1;
  int function() fp1;
}

@safe pure
{
  int delegate() dg2;
  int function() fp2;
}

foo(dg1, fp1);
foo(dg2, fp2);

Are these different template instantiations? If not, then you can ironically turn off delegate/function-pointer inferred attributes by making something a template.

-Steve
April 03, 2020
On 4/3/20 9:08 AM, Steven Schveighoffer wrote:
> T foo(T)(T delegate() dg, T function()) { return dg() + fp(); }

I should clarify this.

Since the delegates are provided not as template parameters but with a templated return value, the attributes can be inferred as normal. So this actually isn't an issue.

It's more when the template doesn't actually call the delegate or function, e.g.:

struct S(T)
{
    T delegate() _dg;
    void foo(T delegate() dg) { _dg = dg; }
}

foo can be inferred as @safe, @nogc, nothrow, pure. What happens to dg?

-Steve
April 03, 2020
On 4/3/2020 7:01 AM, Steven Schveighoffer wrote:
> On 4/3/20 9:08 AM, Steven Schveighoffer wrote:
>> T foo(T)(T delegate() dg, T function()) { return dg() + fp(); }
> 
> I should clarify this.
> 
> Since the delegates are provided not as template parameters but with a templated return value, the attributes can be inferred as normal. So this actually isn't an issue.
> 
> It's more when the template doesn't actually call the delegate or function, e.g.:
> 
> struct S(T)
> {
>      T delegate() _dg;
>      void foo(T delegate() dg) { _dg = dg; }
> }
> 
> foo can be inferred as @safe, @nogc, nothrow, pure. What happens to dg?
> 
> -Steve

Delegate/functionpointer parameters do not infer safe/nogc/pure/nothrow from their use inside the function. They don't do it now, and the dip does not suggest changing that.
April 03, 2020
On Friday, 3 April 2020 at 10:31:12 UTC, Mike Parker wrote:
> [snip]

I completely disagree with the notion that delegates with conventional syntax should inherit the attributes of the function. First, the code breakage is going to be high relative to the benefit. Second, we are talking about adding a special case to the language semantics, that is likely going to be hard to understand and thus, to learn and remember.

If this proposal is changed to only propose this change to `lazy` parameters, it might just be worth considering. `lazy` is already kind of "special" in it's behaviour so I could see the special casing pshycologically easier to accept there. But even there I'm sceptical.

What I'm saying next will be off the scope of the DIP, but I say it because of the possibility that the DIP is unintentionally trying to solve the wrong problem. The biggest problem with delegates in attributes is not that they don't infer the attributes from the called function -vice versa! In the ideal world, the called function would infer it's attributes from the delegate, not unlike how `inout` function infers it's return value constness from constness of the `inout` parameter.
April 03, 2020
On Friday, 3 April 2020 at 10:31:12 UTC, Mike Parker wrote:
> This is the feedback thread for the first round of Communnity Review of DIP 1032, "Function pointers and Delegate Parameters Inherit Attributes from Function".
>
> ===================================
> **THIS IS NOT A DISCUSSION THREAD**
>
> Posts in this thread must adhere to the feedback thread rules outlined in the Reviewer Guidelines (and listed at the bottom of this post).
>
> https://github.com/dlang/DIPs/blob/master/docs/guidelines-reviewers.md
>
> That document also provides guidelines on contributing feedback to a DIP review. Please read it before posting here. If you would like to discuss this DIP, please do so in the discussion thread:
>
> https://forum.dlang.org/post/ovllntpiebixbtrbiuxj@forum.dlang.org
>
> ==================================
>
> You can find DIP 1032 here:
>
> https://github.com/dlang/DIPs/blob/0c99bd854302ade3e6833080410e9050fddec346/DIPs/DIP1032.md
>
> The review period will end at 11:59 PM ET on April 17, or when I make a post declaring it complete. Feedback posted to this thread after that point may be ignored.
>
> At the end of this review round, the DIP will be moved into the Post-Community Round 1 state. Significant revisions resulting from this review round may cause the DIP manager to require another round of Community Review, otherwise the DIP will be queued for the Final Review.
>
> ==================================
> Posts in this thread that do not adhere to the following rules will be deleted at the DIP author's discretion:
>
> * All posts must be a direct reply to the DIP manager's initial post, with only two exceptions:
>
>     - Any commenter may reply to their own posts to retract feedback contained in the original post
>
>     - The DIP author may (and is encouraged to) reply to any feedback solely to acknowledge the feedback with agreement or disagreement (preferably with supporting reasons in the latter case)
>
> * Feedback must be actionable, i.e., there must be some action the DIP author can choose to take in response to the feedback, such as changing details, adding new information, or even retracting the proposal.
>
> * Feedback related to the merits of the proposal rather than to the contents of the DIP (e.g., "I'm against this DIP.") is allowed in Community Review (not Final Review), but must be backed by supporting arguments (e.g., "I'm against this DIP because..."). The supporting arguments must be reasonable. Obviously frivolous arguments waste everyone's time.
>
> * Feedback should be clear and concise, preferably listed as bullet points (those who take the time to do an in-depth review and provide feedback in the form of answers to the questions in this document will receive much gratitude). Information irrelevant to the DIP or is not provided in service of clarifying the feedback is unwelcome.

Instead of delegate/function pointer parameters implicitly inheriting all the attributes of the containing function, what if we made it "opt-in" with a single attribute? i.e.

@safe pure nothrow @nogc
int foo(int delegate() @inherit dg, int function() @inherit fp)
{
    return dg() + fp();
}

Advantages:

1. No code breakage
2. The developer sees @inherit and knows the function/delegate pointer it will contain extra attributes inherited from somewhere else.
3. You can still support the case where you don't want any attributes.  Example cases of this would be if you're not calling the pointer yourself, or, maybe the function itself is nothrow but it allows the function/delegate pointers to throw and catches/handles their exceptions without propogating them.
April 03, 2020
On Friday, 3 April 2020 at 10:31:12 UTC, Mike Parker wrote:
> This is the feedback thread for the first round of Communnity Review of DIP 1032, "Function pointers and Delegate Parameters Inherit Attributes from Function".
>
> ===================================
> **THIS IS NOT A DISCUSSION THREAD**
>
> Posts in this thread must adhere to the feedback thread rules outlined in the Reviewer Guidelines (and listed at the bottom of this post).
>
> https://github.com/dlang/DIPs/blob/master/docs/guidelines-reviewers.md
>
> That document also provides guidelines on contributing feedback to a DIP review. Please read it before posting here. If you would like to discuss this DIP, please do so in the discussion thread:
>
> https://forum.dlang.org/post/ovllntpiebixbtrbiuxj@forum.dlang.org
>
> ==================================
>
> You can find DIP 1032 here:
>
> https://github.com/dlang/DIPs/blob/0c99bd854302ade3e6833080410e9050fddec346/DIPs/DIP1032.md
>
> The review period will end at 11:59 PM ET on April 17, or when I make a post declaring it complete. Feedback posted to this thread after that point may be ignored.
>
> At the end of this review round, the DIP will be moved into the Post-Community Round 1 state. Significant revisions resulting from this review round may cause the DIP manager to require another round of Community Review, otherwise the DIP will be queued for the Final Review.
>
> ==================================
> Posts in this thread that do not adhere to the following rules will be deleted at the DIP author's discretion:
>
> * All posts must be a direct reply to the DIP manager's initial post, with only two exceptions:
>
>     - Any commenter may reply to their own posts to retract feedback contained in the original post
>
>     - The DIP author may (and is encouraged to) reply to any feedback solely to acknowledge the feedback with agreement or disagreement (preferably with supporting reasons in the latter case)
>
> * Feedback must be actionable, i.e., there must be some action the DIP author can choose to take in response to the feedback, such as changing details, adding new information, or even retracting the proposal.
>
> * Feedback related to the merits of the proposal rather than to the contents of the DIP (e.g., "I'm against this DIP.") is allowed in Community Review (not Final Review), but must be backed by supporting arguments (e.g., "I'm against this DIP because..."). The supporting arguments must be reasonable. Obviously frivolous arguments waste everyone's time.
>
> * Feedback should be clear and concise, preferably listed as bullet points (those who take the time to do an in-depth review and provide feedback in the form of answers to the questions in this document will receive much gratitude). Information irrelevant to the DIP or is not provided in service of clarifying the feedback is unwelcome.


I also want to point out that the "Breaking Changes and Deprecations" section is incorrect.

   > It is possible that a parameter declaration may require that a delegate or function pointer parameter have fewer attributes than the function itself. This would only be possible if the delegate or function pointer was never called, but was ignored or simply stored elsewhere.

It's possible that you want the function or delegate pointer to have fewer attributes even when you are calling it.

In my other comment I gave the "nothrow" example, where the function itself is nothrow but the function/delegate points can throw.  So I wanted to make sure that this use case is also addressed in this section.

Another use case off the top of my head is "pure".  You could be a pure function yourself, and call non-pure function/delegate pointers so long as they are inside debug blocks.

I'm sure there are other cases, the author has oversimplified the breaking changes here.

April 07, 2020
In some cases i may want to pass a @system delegate to a @safe function (or - more likely - method). The first case that comes into my mind is a constructor or setter.

import std;

struct C {
    void delegate() runner;

    this(void delegate() func) pure nothrow @safe @nogc {
        runner = func;
    }

    void run() {
        runner();
    }
}

void main() {
    C c = C(() { writeln("I am not pure!"); });
    c.run();
}

In this case after this DIP constructor either could not be marked pure etc (and it definitely is!). or could not accept this function pointer.

That limitation could also surface after longer period if I used the constructor with pure functions in general, but at some point I would need to pass a impure function. I would then need to impurify the constructor and every place I've used it so far.

That's why in my opinion either opt-in (like the suggested @inherit - but is it a good enough reason to introduce a new @attribute and possibly break a specific of UDA with this name?) or not at all. I think I could live without this improvement and either just mark them all or use a type alias.
April 19, 2020
On Friday, 3 April 2020 at 10:31:12 UTC, Mike Parker wrote:
>
> The review period will end at 11:59 PM ET on April 17, or when I make a post declaring it complete. Feedback posted to this thread after that point may be ignored.

This review round has ended. Thanks to everyone who provided feedback.
May 19, 2020
On 4/3/2020 3:23 PM, Dukc wrote:
> I completely disagree with the notion that delegates with conventional syntax should inherit the attributes of the function. First, the code breakage is going to be high relative to the benefit.

That would only be true if the function never calls the delegate (i.e. it only stores the delegate elsewhere), which does happen but is not the usual use.


> Second, we are talking about adding a special case to the language semantics, that is likely going to be hard to understand and thus, to learn and remember.

On the contrary, it will likely not even be noticed. For example, it only makes sense that a pure function would need its delegate parameters to also be pure so it can call them. It's annoying to have to specify `pure` twice.


> If this proposal is changed to only propose this change to `lazy` parameters, it might just be worth considering. `lazy` is already kind of "special" in it's behaviour so I could see the special casing pshycologically easier to accept there. But even there I'm sceptical.

The idea is to get rid of the special cases of lazy.


> What I'm saying next will be off the scope of the DIP, but I say it because of the possibility that the DIP is unintentionally trying to solve the wrong problem. The biggest problem with delegates in attributes is not that they don't infer the attributes from the called function -vice versa! In the ideal world, the called function would infer it's attributes from the delegate, not unlike how `inout` function infers it's return value constness from constness of the `inout` parameter.

Inferring function attributes from the delegate argument is impractical. For example, many delegates are trivial lambda functions, often inferred as pure. But the functions that call those delegates can rarely be pure. In effect, the function would have to be compilable with the *tightest* combination of attributes every time.
« First   ‹ Prev
1 2