digitalmars.D - Syntax ideas for `ref` returning delegate and FP parameters
- Q. Schroll (37/37) Apr 10 2021 Currently in D, one cannot directly express that a function
- Nick Treleaven (4/13) Apr 10 2021 I don't mind that. Also this (particularly if std.meta.Alias was
- Nick Treleaven (2/3) Apr 10 2021 Actually that doesn't work :-/
- MoonlightSentinel (7/12) Apr 10 2021 Maybe allow `ref` as a postfix?
- Kagamin (7/12) Apr 13 2021 An obvious solution.
- user1234 (18/30) Apr 10 2021 Slightly off topic but very curiously `auto ref` seems to have
- Q. Schroll (7/37) Apr 11 2021 No. When doing `f(&a)`, the `auto ref` boils down to by copy
- Boris Carvajal (12/13) Apr 11 2021 https://github.com/dlang/dmd/pull/10018#issuecomment-504347888
- Dukc (4/16) Apr 13 2021 Question to somebody more familiar with grammar specs: is this
Currently in D, one cannot directly express that a function parameter's type is a delegate or function pointer that returns by `ref`. If you write ```D void f(ref int delegate() dg) { .. } ``` then `dg` will be bound by reference which is probably not what the user likely intended. It is equivalent to: ```D alias DG = int delegate(); void f(ref DG dg) { .. } ``` I guess it should be possible to express ```D alias refDG = ref int delegate(); void f(refDG dg) { .. } ``` without an alias. The obvious idea is allowing ```D void f(int delegate() ref dg) ``` but I really dislike not having `ref` next to the return type. I guess most users read `ref int` as a pseudo type, so having them separated is misleading. Another was a breaking change making `ref` part of the delegate type when spelled out: ```D void f(ref int delegate() dg) { .. } ``` would take `dg` by copy and `typeof(dg)` would be `ref int delegate()`. If you want to take the delegate by reference, use an alias. A third one that is a little obscure is allowing `ref(int)` as a syntax for delegate and function pointer return types. Then it would be akin to `const int* method()` being different from `const(int*) method()`. Do you guys have any better ideas? I don't really like mine.
Apr 10 2021
On Saturday, 10 April 2021 at 14:27:31 UTC, Q. Schroll wrote:```D alias refDG = ref int delegate(); void f(refDG dg) { .. } ``` without an alias. The obvious idea is allowing ```D void f(int delegate() ref dg) ``` but I really dislike not having `ref` next to the return type.I don't mind that. Also this (particularly if std.meta.Alias was in object.d) is a workaround: void f(Alias!(ref int delegate()) dg);
Apr 10 2021
On Saturday, 10 April 2021 at 15:26:16 UTC, Nick Treleaven wrote:void f(Alias!(ref int delegate()) dg);Actually that doesn't work :-/
Apr 10 2021
On Saturday, 10 April 2021 at 14:27:31 UTC, Q. Schroll wrote:A third one that is a little obscure is allowing `ref(int)` as a syntax for delegate and function pointer return types. Then it would be akin to `const int* method()` being different from `const(int*) method()`.That's the best option IMO because it adapts a well known pattern.Do you guys have any better ideas? I don't really like mine.Maybe allow `ref` as a postfix? ```d void foo(int ref delegate() dg) {} ``` Allthough that looks kinda weird.
Apr 10 2021
On Saturday, 10 April 2021 at 21:25:07 UTC, MoonlightSentinel wrote:Maybe allow `ref` as a postfix? ```d void foo(int ref delegate() dg) {} ``` Allthough that looks kinda weird.An obvious solution. It's composable too: ```d void foo(int ref delegate() ref delegate() dg) {} ```
Apr 13 2021
On Saturday, 10 April 2021 at 14:27:31 UTC, Q. Schroll wrote:Currently in D, one cannot directly express that a function parameter's type is a delegate or function pointer that returns by `ref`. If you write ```D void f(ref int delegate() dg) { .. } ``` then `dg` will be bound by reference which is probably not what the user likely intended. It is equivalent to: ```D alias DG = int delegate(); void f(ref DG dg) { .. } ```Slightly off topic but very curiously `auto ref` seems to have for effect to set the function pointer type return as `ref` rather than the parameter itself ```d void f(DG/* = int function()*/)(auto ref DG dg) { dg()++; } ref int a() { static int b; return b; } void main() { f(&a); assert(a == 1); // passes } ``` a bug certainly.
Apr 10 2021
On Sunday, 11 April 2021 at 05:44:58 UTC, user1234 wrote:On Saturday, 10 April 2021 at 14:27:31 UTC, Q. Schroll wrote:No. When doing `f(&a)`, the `auto ref` boils down to by copy (i.e. no `ref`) and `DG` is inferred by IFTI to be `int function() ref` which can easily be observed using `pragma(msg, DG)` in `f`. You can remove `auto ref` no problem. If you replace the comment by `: int function()`, you get a compile error, because `ref` return and value return are incompatible.Currently in D, one cannot directly express that a function parameter's type is a delegate or function pointer that returns by `ref`. If you write ```D void f(ref int delegate() dg) { .. } ``` then `dg` will be bound by reference which is probably not what the user likely intended. It is equivalent to: ```D alias DG = int delegate(); void f(ref DG dg) { .. } ```Slightly off topic but very curiously `auto ref` seems to have for effect to set the function pointer type return as `ref` rather than the parameter itself ```d void f(DG/* = int function()*/)(auto ref DG dg) { dg()++; } ref int a() { static int b; return b; } void main() { f(&a); assert(a == 1); // passes } ``` a bug certainly.
Apr 11 2021
On Saturday, 10 April 2021 at 14:27:31 UTC, Q. Schroll wrote:Do you guys have any better ideas? I don't really like mine.https://github.com/dlang/dmd/pull/10018#issuecomment-504347888 In short, allow putting function/delegate keyword at the beginning like function literals do: ```d // declaration function int(char c) fp = function int(char c) { ... }; // also function literal syntax already accepts 'ref' returns function ref int(char c) fp = function ref int(char c) { ... }; // as parameter void fun(ref function ref int(char c) fp); ```
Apr 11 2021
On Saturday, 10 April 2021 at 14:27:31 UTC, Q. Schroll wrote:Currently in D, one cannot directly express that a function parameter's type is a delegate or function pointer that returns by `ref`. If you write ```D void f(ref int delegate() dg) { .. } ``` then `dg` will be bound by reference which is probably not what the user likely intended. It is equivalent to: ```D alias DG = int delegate(); void f(ref DG dg) { .. } ```Question to somebody more familiar with grammar specs: is this behaviour enforced by the spec, or is it implementation-defined behaviour?
Apr 13 2021