www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Discussion Thread: DIP 1043--Shortened Method Syntax--Community Review

reply Mike Parker <aldacron gmail.com> writes:


This is the discussion thread for the first round of Community
Review of DIP 1043, "Shortened Method Syntax":

https://github.com/dlang/DIPs/blob/5a3b437f2b6be8fb23e855fc0da20f19f68edac8/DIPs/DIP1043.md

The review period will **end at 11:59 PM ET on February 18**, or
when I make a post declaring it complete. Discussion in this
thread may continue beyond that point.

Here in the discussion thread, you are free to discuss anything
and everything related to the DIP. Express your support or
opposition, debate alternatives, argue the merits, etc.

However, if you have any specific feedback on how to improve the
proposal itself, then please post it in the Feedback Thread. The
Feedback Thread will be the source for the review summary that I
will write at the end of this review round. I will post a link to
that thread immediately following this post. Just be sure to read
and understand the Reviewer Guidelines before posting there:

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

And my blog post on the difference between the Discussion and
Feedback threads:

https://dlang.org/blog/2020/01/26/dip-reviews-discussion-vs-feedback/

Please stay on topic here. I will delete posts that are 
completely off-topic.
Feb 04 2022
next sibling parent Mike Parker <aldacron gmail.com> writes:
On Friday, 4 February 2022 at 10:53:45 UTC, Mike Parker wrote:

 However, if you have any specific feedback on how to improve the
 proposal itself, then please post it in the Feedback Thread. The
 Feedback Thread will be the source for the review summary that I
 will write at the end of this review round. I will post a link 
 to that thread immediately following this post.
The Feedback Thread is here: https://forum.dlang.org/post/picueoqamrouueyntjmk forum.dlang.org
Feb 04 2022
prev sibling next sibling parent reply Elronnd <elronnd elronnd.net> writes:
It would be nice to permit something like this:

struct Foo {
     this(int x, string y) { ... }
     this(string y) => this(0, y);
}

Currently this fails because constructors are not allowed to 
return anything.  But that should not be part of this DIP, 
probably.
Feb 04 2022
parent reply max haughton <maxhaton gmail.com> writes:
On Friday, 4 February 2022 at 11:21:48 UTC, Elronnd wrote:
 It would be nice to permit something like this:

 struct Foo {
     this(int x, string y) { ... }
     this(string y) => this(0, y);
 }

 Currently this fails because constructors are not allowed to 
 return anything.  But that should not be part of this DIP, 
 probably.
The implementation as done by Adam is done in the parser but if I move it down the stack a bit this is probably doable.
Feb 04 2022
parent reply Paul Backus <snarwin gmail.com> writes:
On Friday, 4 February 2022 at 12:40:32 UTC, max haughton wrote:
 On Friday, 4 February 2022 at 11:21:48 UTC, Elronnd wrote:
 It would be nice to permit something like this:

 struct Foo {
     this(int x, string y) { ... }
     this(string y) => this(0, y);
 }

 Currently this fails because constructors are not allowed to 
 return anything.  But that should not be part of this DIP, 
 probably.
The implementation as done by Adam is done in the parser but if I move it down the stack a bit this is probably doable.
Please don't. Having `=> expr` be simple syntax sugar for `{ return expr; }` is consistent and easy to understand. We don't need to add special cases just to save a *single character*: this(string y) => this(0, y); this(string y) { this(0, y); }
Feb 04 2022
next sibling parent reply Tejas <notrealemail gmail.com> writes:
On Friday, 4 February 2022 at 14:46:39 UTC, Paul Backus wrote:
 On Friday, 4 February 2022 at 12:40:32 UTC, max haughton wrote:
 On Friday, 4 February 2022 at 11:21:48 UTC, Elronnd wrote:
 It would be nice to permit something like this:

 struct Foo {
     this(int x, string y) { ... }
     this(string y) => this(0, y);
 }

 Currently this fails because constructors are not allowed to 
 return anything.  But that should not be part of this DIP, 
 probably.
The implementation as done by Adam is done in the parser but if I move it down the stack a bit this is probably doable.
Please don't. Having `=> expr` be simple syntax sugar for `{ return expr; }` is consistent and easy to understand. We don't need to add special cases just to save a *single character*: this(string y) => this(0, y); this(string y) { this(0, y); }
Actually, the following compiles: ```d void funcc() { } void func() { return funcc(); } void main() { func(); } ``` So maybe the fact that `this(string y) => this(0, y);` doesn't compile is a compiler bug? Constructors return `void` after all, no?
Feb 04 2022
next sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 04.02.22 18:18, Tejas wrote:
 On Friday, 4 February 2022 at 14:46:39 UTC, Paul Backus wrote:
 On Friday, 4 February 2022 at 12:40:32 UTC, max haughton wrote:
 On Friday, 4 February 2022 at 11:21:48 UTC, Elronnd wrote:
 It would be nice to permit something like this:

 struct Foo {
     this(int x, string y) { ... }
     this(string y) => this(0, y);
 }

 Currently this fails because constructors are not allowed to return 
 anything.  But that should not be part of this DIP, probably.
The implementation as done by Adam is done in the parser but if I move it down the stack a bit this is probably doable.
Please don't. Having `=> expr` be simple syntax sugar for `{ return expr; }` is consistent and easy to understand.
Yes, no need to change the implementation of this feature, just fix semantic analysis of constructors.
 We don't need to add 
 special cases just to save a *single character*:
 ...
