www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Syntax ideas for `ref` returning delegate and FP parameters

reply Q. Schroll <qs.il.paperinik gmail.com> writes:
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
next sibling parent reply Nick Treleaven <nick geany.org> writes:
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
parent Nick Treleaven <nick geany.org> writes:
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
prev sibling next sibling parent reply MoonlightSentinel <moonlightsentinel disroot.org> writes:
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
parent Kagamin <spam here.lot> writes:
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
prev sibling next sibling parent reply user1234 <user1234 12.de> writes:
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
parent Q. Schroll <qs.il.paperinik gmail.com> writes:
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:
 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.
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.
Apr 11 2021
prev sibling next sibling parent Boris Carvajal <boris2.9 gmail.com> writes:
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
prev sibling parent Dukc <ajieskola gmail.com> writes:
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