Sure, but actually, the fact that the example code does not already work with the current implementation of the feature is the special case. There is even less need to add special cases just so people have to waste an additional character. (Plus some white space, by the way, at least outside of personal projects. There may be strict style guidelines.)
     this(string y) => this(0, y);
     this(string y) { this(0, y); }
...
If you have to violate common style guidelines in order to support a claim that the status quo is not so much worse, then probably the new syntax is actually significantly better. (Razvan did the same in the feedback thread, I don't get why people are doing this. Would this really fly, e.g., in Phobos?)
 Actually, the following compiles:
 ```d
 void funcc()
 {
 }
 
 void func()
 {
      return funcc();
 }
 void main()
 {
      func();
 
 }
 ```
 So maybe the fact that `this(string y) => this(0, y);` doesn't compile 
 is a compiler bug? Constructors return `void` after all, no?
I think so, or at least it's an undesirable special case: ```d void foo(){ return; } struct S{ this(int x){ return; } // ok, can return void this(int x,int y){ return foo(); } // error } ``` "Error: cannot return expression from constructor"
Feb 04 2022
parent reply Paul Backus <snarwin gmail.com> writes:
On Friday, 4 February 2022 at 17:59:40 UTC, Timon Gehr wrote:
 On 04.02.22 18:18, Tejas wrote:
 On Friday, 4 February 2022 at 14:46:39 UTC, Paul Backus wrote:
     this(string y) => this(0, y);
     this(string y) { this(0, y); }
...
If you have to violate common style guidelines in order to support a claim that the status quo is not so much worse, then probably the new syntax is actually significantly better. (Razvan did the same in the feedback thread, I don't get why people are doing this. Would this really fly, e.g., in Phobos?)
It's not super common, but it does show up. Some examples: https://github.com/dlang/phobos/blob/v2.098.1/std/algorithm/setops.d#L901 https://github.com/dlang/phobos/blob/v2.098.1/std/algorithm/iteration.d#L2051-L2052 https://github.com/dlang/phobos/blob/v2.098.1/std/encoding.d#L487-L549 https://github.com/dlang/phobos/blob/v2.098.1/std/datetime/systime.d#L9564-L9574 https://github.com/dlang/phobos/blob/v2.098.1/std/math/exponential.d#L2748-L2755 https://github.com/dlang/phobos/blob/v2.098.1/std/experimental/allocator/building_blocks/stats_collector.d#L199-L200
Feb 04 2022
parent Timon Gehr <timon.gehr gmx.ch> writes:
On 2/4/22 20:44, Paul Backus wrote:
 On Friday, 4 February 2022 at 17:59:40 UTC, Timon Gehr wrote:
 On 04.02.22 18:18, Tejas wrote:
 On Friday, 4 February 2022 at 14:46:39 UTC, Paul Backus wrote:
     this(string y) => this(0, y);
     this(string y) { this(0, y); }
...
If you have to violate common style guidelines in order to support a claim that the status quo is not so much worse, then probably the new syntax is actually significantly better. (Razvan did the same in the feedback thread, I don't get why people are doing this. Would this really fly, e.g., in Phobos?)
It's not super common, but it does show up. Some examples: https://github.com/dlang/phobos/blob/v2.098.1/std/algorithm/setops.d#L901 https://github.com/dlang/phobos/blob/v2.098.1/std/algorithm/ite ation.d#L2051-L2052 https://github.com/dlang/phobos/blob/v2.098.1/std/encoding.d#L487-L549 https://github.com/dlang/phobos/blob/v2.098.1/std/datetime/s stime.d#L9564-L9574 https://github.com/dlang/phobos/blob/v2.098.1/std/math/expon ntial.d#L2748-L2755 https://github.com/dlang/phobos/blob/v2.098.1/std/experimental/allocator/building_blocks/stats_c llector.d#L199-L200
Thanks! I guess one way to interpret this is that there should be shortened method syntax to replace those. ;)
Feb 08 2022
prev sibling next sibling parent reply Basile B. <b2.temp gmx.com> writes:
On Friday, 4 February 2022 at 17:18:54 UTC, Tejas wrote:
 So maybe the fact that `this(string y) => this(0, y);` doesn't 
 compile is a compiler bug? Constructors return `void` after 
 all, no?
No, aggregate ctors are not `void` but the return is generated [by the compiler](https://github.com/dlang/dmd/blob/51882e40fd17ed4b57a8ce3a355ea76b55d777c9/src/dmd/semantic3.d#L771-L780).
Feb 04 2022
parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 04.02.22 19:03, Basile B. wrote:
 On Friday, 4 February 2022 at 17:18:54 UTC, Tejas wrote:
 So maybe the fact that `this(string y) => this(0, y);` doesn't compile 
 is a compiler bug? Constructors return `void` after all, no?
No, aggregate ctors are not `void` but the return is generated [by the compiler](https://github.com/dlang/dmd/blob/51882e40fd17ed4b57a8ce3a355ea76b55d777c9/src/dmd/sem ntic3.d#L771-L780).
That's an implementation/ABI detail. Plain "return" is allowed, just as if the constructor returned `void`. https://github.com/dlang/dmd/blob/51882e40fd17ed4b57a8ce3a355ea76b55d777c9/src/dmd/statementsem.d#L2849-L2852 Therefore, it makes sense to do this rewrite in constructors too: https://github.com/dlang/dmd/blob/51882e40fd17ed4b57a8ce3a355ea76b55d777c9/src/dmd/statementsem.d#L2896-L2910
Feb 04 2022
parent Basile B. <b2.temp gmx.com> writes:
On Friday, 4 February 2022 at 18:21:44 UTC, Timon Gehr wrote:
 On 04.02.22 19:03, Basile B. wrote:
 On Friday, 4 February 2022 at 17:18:54 UTC, Tejas wrote:
 So maybe the fact that `this(string y) => this(0, y);` 
 doesn't compile is a compiler bug? Constructors return `void` 
 after all, no?
No, aggregate ctors are not `void` but the return is generated [by the compiler](https://github.com/dlang/dmd/blob/51882e40fd17ed4b57a8ce3a355ea76b55d777c9/src/dmd/semantic3.d#L771-L780).
That's an implementation/ABI detail. Plain "return" is allowed, just as if the constructor returned `void`. https://github.com/dlang/dmd/blob/51882e40fd17ed4b57a8ce3a355ea76b55d777c9/src/dmd/statementsem.d#L2849-L2852 Therefore, it makes sense to do this rewrite in constructors too: https://github.com/dlang/dmd/blob/51882e40fd17ed4b57a8ce3a355ea76b55d777c9/src/dmd/statementsem.d#L2896-L2910
sure, but my point was to say that Tejas assumption about void returns was wrong. Anyway, it is not reported in the feedback thread for now. The document should mention something about ctor calls since the compiler does special things that prevent shorthand syntax to work.
Feb 05 2022
prev sibling parent Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Friday, 4 February 2022 at 17:18:54 UTC, Tejas wrote:
 Actually, the following compiles:
 ```d
 void funcc()
 {
 }

 void func()
 {
     return funcc();
 }
 void main()
 {
     func();

 }
 ```
That syntax sucks. void isn't constructible. It only makes sense if you also allow ```return void();```
Feb 04 2022
prev sibling parent max haughton <maxhaton gmail.com> writes:
On Friday, 4 February 2022 at 14:46:39 UTC, Paul Backus wrote:
 On Friday, 4 February 2022 at 12:40:32 UTC, max haughton wrote:
 On Friday, 4 February 2022 at 11:21:48 UTC, Elronnd wrote:
 [...]
The implementation as done by Adam is done in the parser but if I move it down the stack a bit this is probably doable.
Please don't. Having `=> expr` be simple syntax sugar for `{ return expr; }` is consistent and easy to understand. We don't need to add special cases just to save a *single character*: this(string y) => this(0, y); this(string y) { this(0, y); }
I am going to move it down the stack for implementation reasons (syntax reproduction and error messages) anyway but point taken.
Feb 04 2022
prev sibling next sibling parent reply Rumbu <rumbu rumbu.ro> writes:
Why ```AssignExpression``` and not ```Expression```?


```Expression``` will allow shortened syntax also for 
constructors, destructors and void functions.
Feb 04 2022
parent max haughton <maxhaton gmail.com> writes:
On Friday, 4 February 2022 at 12:48:20 UTC, Rumbu wrote:
 Why ```AssignExpression``` and not ```Expression```?


 ```Expression``` will allow shortened syntax also for 
 constructors, destructors and void functions.
That's what the current implementation does. Also unless you mean allowing comma expressions, AssignExpression is the highest level in the grammar available.
Feb 04 2022
prev sibling next sibling parent reply bauss <jj_1337 live.dk> writes:
On Friday, 4 February 2022 at 10:53:45 UTC, Mike Parker wrote:


 This is the discussion thread for the first round of Community
 Review of DIP 1043, "Shortened Method Syntax":

 https://github.com/dlang/DIPs/blob/5a3b437f2b6be8fb23e855fc0da20f19f68edac8/DIPs/DIP1043.md

 The review period will **end at 11:59 PM ET on February 18**, or
 when I make a post declaring it complete. Discussion in this
 thread may continue beyond that point.

 Here in the discussion thread, you are free to discuss anything
 and everything related to the DIP. Express your support or
 opposition, debate alternatives, argue the merits, etc.

 However, if you have any specific feedback on how to improve the
 proposal itself, then please post it in the Feedback Thread. The
 Feedback Thread will be the source for the review summary that I
 will write at the end of this review round. I will post a link 
 to
 that thread immediately following this post. Just be sure to 
 read
 and understand the Reviewer Guidelines before posting there:

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

 And my blog post on the difference between the Discussion and
 Feedback threads:

 https://dlang.org/blog/2020/01/26/dip-reviews-discussion-vs-feedback/

 Please stay on topic here. I will delete posts that are 
 completely off-topic.
From the DIP itself it wasn't clear to me whether it would only support expressions that returns a value or not, because to me it should also support expressions that don't necessarily yield a value. So both these would be valid: ```d void foo() { ... } void bar() => foo(); // This private int _value; void baz(int value) => _value = value; // And this int baz() => _value; ``` If it's supported then I'm all for this, but if not then I think it's only a half-baked implementation.
Feb 04 2022
next sibling parent Steven Schveighoffer <schveiguy gmail.com> writes:
On 2/4/22 7:17 PM, bauss wrote:
 On Friday, 4 February 2022 at 10:53:45 UTC, Mike Parker wrote:


 This is the discussion thread for the first round of Community
 Review of DIP 1043, "Shortened Method Syntax":

 https://github.com/dlang/DIPs/blob/5a3b437f2b6be8fb23e855fc0da20f19f68e
ac8/DIPs/DIP1043.md 


 The review period will **end at 11:59 PM ET on February 18**, or
 when I make a post declaring it complete. Discussion in this
 thread may continue beyond that point.

 Here in the discussion thread, you are free to discuss anything
 and everything related to the DIP. Express your support or
 opposition, debate alternatives, argue the merits, etc.

 However, if you have any specific feedback on how to improve the
 proposal itself, then please post it in the Feedback Thread. The
 Feedback Thread will be the source for the review summary that I
 will write at the end of this review round. I will post a link to
 that thread immediately following this post. Just be sure to read
 and understand the Reviewer Guidelines before posting there:

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

 And my blog post on the difference between the Discussion and
 Feedback threads:

 https://dlang.org/blog/2020/01/26/dip-reviews-discussion-vs-feedback/

 Please stay on topic here. I will delete posts that are completely 
 off-topic.
From the DIP itself it wasn't clear to me whether it would only support expressions that returns a value or not, because to me it should also support expressions that don't necessarily yield a value. So both these would be valid: ```d void foo() { ... } void bar() => foo(); // This private int _value; void baz(int value) => _value = value; // And this int baz() => _value; ``` If it's supported then I'm all for this, but if not then I think it's only a half-baked implementation.
there's a preview switch. Looks like the second case is not supported in the current implementation. onlineapp.d(5): Error: cannot return non-void from `void` function But... a one-line void function doesn't need a return statement, so using a shortened method doesn't give much benefit. -Steve
Feb 04 2022
prev sibling next sibling parent Basile B. <b2.temp gmx.com> writes:
On Saturday, 5 February 2022 at 00:17:23 UTC, bauss wrote:
 So both these would be valid:

 ```d
 void foo() { ... }
 void bar() => foo(); // This

 private int _value;
 void baz(int value) => _value = value; // And this
 int baz() => _value;
 ```
Second case works with a void cast: ```d void baz(int value) => cast(void) (_value = value); ```
Feb 04 2022
prev sibling parent reply Doigt <labog outlook.com> writes:
On Saturday, 5 February 2022 at 00:17:23 UTC, bauss wrote:
 On Friday, 4 February 2022 at 10:53:45 UTC, Mike Parker wrote:


 This is the discussion thread for the first round of Community
 Review of DIP 1043, "Shortened Method Syntax":

 https://github.com/dlang/DIPs/blob/5a3b437f2b6be8fb23e855fc0da20f19f68edac8/DIPs/DIP1043.md

 The review period will **end at 11:59 PM ET on February 18**, 
 or
 when I make a post declaring it complete. Discussion in this
 thread may continue beyond that point.

 Here in the discussion thread, you are free to discuss anything
 and everything related to the DIP. Express your support or
 opposition, debate alternatives, argue the merits, etc.

 However, if you have any specific feedback on how to improve 
 the
 proposal itself, then please post it in the Feedback Thread. 
 The
 Feedback Thread will be the source for the review summary that 
 I
 will write at the end of this review round. I will post a link 
 to
 that thread immediately following this post. Just be sure to 
 read
 and understand the Reviewer Guidelines before posting there:

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

 And my blog post on the difference between the Discussion and
 Feedback threads:

 https://dlang.org/blog/2020/01/26/dip-reviews-discussion-vs-feedback/

 Please stay on topic here. I will delete posts that are 
 completely off-topic.
From the DIP itself it wasn't clear to me whether it would only support expressions that returns a value or not, because to me it should also support expressions that don't necessarily yield a value. So both these would be valid: ```d void foo() { ... } void bar() => foo(); // This private int _value; void baz(int value) => _value = value; // And this int baz() => _value; ``` If it's supported then I'm all for this, but if not then I think it's only a half-baked implementation.
is allowed, it seems weird to me that it doesn't always work no matter what kind of method you're using it on. If anything it introduces an inconsistency in the syntax and makes it very inconvenient because it also introduces style inconsistency where if your code uses single line functions side by side and some use the arrow notation and others don't because it's not possible by an arbitrary opinion that it shouldn't be possible. To me such thinking seems rooted in the past.
Feb 05 2022
parent reply Paul Backus <snarwin gmail.com> writes:
On Saturday, 5 February 2022 at 14:13:50 UTC, Doigt wrote:
 On Saturday, 5 February 2022 at 00:17:23 UTC, bauss wrote:
 ```d
 void foo() { ... }
 void bar() => foo(); // This

 private int _value;
 void baz(int value) => _value = value; // And this
 int baz() => _value;
 ```

 If it's supported then I'm all for this, but if not then I 
 think it's only a half-baked implementation.
void is allowed, it seems weird to me that it doesn't always work no matter what kind of method you're using it on. If anything it introduces an inconsistency in the syntax and makes it very inconvenient because it also introduces style inconsistency where if your code uses single line functions side by side and some use the arrow notation and others don't because it's not possible by an arbitrary opinion that it shouldn't be possible. To me such thinking seems rooted in the past.
`=> expression` is shorthand for `{ return expression; }`, and the type of the expression `_value = value` is `int`, not `void`, so you get a type mismatch. Seems pretty straightforward to me. If anything, adding a special case for `void` functions would make it less consistent and more arbitrary. Maybe there's an argument to be made that the compiler should allow this kind of `return` statement in `void` functions *in general*, regardless of whether you use the short or long syntax. But that's a totally separate issue from this DIP's proposal.
Feb 05 2022
parent reply Doigt <labog outlook.com> writes:
On Saturday, 5 February 2022 at 14:22:07 UTC, Paul Backus wrote:
 On Saturday, 5 February 2022 at 14:13:50 UTC, Doigt wrote:
 On Saturday, 5 February 2022 at 00:17:23 UTC, bauss wrote:
 ```d
 void foo() { ... }
 void bar() => foo(); // This

 private int _value;
 void baz(int value) => _value = value; // And this
 int baz() => _value;
 ```

 If it's supported then I'm all for this, but if not then I 
 think it's only a half-baked implementation.
void is allowed, it seems weird to me that it doesn't always work no matter what kind of method you're using it on. If anything it introduces an inconsistency in the syntax and makes it very inconvenient because it also introduces style inconsistency where if your code uses single line functions side by side and some use the arrow notation and others don't because it's not possible by an arbitrary opinion that it shouldn't be possible. To me such thinking seems rooted in the past.
`=> expression` is shorthand for `{ return expression; }`, and the type of the expression `_value = value` is `int`, not `void`, so you get a type mismatch. Seems pretty straightforward to me. If anything, adding a special case for `void` functions would make it less consistent and more arbitrary. Maybe there's an argument to be made that the compiler should allow this kind of `return` statement in `void` functions *in general*, regardless of whether you use the short or long syntax. But that's a totally separate issue from this DIP's proposal.
Except commonly, and to take two popular examples: JavaScript and return expression but just an expression. I don't think I'll use this new feature if I can't make my code base consistent in style. It makes no sense to me to have things like int myFunc (int a) => something; void myProc (int a) { something; } it looks bad and it makes it seems like void is a special case that is not immediately obvious why the arrow notation is not used.
Feb 05 2022
next sibling parent bauss <jj_1337 live.dk> writes:
On Saturday, 5 February 2022 at 16:19:42 UTC, Doigt wrote:
 On Saturday, 5 February 2022 at 14:22:07 UTC, Paul Backus wrote:
 On Saturday, 5 February 2022 at 14:13:50 UTC, Doigt wrote:
 On Saturday, 5 February 2022 at 00:17:23 UTC, bauss wrote:
 ```d
 void foo() { ... }
 void bar() => foo(); // This

 private int _value;
 void baz(int value) => _value = value; // And this
 int baz() => _value;
 ```

 If it's supported then I'm all for this, but if not then I 
 think it's only a half-baked implementation.
void is allowed, it seems weird to me that it doesn't always work no matter what kind of method you're using it on. If anything it introduces an inconsistency in the syntax and makes it very inconvenient because it also introduces style inconsistency where if your code uses single line functions side by side and some use the arrow notation and others don't because it's not possible by an arbitrary opinion that it shouldn't be possible. To me such thinking seems rooted in the past.
`=> expression` is shorthand for `{ return expression; }`, and the type of the expression `_value = value` is `int`, not `void`, so you get a type mismatch. Seems pretty straightforward to me. If anything, adding a special case for `void` functions would make it less consistent and more arbitrary. Maybe there's an argument to be made that the compiler should allow this kind of `return` statement in `void` functions *in general*, regardless of whether you use the short or long syntax. But that's a totally separate issue from this DIP's proposal.
Except commonly, and to take two popular examples: JavaScript for a return expression but just an expression. I don't think I'll use this new feature if I can't make my code base consistent in style. It makes no sense to me to have things like int myFunc (int a) => something; void myProc (int a) { something; } it looks bad and it makes it seems like void is a special case that is not immediately obvious why the arrow notation is not used.
Yep, exactly. You'll end up with two different writing styles everywhere, which makes everything look inconsistent.
Feb 06 2022
prev sibling next sibling parent reply Max Samukha <maxsamukha gmail.com> writes:
On Saturday, 5 February 2022 at 16:19:42 UTC, Doigt wrote:

 Except commonly, and to take two popular examples: JavaScript 

 for a return expression but just an expression.
https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/lambda-expressions#expression-lambdas: "An expression lambda *returns* the result of the expression..."
 I don't think I'll use this new feature if I can't make my code 
 base consistent in style. It makes no sense to me to have 
 things like
 int myFunc (int a) => something;
 void myProc (int a) { something; }
The former is equivalent to int myFunc (int a) { return something; }. The latter - void myProc (int a) { something; return; }.
 it looks bad and it makes it seems like void is a special case 
 that is not immediately obvious why the arrow notation is not 
 used.
Feb 08 2022
parent reply Doigt <labog outlook.com> writes:
On Tuesday, 8 February 2022 at 09:31:04 UTC, Max Samukha wrote:
 On Saturday, 5 February 2022 at 16:19:42 UTC, Doigt wrote:

 Except commonly, and to take two popular examples: JavaScript 

 for a return expression but just an expression.
https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/lambda-expressions#expression-lambdas: "An expression lambda *returns* the result of the expression..."
 I don't think I'll use this new feature if I can't make my 
 code base consistent in style. It makes no sense to me to have 
 things like
 int myFunc (int a) => something;
 void myProc (int a) { something; }
The former is equivalent to int myFunc (int a) { return something; }. The latter - void myProc (int a) { something; return; }.
 it looks bad and it makes it seems like void is a special case 
 that is not immediately obvious why the arrow notation is not 
 used.
You cannot use MSDN as a source to counteract my argument because I mentioned "commonly" in reference to popular usage. You'd need a statistic to address that argument. But even ignoring that, if you take a few moments to lower your eyes, you'll see exactly that they also have a case for lambda expressions with no return values. This is actually fatal to you because you could've argued semantics and moved the goal post smoothly without me noticing. But semantics aside, it is clear to me and any one who is intellectually honest that what Microsoft refers to "statement expression" is the simple no return expression I was talking about earlier. Also you never addressed the JS side of my argument. You'll notice that documentation you linked has several types of arrow notations which links back to my point about them that there is not just one use for them.
Feb 08 2022
parent reply Adam D Ruppe <destructionator gmail.com> writes:
On Tuesday, 8 February 2022 at 17:03:25 UTC, Doigt wrote:
 you'll see exactly that they also have a case for lambda 
 expressions with no return values
Which example is that? Do they assign it to a value of a different type?
 Also you never addressed the JS side of my argument.
D allows a no-return lambda, but it doesn't allow you to assign it to a variable of a different type. Javascript doesn't do static type checking at all, so obviously it would be different.
Feb 08 2022
parent reply bauss <jj_1337 live.dk> writes:
On Tuesday, 8 February 2022 at 17:11:19 UTC, Adam D Ruppe wrote:
 On Tuesday, 8 February 2022 at 17:03:25 UTC, Doigt wrote:
 you'll see exactly that they also have a case for lambda 
 expressions with no return values
Which example is that? Do they assign it to a value of a different type?
```d int Value { get => _value; set => _value = value; // This is okay } ``` But it won't work in D according to this DIP: ```d int value() => _value; void value(int newValue) => _value = newValue; // This will not work ``` So instead everything becomes inconsistent like: ```d int value() => _value; void value(int newValue) { _value = newValue; } // This is ok obv. ``` However, now the code looks inconsistent and not intuitive at all.
Feb 08 2022
parent reply Max Samukha <maxsamukha gmail.com> writes:
On Wednesday, 9 February 2022 at 07:54:20 UTC, bauss wrote:
 On Tuesday, 8 February 2022 at 17:11:19 UTC, Adam D Ruppe wrote:
 On Tuesday, 8 February 2022 at 17:03:25 UTC, Doigt wrote:
 you'll see exactly that they also have a case for lambda 
 expressions with no return values
Which example is that? Do they assign it to a value of a different type?
```d int Value { get => _value; set => _value = value; // This is okay } ``` But it won't work in D according to this DIP: ```d int value() => _value; void value(int newValue) => _value = newValue; // This will not work ```
return value, the actual return type of the assignment is still int. Consider: var y = x.Value = 42; which the compiler rewrites to something like: x.set_Value(42); var y = x.get_Value(); In D, you just return the new value from the setter: int value(int newValue) => _value = newValue;
 So instead everything becomes inconsistent like:

 ```d
 int value() => _value;
 void value(int newValue) { _value = newValue; } // This is ok 
 obv.
 ```

 However, now the code looks inconsistent and not intuitive at 
 all.
I disagree. The proposed feature makes D overall more consistent.
Feb 09 2022
parent reply bauss <jj_1337 live.dk> writes:
On Wednesday, 9 February 2022 at 10:34:57 UTC, Max Samukha wrote:
 I disagree. The proposed feature makes D overall more 
 consistent.
Yes it does, but not if both cases aren't supported. And you shouldn't return the value from a setter, it should be void. Which looks better? ``` int value() => _value; void value(int newValue) => _value = newValue; ``` Or ``` int value() => _value; void value(int newValue) { _value = newValue; } ``` The first case definitely looks better IMHO. And yeah as you said void could just be int, but it shouldn't. The setter should be void. It is almost universally accepted that setters should __never__ return anything and there's only one case where you might return from a setter and that is in fluid programming where you return the parent object to allow chaining. So it's irrelevant that it works as a work-around.
Feb 09 2022
parent reply Max Samukha <maxsamukha gmail.com> writes:
On Wednesday, 9 February 2022 at 11:02:03 UTC, bauss wrote:

 Yes it does, but not if both cases aren't supported.

 And you shouldn't return the value from a setter, it should be 
 void.

 Which looks better?

 ```
 int value() => _value;
 void value(int newValue) => _value = newValue;
Sorry, it doesn't look better to me. It looks as if the second function has an incorrect return type. It would look better if it was marked as a property setter and D handled property setters specially.
 ```

 Or

 ```
 int value() => _value;
 void value(int newValue) { _value = newValue; }
 ```

 The first case definitely looks better IMHO.

 And yeah as you said void could just be int, but it shouldn't. 
 The setter should be void.

 It is almost universally accepted that setters should __never__ 
 return anything and there's only one case where you might 
 return from a setter and that is in fluid programming where you 
 return the parent object to allow chaining.
 So it's irrelevant that it works as a work-around.
Are we discussing this proposal, which is about unifying named and anonymous function syntax? Changing the way D handles property setters is a separate issue.
Feb 09 2022
parent reply bauss <jj_1337 live.dk> writes:
On Wednesday, 9 February 2022 at 12:14:22 UTC, Max Samukha wrote:
 It would look better if it was marked as a property setter and 
 D handled property setters specially.
That's what it is. It's a property but property is useless in D and you shouldn't use it, so maybe if property actually worked in D then yeah I would agree. But since property doesn't really work and is somewhat obsolete then it should absolutely be supported to do the above regardless of whether it's a property or not. And it also only looks wrong to you because you think of "N => N" being an expression only, BUT in this case it's not supposed to be an expression. It's supposed to be a shortened method syntax. So arguably any function statement should be valid after the "=>" and it indeed should be an "edge-case" for the "=>" operator. void a() => b(); is valid in __all__ other languages that support it and thus it should be valid in D too, otherwise D again only gets a feature half-assed and falls behind everyone else. Can we just for once in D not rely on being "hacky"?
Feb 09 2022
next sibling parent Max Samukha <maxsamukha gmail.com> writes:
On Wednesday, 9 February 2022 at 12:38:56 UTC, bauss wrote:

 And it also only looks wrong to you because you think of "N => 
 N" being an expression only, BUT in this case it's not supposed 
 to be an expression. It's supposed to be a shortened method 
 syntax. So arguably any function statement should be valid 
 after the "=>" and it indeed should be an "edge-case" for the 
 "=>" operator.
Actually, if any type implicitly converted to the unit type, it would probably look pretty good to me. Not going to ever happen in D, though.
Feb 09 2022
prev sibling parent reply Adam D Ruppe <destructionator gmail.com> writes:
On Wednesday, 9 February 2022 at 12:38:56 UTC, bauss wrote:
 void a() => b(); is valid in __all__ other languages that
You can do that in D too, as long as b also returns void. BTW it'd actually be a fairly simple change to the dip to allow these things. Instead of `x => y` translated to `x { return y; }` it could be translated to `x { return cast(typeof(return))( y ); }` But casts are kinda harmful so i don't think that's a good idea in general. Of course it could special case it and say it does: `x { static if(is(typeof(return) == void)) return cast(void) (y); else return y; }` but idk.
Feb 09 2022
next sibling parent Adam D Ruppe <destructionator gmail.com> writes:
On Wednesday, 9 February 2022 at 13:05:35 UTC, Adam D Ruppe wrote:
 it could be translated to `x { return cast(typeof(return))( y 
 ); }`
actually wait i think this breaks return type inference so that impl would suck after all. the thing that actually kicked off this implementation was writing to write: property foo() => this._foo; which is an inferred return type so breaking that would be no good!
Feb 09 2022
prev sibling parent bauss <jj_1337 live.dk> writes:
On Wednesday, 9 February 2022 at 13:05:35 UTC, Adam D Ruppe wrote:
 On Wednesday, 9 February 2022 at 12:38:56 UTC, bauss wrote:
 void a() => b(); is valid in __all__ other languages that
Yes but the example would be b() is replaced by x = someparameter and then it fails.
Feb 09 2022
prev sibling parent Kagamin <spam here.lot> writes:
On Saturday, 5 February 2022 at 16:19:42 UTC, Doigt wrote:
 Except commonly, and to take two popular examples: JavaScript 

 for a return expression but just an expression. I don't think 
 I'll use this new feature if I can't make my code base 
 consistent in style. It makes no sense to me to have things like
 int myFunc (int a) => something;
 void myProc (int a) { something; }
 it looks bad and it makes it seems like void is a special case 
 that is not immediately obvious why the arrow notation is not 
 used.
You can't opt out from the full function syntax: most functions can't be shortened, so you end up using both syntaxes.
Feb 09 2022
prev sibling next sibling parent reply forkit <forkit gmail.com> writes:
On Friday, 4 February 2022 at 10:53:45 UTC, Mike Parker wrote:

I am neither for or against it really.

It is clear that the D programming language is really more 'a 
collection of dialects', including those whose only real value, 
is that they save you a few keystrokes.

That's the upside of the proposal I assume?

The downside, is the additional cognitive load.
Feb 05 2022
next sibling parent Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Saturday, 5 February 2022 at 08:12:32 UTC, forkit wrote:
 The downside, is the additional cognitive load.
Most likely a negative change, makes it easier to write code that looks messy.
Feb 05 2022
prev sibling parent reply Paul Backus <snarwin gmail.com> writes:
On Saturday, 5 February 2022 at 08:12:32 UTC, forkit wrote:
 It is clear that the D programming language is really more 'a 
 collection of dialects', including those whose only real value, 
 is that they save you a few keystrokes.

 That's the upside of the proposal I assume?

 The downside, is the additional cognitive load.
D already supports this shortened syntax for anonymous functions: (int x) { return x + 1; } (int x) => x + 1 So, allowing it for named functions too is a logical extension of a language feature that already exists.
Feb 05 2022
next sibling parent rikki cattermole <rikki cattermole.co.nz> writes:
On 06/02/2022 3:10 AM, Paul Backus wrote:
 So, allowing it for named functions too is a logical extension of a 
 language feature that already exists.
Yes. A lot of the point of this DIP is to make D more consistent. For stuff like this you should be able to guess that a feature exists and the language is like yup! It totally does the thing you think it does. In a lot of ways this simplifies D, as it no longer has a special case where this is syntax is possible.
Feb 05 2022
prev sibling parent reply Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Saturday, 5 February 2022 at 14:10:51 UTC, Paul Backus wrote:
 D already supports this shortened syntax for anonymous 
 functions:

     (int x) { return x + 1; }
     (int x) => x + 1

 So, allowing it for named functions too is a logical extension 
 of a language feature that already exists.
Hardly, I would read arrow as a math-like lambda by convention.
Feb 05 2022
parent reply forkit <forkit gmail.com> writes:
On Saturday, 5 February 2022 at 20:15:33 UTC, Ola Fosheim Grøstad 
wrote:
 On Saturday, 5 February 2022 at 14:10:51 UTC, Paul Backus wrote:
 D already supports this shortened syntax for anonymous 
 functions:

     (int x) { return x + 1; }
     (int x) => x + 1

 So, allowing it for named functions too is a logical extension 
 of a language feature that already exists.
Hardly, I would read arrow as a math-like lambda by convention.
The proposal seems straight forward to me: auto multiplyBy10 = (int a) => a * 10; // already exists. auto multiplyBy10(int x) => x * 10; // proposed: Shortened Method Syntax Nothing to see here. Just do it.
Feb 05 2022
parent reply Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Saturday, 5 February 2022 at 20:47:02 UTC, forkit wrote:
 auto multiplyBy10 = (int a) => a * 10; // already exists.
 auto multiplyBy10(int x) => x * 10; // proposed: Shortened 
 Method Syntax
I don't really care either way. It is in general a bad idea to have to syntaxes for the same thing. It is certainly not logical though. Lambdas conceptualize mathematical expressions. Methods conceptualize messages. Two different modelling ideas.
Feb 05 2022
next sibling parent Guillaume Piolat <first.last gmail.com> writes:
On Saturday, 5 February 2022 at 21:17:23 UTC, Ola Fosheim Grøstad 
wrote:
 I don't really care either way.
Same.
Feb 05 2022
prev sibling parent forkit <forkit gmail.com> writes:
On Saturday, 5 February 2022 at 21:17:23 UTC, Ola Fosheim Grøstad 
wrote:
 On Saturday, 5 February 2022 at 20:47:02 UTC, forkit wrote:
 auto multiplyBy10 = (int a) => a * 10; // already exists.
 auto multiplyBy10(int x) => x * 10; // proposed: Shortened 
 Method Syntax
I don't really care either way. It is in general a bad idea to have to syntaxes for the same thing. It is certainly not logical though. Lambdas conceptualize mathematical expressions. Methods conceptualize messages. Two different modelling ideas.
I agree. The real issue, is how developers decide the case for when to use, and when not to use one style of the other. Irregular mixing of the two dialects would not constitute good coding style in my opinion. My primary concern about integrating mathmatical expressions like these into a programming language, has always been the extent to which one can understand them without training. This continual evolution towards making programming languages appear more like Frisian, is in nobodys interest.. unless you already speak Frisian.
Feb 05 2022
prev sibling next sibling parent reply IGotD- <nise nise.com> writes:
On Friday, 4 February 2022 at 10:53:45 UTC, Mike Parker wrote:


 This is the discussion thread for the first round of Community
 Review of DIP 1043, "Shortened Method Syntax":

 https://github.com/dlang/DIPs/blob/5a3b437f2b6be8fb23e855fc0da20f19f68edac8/DIPs/DIP1043.md
Just to ensure, the new simplified method syntax is only for single assignment methods, right? I haven't detail studied the AssigmentStatement grammar but is there any possibility that the new syntax can be abused? For example starting new entire statement blocks and that way creating a new ugly way of writing methods. The reason not allowing the lamda syntax was to have a single way of writing methods. If we allow the new syntax, the we need restrictions for that one as well so that it doesn't become a Frankenstein.
Feb 05 2022
parent Tejas <notrealemail gmail.com> writes:
On Saturday, 5 February 2022 at 22:42:35 UTC, IGotD- wrote:
 On Friday, 4 February 2022 at 10:53:45 UTC, Mike Parker wrote:


 This is the discussion thread for the first round of Community
 Review of DIP 1043, "Shortened Method Syntax":

 https://github.com/dlang/DIPs/blob/5a3b437f2b6be8fb23e855fc0da20f19f68edac8/DIPs/DIP1043.md
Just to ensure, the new simplified method syntax is only for single assignment methods, right? I haven't detail studied the AssigmentStatement grammar but is there any possibility that the new syntax can be abused? For example starting new entire statement blocks and that way creating a new ugly way of writing methods. The reason not allowing the lamda syntax was to have a single way of writing methods. If we allow the new syntax, the we need restrictions for that one as well so that it doesn't become a Frankenstein.
I guess you can abuse it like ```d auto func(int a, int b) => (a,b) { int c,d; return a+b+c+d; }(a, b); ``` Basically you can write a regular function body if you enclose it inside a lamba and call it immediately.
Feb 05 2022
prev sibling parent reply Kagamin <spam here.lot> writes:

searched our codebase and couldn't find many shortened methods, 
autoproperties are used much more often. Methods simply tend to 
be at leas a couple of lines long and can't be shortened easily.

Some examples:
```
private bool isCanceled() => _state == RequestState.canceled;
private bool isCanceled() { return _state == 
RequestState.canceled; }
```
61 and 69 characters respectively, 12% saving.

A single valued method:
```
IClient create(string address)
{
	return new Client(
		new DefaultProducerEndpoint(address, _producerFactory.create(), 
0),
		new DefaultConsumerEndpoint(address, _consumerFactory.create()),
		new DefaultBrokerEndpoint(address, _brokerFactory.create()),
		null);
}
```
Ermm... should it be shortened?
Feb 09 2022
parent reply Kagamin <spam here.lot> writes:
Another single valued method:
```
static string getPipeName(int pid)
{
	return string.Format("{0}-{1}", _baseName, pid);
}
static string getPipeName(int pid) => string.Format("{0}-{1}", 
_baseName, pid);
```
88 and 79 characters, 10% saving.
Feb 09 2022
parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 09.02.22 14:46, Kagamin wrote:
 Another single valued method:
 ```
 static string getPipeName(int pid)
 {
      return string.Format("{0}-{1}", _baseName, pid);
 }
 static string getPipeName(int pid) => string.Format("{0}-{1}", 
 _baseName, pid);
 ```
 88 and 79 characters, 10% saving.
I don't think this is primarily about saving characters.
Feb 09 2022
parent bauss <jj_1337 live.dk> writes:
On Wednesday, 9 February 2022 at 14:10:57 UTC, Timon Gehr wrote:
 On 09.02.22 14:46, Kagamin wrote:
 Another single valued method:
 ```
 static string getPipeName(int pid)
 {
      return string.Format("{0}-{1}", _baseName, pid);
 }
 static string getPipeName(int pid) => string.Format("{0}-{1}", 
 _baseName, pid);
 ```
 88 and 79 characters, 10% saving.
I don't think this is primarily about saving characters.
Yep, that's definitely not the primary goal. It's to reduce verbosity instead.
Feb 09 2022