www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - proposal: short => rewrite for function declarations

reply Adam D. Ruppe <destructionator gmail.com> writes:
After a brief chat yesterday, I slapped this together:

https://github.com/dlang/dmd/pull/11833

In short, in a function declaration, it rewrites `=> ...;` into 
`{ return ...; }`

One benefit is shorter property accessors:

     private int _x = 34;
      property x() => _x;
      property x(int v) => _x = v;

But it also works basically anywhere

     bool isNull() => this is null;
     auto identity(T)(T a) => a;
      property y() in(true) => _x; // contracts still work too

So it just extends the existing lambda shorthand to full 
declarations too.

See more in the PR description and the test case there.
Oct 09 2020
next sibling parent reply 12345swordy <alexanderheistermann gmail.com> writes:
On Friday, 9 October 2020 at 14:44:25 UTC, Adam D. Ruppe wrote:
 After a brief chat yesterday, I slapped this together:

 https://github.com/dlang/dmd/pull/11833

 In short, in a function declaration, it rewrites `=> ...;` into 
 `{ return ...; }`

 One benefit is shorter property accessors:

     private int _x = 34;
      property x() => _x;
      property x(int v) => _x = v;

 But it also works basically anywhere

     bool isNull() => this is null;
     auto identity(T)(T a) => a;
      property y() in(true) => _x; // contracts still work too

 So it just extends the existing lambda shorthand to full 
 declarations too.

 See more in the PR description and the test case there.
This needs a dip and a preview switch. I was working on a dip that makes property useful in the discord chat, and then you go off and implement one of the syntax that we had talk about. Alex
Oct 09 2020
parent Adam D. Ruppe <destructionator gmail.com> writes:
On Friday, 9 October 2020 at 14:46:28 UTC, 12345swordy wrote:
 I was working on a dip that makes  property
This works with property of course, but it is not specific to it in any way. It might even help your dip.
Oct 09 2020
prev sibling next sibling parent Jacob Carlborg <doob me.com> writes:
On 2020-10-09 16:44, Adam D. Ruppe wrote:
 After a brief chat yesterday, I slapped this together:
 
 https://github.com/dlang/dmd/pull/11833
 
 In short, in a function declaration, it rewrites `=> ...;` into `{ 
 return ...; }`
 
 One benefit is shorter property accessors:
 
      private int _x = 34;
       property x() => _x;
       property x(int v) => _x = v;
 
 But it also works basically anywhere
 
      bool isNull() => this is null;
      auto identity(T)(T a) => a;
       property y() in(true) => _x; // contracts still work too
 
 So it just extends the existing lambda shorthand to full declarations too.
Yes please. -- /Jacob Carlborg
Oct 09 2020
prev sibling next sibling parent reply Andre Pany <andre s-e-a-p.de> writes:
On Friday, 9 October 2020 at 14:44:25 UTC, Adam D. Ruppe wrote:
 After a brief chat yesterday, I slapped this together:

 https://github.com/dlang/dmd/pull/11833

 In short, in a function declaration, it rewrites `=> ...;` into 
 `{ return ...; }`

 One benefit is shorter property accessors:

     private int _x = 34;
      property x() => _x;
      property x(int v) => _x = v;

 But it also works basically anywhere

     bool isNull() => this is null;
     auto identity(T)(T a) => a;
      property y() in(true) => _x; // contracts still work too

 So it just extends the existing lambda shorthand to full 
 declarations too.

 See more in the PR description and the test case there.
If I remember correctly, the property setter in your example works, because the assignment _x = v returns an int. In case you do not assign the value but call a method which has return type void, it won't work? (As far as I remember). Overall I like your proposal. Kind regards Andre
Oct 09 2020
parent reply Adam D. Ruppe <destructionator gmail.com> writes:
On Friday, 9 October 2020 at 17:40:56 UTC, Andre Pany wrote:
 If I remember correctly, the property setter in your example 
 works, because the assignment _x = v returns an int.
 In case you do not assign the value but call a method which has 
 return type void, it won't work? (As far as I remember).
Well, it will actually sometimes work. Remember it just rewrites => x; into { return x; } And dmd *sometimes* lets you: void foo() {} void test() { return foo(); } It sees you are just returning void from a void function and allows it. If it is allowed there, void test() => foo(); is also allowed. But `void b() => _x = 5;` triggers "Error: cannot return non-void from void function", the same as if you wrote out `void b() { return _x = 5; }` If you don't want to return anything of course you can just write the bracket syntax: // this is allowed, but why would you when you can just write... void foo() => cast(void)(x+=5); // this instead? void foo() { x+= 5; } You only really save syntax if you are returning something anyway.
Oct 09 2020
parent Andre Pany <andre s-e-a-p.de> writes:
On Friday, 9 October 2020 at 17:50:54 UTC, Adam D. Ruppe wrote:
 On Friday, 9 October 2020 at 17:40:56 UTC, Andre Pany wrote:
 [...]
Well, it will actually sometimes work. Remember it just rewrites => x; into { return x; } And dmd *sometimes* lets you: [...]
Thanks for the explanation, makes sense. Kind regards Andre
Oct 09 2020
prev sibling next sibling parent reply James Blachly <james.blachly gmail.com> writes:
On Friday, 9 October 2020 at 14:44:25 UTC, Adam D. Ruppe wrote:
 After a brief chat yesterday, I slapped this together:

 https://github.com/dlang/dmd/pull/11833

 In short, in a function declaration, it rewrites `=> ...;` into 
 `{ return ...; }`
Very much support! (a limited form of) This is widely used in ECMAscript and called "arrow function" https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions
Oct 09 2020
parent Adam D. Ruppe <destructionator gmail.com> writes:
On Friday, 9 October 2020 at 18:09:38 UTC, James Blachly wrote:
 (a limited form of) This is widely used in ECMAscript and 
 called "arrow function"
Yeah, D already has it very similarly to that too, you can use it for function arguments and variables, just not in like class definitions, so it was a small change to the compiler to add it here.
Oct 09 2020
prev sibling next sibling parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 10/9/20 10:44 AM, Adam D. Ruppe wrote:
 After a brief chat yesterday, I slapped this together:
 
 https://github.com/dlang/dmd/pull/11833
 
 In short, in a function declaration, it rewrites `=> ...;` into `{ 
 return ...; }`
 
 One benefit is shorter property accessors:
 
      private int _x = 34;
       property x() => _x;
       property x(int v) => _x = v;
 
 But it also works basically anywhere
 
      bool isNull() => this is null;
      auto identity(T)(T a) => a;
       property y() in(true) => _x; // contracts still work too
 
 So it just extends the existing lambda shorthand to full declarations too.
 
 See more in the PR description and the test case there.
It's kind of weird. You usually name a lambda outside the definition. Like: auto x = () => _x; But having the name makes it unambiguous from an actual lambda. You aren't saving much though, I do a lot of one-liners like: property x() { return _x; } Compare to: property x() => _x; It's not *that* much savings... A lambda can also have no type for the parameter: (v) => _x + v; (T)(T v) => _x + v; // equivalent to this Which is super-useful and less verbose. But in this syntax, I'm guessing it's going to interpret v as a type? -Steve
Oct 09 2020
parent Adam D. Ruppe <destructionator gmail.com> writes:
On Friday, 9 October 2020 at 19:11:44 UTC, Steven Schveighoffer 
wrote:
 You aren't saving much though, I do a lot of one-liners like:
Yeah, but we could (and did) say the same thing about the other uses of the => syntax. It was accepted there, so this just makes it consistently allowed in more cases.
 Which is super-useful and less verbose. But in this syntax, I'm 
 guessing it's going to interpret v as a type?
Right, it will complain "undefined identifier", same as if you wrote it `whatever foo(v) { return stuff; }`. As you can see from the PR diff, there's no special cases, just a straight forward syntax shortcut to keep it simple. Of course you can still do: auto identity(T)(T a) => a; if you wanted to.
Oct 09 2020
prev sibling next sibling parent reply claptrap <clap trap.com> writes:
On Friday, 9 October 2020 at 14:44:25 UTC, Adam D. Ruppe wrote:
 After a brief chat yesterday, I slapped this together:

 https://github.com/dlang/dmd/pull/11833

 In short, in a function declaration, it rewrites `=> ...;` into 
 `{ return ...; }`

 One benefit is shorter property accessors:

     private int _x = 34;
      property x() => _x;
      property x(int v) => _x = v;

 But it also works basically anywhere

     bool isNull() => this is null;
     auto identity(T)(T a) => a;
      property y() in(true) => _x; // contracts still work too

 So it just extends the existing lambda shorthand to full 
 declarations too.

 See more in the PR description and the test case there.
From the recent discussions I got the impression that needless syntax sugar shouldn't be added any more. To get new features in it needs to be something that cant be done with existing language features, or it needs to fix something. So doesn't this just add more "stuff" for no meaningful benefit? I couldnt care less about property x() => _x; vs property x() { return -x; } cause the important thing to me is that my code is simple, readable, expressive, i dont care about saving 7 chars on a one liner.
Oct 10 2020
next sibling parent reply Andre Pany <andre s-e-a-p.de> writes:
On Saturday, 10 October 2020 at 10:18:15 UTC, claptrap wrote:
 On Friday, 9 October 2020 at 14:44:25 UTC, Adam D. Ruppe wrote:
 After a brief chat yesterday, I slapped this together:

 https://github.com/dlang/dmd/pull/11833

 In short, in a function declaration, it rewrites `=> ...;` 
 into `{ return ...; }`

 One benefit is shorter property accessors:

     private int _x = 34;
      property x() => _x;
      property x(int v) => _x = v;

 But it also works basically anywhere

     bool isNull() => this is null;
     auto identity(T)(T a) => a;
      property y() in(true) => _x; // contracts still work too

 So it just extends the existing lambda shorthand to full 
 declarations too.

 See more in the PR description and the test case there.
From the recent discussions I got the impression that needless syntax sugar shouldn't be added any more. To get new features in it needs to be something that cant be done with existing language features, or it needs to fix something. So doesn't this just add more "stuff" for no meaningful benefit? I couldnt care less about property x() => _x; vs property x() { return -x; } cause the important thing to me is that my code is simple, readable, expressive, i dont care about saving 7 chars on a one liner.
I assume, if you follow the style guide, the second example should be written with 4 lines: property x() { return -x; } While the proposal from Adam is a 1 liner also from a style guide perspective: property x() => _x; (Yes, this is nitpicking... but for me the reason why I like the proposal). Kind regards Andre
Oct 10 2020
next sibling parent claptrap <clap trap.com> writes:
On Saturday, 10 October 2020 at 10:25:05 UTC, Andre Pany wrote:
 On Saturday, 10 October 2020 at 10:18:15 UTC, claptrap wrote:
 On Friday, 9 October 2020 at 14:44:25 UTC, Adam D. Ruppe wrote:
While the proposal from Adam is a 1 liner also from a style guide perspective: property x() => _x; (Yes, this is nitpicking... but for me the reason why I like the proposal).
A better solution is to modify the style guide to allow one liners where reasonable.. And you can just ignore it till then. :)
Oct 10 2020
prev sibling parent Steven Schveighoffer <schveiguy gmail.com> writes:
On 10/10/20 6:25 AM, Andre Pany wrote:
 On Saturday, 10 October 2020 at 10:18:15 UTC, claptrap wrote:
 On Friday, 9 October 2020 at 14:44:25 UTC, Adam D. Ruppe wrote:
 After a brief chat yesterday, I slapped this together:

 https://github.com/dlang/dmd/pull/11833

 In short, in a function declaration, it rewrites `=> ...;` into `{ 
 return ...; }`

 One benefit is shorter property accessors:

     private int _x = 34;
      property x() => _x;
      property x(int v) => _x = v;

 But it also works basically anywhere

     bool isNull() => this is null;
     auto identity(T)(T a) => a;
      property y() in(true) => _x; // contracts still work too

 So it just extends the existing lambda shorthand to full declarations 
 too.

 See more in the PR description and the test case there.
From the recent discussions I got the impression that needless syntax sugar shouldn't be added any more. To get new features in it needs to be something that cant be done with existing language features, or it needs to fix something. So doesn't this just add more "stuff" for no meaningful benefit? I couldnt care less about property x() => _x; vs property x() { return -x; } cause the important thing to me is that my code is simple, readable, expressive, i dont care about saving 7 chars on a one liner.
I assume, if you follow the style guide, the second example should be written with 4 lines: property x() {     return -x; } While the proposal from Adam is a 1 liner also from a style guide perspective: property x() => _x; (Yes, this is nitpicking... but for me the reason why I like the proposal).
The D style guide is here: https://dlang.org/dstyle.html Indeed, it says you should always use separate lines for braces for all functions. But I think even Phobos/Druntime don't always follow this convention. We should change it so property functions and/or simple "return exp" functions do not need to be multiple lines. This is not a reason to accept a language change, at all. Just change the style guide. -Steve
Oct 10 2020
prev sibling next sibling parent reply Imperatorn <johan_forsberg_86 hotmail.com> writes:
On Saturday, 10 October 2020 at 10:18:15 UTC, claptrap wrote:
 On Friday, 9 October 2020 at 14:44:25 UTC, Adam D. Ruppe wrote:
 [...]
From the recent discussions I got the impression that needless syntax sugar shouldn't be added any more. To get new features in it needs to be something that cant be done with existing language features, or it needs to fix something. So doesn't this just add more "stuff" for no meaningful benefit? I couldnt care less about property x() => _x; vs property x() { return -x; } cause the important thing to me is that my code is simple, readable, expressive, i dont care about saving 7 chars on a one liner.
What do you mean. It removes stuff. I'd say Adam's proposal is more readable.
Oct 10 2020
next sibling parent reply IGotD- <nise nise.com> writes:
On Saturday, 10 October 2020 at 12:30:24 UTC, Imperatorn wrote:
 What do you mean. It removes stuff. I'd say Adam's proposal is 
 more readable.
I don't experience it as more readable. However, the biggest problem I have with it is that we just add more ways doing the same thing. I want the D should be restrictive adding more ways doing the same thing, otherwise we will get into a C++ situation. Initialization in C++, has more different ways than you can count on your fingers.
Oct 10 2020
parent Imperatorn <johan_forsberg_86 hotmail.com> writes:
On Saturday, 10 October 2020 at 12:36:15 UTC, IGotD- wrote:
 On Saturday, 10 October 2020 at 12:30:24 UTC, Imperatorn wrote:
 What do you mean. It removes stuff. I'd say Adam's proposal is 
 more readable.
I don't experience it as more readable. However, the biggest problem I have with it is that we just add more ways doing the same thing. I want the D should be restrictive adding more ways doing the same thing, otherwise we will get into a C++ situation. Initialization in C++, has more different ways than you can count on your fingers.
Sure, readability is subjective. It's shorter though. And I agree that we generally should be very restrictive with adding features. But I believe this would be achieved through a preview switch, so technically it doesn't change the default case.
Oct 10 2020
prev sibling next sibling parent reply Mike Parker <aldacron gmail.com> writes:
On Saturday, 10 October 2020 at 12:30:24 UTC, Imperatorn wrote:

  property x() => _x;

 vs

  property x() { return -x; }

 cause the important thing to me is that my code is simple, 
 readable, expressive, i dont care about saving 7 chars on a 
 one liner.
What do you mean. It removes stuff. I'd say Adam's proposal is more readable.
Not to me. Taking away the braces and the return statement turns it into a foreign language.
Oct 10 2020
next sibling parent reply Imperatorn <johan_forsberg_86 hotmail.com> writes:
On Saturday, 10 October 2020 at 13:05:48 UTC, Mike Parker wrote:
 On Saturday, 10 October 2020 at 12:30:24 UTC, Imperatorn wrote:

  property x() => _x;

 vs

  property x() { return -x; }

 cause the important thing to me is that my code is simple, 
 readable, expressive, i dont care about saving 7 chars on a 
 one liner.
What do you mean. It removes stuff. I'd say Adam's proposal is more readable.
Not to me. Taking away the braces and the return statement turns it into a foreign language.
Might be a bit of a stretch to say it becomes a "foreign language" just because you change one thing... But, I do agree that in general you should be very restrictive about adding things. A new feature always seems so nice and shiny in the beginning, before you have analysed its potential side effects.
Oct 10 2020
next sibling parent reply Patrick Schluter <Patrick.Schluter bbox.fr> writes:
On Saturday, 10 October 2020 at 13:55:13 UTC, Imperatorn wrote:
 On Saturday, 10 October 2020 at 13:05:48 UTC, Mike Parker wrote:
 On Saturday, 10 October 2020 at 12:30:24 UTC, Imperatorn wrote:

  property x() => _x;

 vs

  property x() { return -x; }

 cause the important thing to me is that my code is simple, 
 readable, expressive, i dont care about saving 7 chars on a 
 one liner.
What do you mean. It removes stuff. I'd say Adam's proposal is more readable.
Not to me. Taking away the braces and the return statement turns it into a foreign language.
Might be a bit of a stretch to say it becomes a "foreign language" just because you change one thing... But, I do agree that in general you should be very restrictive about adding things. A new feature always seems so nice and shiny in the beginning, before you have analysed its potential side effects.
It's a question of point of view. This is not adding a new feature, it's removing a restriction. The lambdas (i.e. unnamed functions) have 2 possible syntaxes. Named functions have only 1. This is inconsistent. Removing the second syntax from lambdas is not possible (unending breakage) so it is more logic to remove the syntax restriction from named functions. As shown it is a very simple change and it removes an artificial restriction. It is clear that dubious languages and syntax additions are to be avoided but this ain't any of it.
Oct 10 2020
parent =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 10/10/20 7:25 AM, Patrick Schluter wrote:

 This is not adding a new feature, it's removing a restriction. The
 lambdas (i.e. unnamed functions) have 2 possible syntaxes. Named
 functions have only 1. This is inconsistent.
That. Ali
Oct 10 2020
prev sibling parent reply Mike Parker <aldacron gmail.com> writes:
On Saturday, 10 October 2020 at 13:55:13 UTC, Imperatorn wrote:

 Might be a bit of a stretch to say it becomes a "foreign 
 language" just because you change one thing...
What I mean is that my brain is conditioned to see the braces and the return statement. I recognize everything immediately and don't have to think about it. If I'm scanning D code and I see the shorthand lambda syntax for delegates, I have to stop and think about it. So yeah, to me, it's like a foreign language.
Oct 10 2020
parent Imperatorn <johan_forsberg_86 hotmail.com> writes:
On Saturday, 10 October 2020 at 15:11:16 UTC, Mike Parker wrote:
 On Saturday, 10 October 2020 at 13:55:13 UTC, Imperatorn wrote:

 Might be a bit of a stretch to say it becomes a "foreign 
 language" just because you change one thing...
What I mean is that my brain is conditioned to see the braces and the return statement. I recognize everything immediately and don't have to think about it. If I'm scanning D code and I see the shorthand lambda syntax for delegates, I have to stop and think about it. So yeah, to me, it's like a foreign language.
Well ok, I guess "foreign" because it's not in the language atm. Sure. But not foreign as in "I don't understand". That's quite different.
Oct 10 2020
prev sibling parent Fred <fred gmail.com> writes:
On Saturday, 10 October 2020 at 13:05:48 UTC, Mike Parker wrote:
 On Saturday, 10 October 2020 at 12:30:24 UTC, Imperatorn wrote:

  property x() => _x;

 vs

  property x() { return -x; }

 cause the important thing to me is that my code is simple, 
 readable, expressive, i dont care about saving 7 chars on a 
 one liner.
What do you mean. It removes stuff. I'd say Adam's proposal is more readable.
Not to me. Taking away the braces and the return statement turns it into a foreign language.
It's literally how lambda's are defined. auto x = () => _x; // no return statement, no braces auto x = () { return _x; }; // exactly the same
Oct 10 2020
prev sibling parent claptrap <clap trap.com> writes:
On Saturday, 10 October 2020 at 12:30:24 UTC, Imperatorn wrote:
 On Saturday, 10 October 2020 at 10:18:15 UTC, claptrap wrote:
 On Friday, 9 October 2020 at 14:44:25 UTC, Adam D. Ruppe wrote:
 [...]
From the recent discussions I got the impression that needless syntax sugar shouldn't be added any more. To get new features in it needs to be something that cant be done with existing language features, or it needs to fix something. So doesn't this just add more "stuff" for no meaningful benefit? I couldnt care less about property x() => _x; vs property x() { return -x; } cause the important thing to me is that my code is simple, readable, expressive, i dont care about saving 7 chars on a one liner.
What do you mean. It removes stuff. I'd say Adam's proposal is more readable.
How quickly you can visually parse either of them is probably 99% down to what your used to. And even then the difference will be minuscule. So it's completely irrelevant imo.
Oct 10 2020
prev sibling parent reply Q. Schroll <qs.il.paperinik gmail.com> writes:
On Saturday, 10 October 2020 at 10:18:15 UTC, claptrap wrote:
 From the recent discussions I got the impression that needless 
 syntax sugar shouldn't be added any more.
together
 cause the important thing to me is that my code is simple, 
 readable, expressive
Maybe it's nothing for you, but to me, your second paragraph is exactly the refutation for the first. It's also about coherence. When lambdas are used, the syntax x => expr is used everywhere when it is admissible, proving their worth. I do write things like int foo(Type param) { return goo(param); } but only because int foo(Type param) => goo(param); is not admissible. int foo(Type param) { return goo(param); } is not D-style, but int foo(Type param) { return goo(param); } is. Have three of them and they waste significant horizontal space in the source buffer. Every layer of brackets (any kind) in a line adds confusion and hinders our commonly beloved readability. Haskell has weird stuff like the $ operator to deal with Lisp-esque amounts of brackets.
Oct 17 2020
parent claptrap <clap trap.com> writes:
On Sunday, 18 October 2020 at 03:03:32 UTC, Q. Schroll wrote:
 On Saturday, 10 October 2020 at 10:18:15 UTC, claptrap wrote:
 From the recent discussions I got the impression that needless 
 syntax sugar shouldn't be added any more.
together
 cause the important thing to me is that my code is simple, 
 readable, expressive
Maybe it's nothing for you, but to me, your second paragraph is exactly the refutation for the first. It's also about coherence. When lambdas are used, the syntax x => expr is used everywhere when it is admissible, proving their worth. I do write things like int foo(Type param) { return goo(param); } but only because int foo(Type param) => goo(param); is not admissible. int foo(Type param) { return goo(param); } is not D-style, but int foo(Type param) { return goo(param); } is. Have three of them and they waste significant horizontal space in the source buffer. Every layer of brackets (any kind) in a line adds confusion and hinders our commonly beloved readability. Haskell has weird stuff like the $ operator to deal with Lisp-esque amounts of brackets.
To me "readability" is how quickly you can look at some code and understand what it does, not only do i think there's so little difference between those 4 styles that it's irrelevant, I think thats not even code you're going to spend any time looking at. Also ahem, change the style guide to allow one liners if they are a single statement. The coherence between features is a better argument, but I'm still meh about about it.
Oct 18 2020
prev sibling next sibling parent Timon Gehr <timon.gehr gmx.ch> writes:
On 09.10.20 16:44, Adam D. Ruppe wrote:
 After a brief chat yesterday, I slapped this together:
 
 https://github.com/dlang/dmd/pull/11833
 
 In short, in a function declaration, it rewrites `=> ...;` into `{ 
 return ...; }`
 
 One benefit is shorter property accessors:
 
      private int _x = 34;
       property x() => _x;
       property x(int v) => _x = v;
 
 But it also works basically anywhere
 
      bool isNull() => this is null;
      auto identity(T)(T a) => a;
       property y() in(true) => _x; // contracts still work too
 
 So it just extends the existing lambda shorthand to full declarations too.
 
 See more in the PR description and the test case there.
https://issues.dlang.org/show_bug.cgi?id=7176 (I have wanted this many times, it's an arbitrary limitation.)
Oct 10 2020
prev sibling next sibling parent reply Sebastiaan Koppe <mail skoppe.eu> writes:
On Friday, 9 October 2020 at 14:44:25 UTC, Adam D. Ruppe wrote:
 After a brief chat yesterday, I slapped this together:

 https://github.com/dlang/dmd/pull/11833

 One benefit is shorter property accessors:

     private int _x = 34;
      property x() => _x;
      property x(int v) => _x = v;

 So it just extends the existing lambda shorthand to full 
 declarations too.
Obvious addition, don't understand much of the resistance. My experience is that a lot of languages use => similarly.
Oct 10 2020
parent reply Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Saturday, 10 October 2020 at 16:38:56 UTC, Sebastiaan Koppe 
wrote:
 Obvious addition, don't understand much of the resistance. My 
 experience is that a lot of languages use => similarly.
I assume that TypeScript and Dart allows "=> expr" as a shortcut for "{return expr;}" on method bodies. So some programmers might expect it, yes. Having many ways to express methods make code harder to read IMO, but if is in the language already then it makes sense to make it a proper shortcut and not a special case.
Oct 10 2020
parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 10/10/20 2:53 PM, Ola Fosheim Grøstad wrote:
 On Saturday, 10 October 2020 at 16:38:56 UTC, Sebastiaan Koppe wrote:
 Obvious addition, don't understand much of the resistance. My 
 experience is that a lot of languages use => similarly.
I assume that TypeScript and Dart allows "=> expr" as a shortcut for "{return expr;}" on method bodies. So some programmers might expect it, yes.
In JavaScript (TypeScript), it looks like => {return expr} and yes, just giving an expression is short for that. I think if D is going to go this route, it needs to at least get rid of the ambiguity of => {return expr;}, which is currently "return a delegate/function that returns expr".
 Having many ways to express methods make code harder to read IMO, but if 
 is in the language already then it makes sense to make it a proper 
 shortcut and not a special case.
I'm not 100% against it, though I don't see a need for it. But one of the biggest sticking points I have is: struct v { static int foo; } 1. (v) => v.foo; 2. auto x(v) => v.foo; The differences here: 1. is short for: (T)(T v) { return v.foo; } 2. is short for: auto x(v _param0) { return v.foo; } This is quite a different set of rules for parameter names and types. I would say that for shortened syntax for declarations, you cannot specify parameters with no names to avoid ambiguity. e.g. you would have to do: auto x(v unused) => v.foo; -Steve
Oct 10 2020
next sibling parent Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Saturday, 10 October 2020 at 20:43:55 UTC, Steven 
Schveighoffer wrote:
 This is quite a different set of rules for parameter names and 
 types.
That would be more difficult for newbies than not having => for member functions at all... I think this would be something that you can transpile as an upgrade though. E.g. compiler ships with source-to-source transform.
Oct 10 2020
prev sibling next sibling parent reply Paul Backus <snarwin gmail.com> writes:
On Saturday, 10 October 2020 at 20:43:55 UTC, Steven 
Schveighoffer wrote:
 I think if D is going to go this route, it needs to at least 
 get rid of the ambiguity of => {return expr;}, which is 
 currently "return a delegate/function that returns expr".
IMO this is a good idea regardless. I've fallen into the `=> { ... }` pit myself multiple times when refactoring from short to long delegate syntax, and I'm sure I'm not the only one.
Oct 10 2020
parent Adam D. Ruppe <destructionator gmail.com> writes:
On Saturday, 10 October 2020 at 23:22:30 UTC, Paul Backus wrote:
 IMO this is a good idea regardless.
Yeah, I've said before we should deprecate the whole {} thing and tell people to use () {} instead in all cases. But minimally the => {} pattern specifically should be recognized and prohibited. The lexer itself could complain about the character sequence itself.
Oct 10 2020
prev sibling next sibling parent Adam D. Ruppe <destructionator gmail.com> writes:
On Saturday, 10 October 2020 at 20:43:55 UTC, Steven 
Schveighoffer wrote:
 1. (v) => v.foo;
 2. auto x(v) => v.foo;
The latter is almost guaranteed to issue a compile time error anyway but it should be simple enough to make it an error to have any anonymous parameter in this short syntax for declarations. Maybe I can code it into the patch, it shouldn't be too complicated.
Oct 10 2020
prev sibling next sibling parent reply Adam D. Ruppe <destructionator gmail.com> writes:
On Saturday, 10 October 2020 at 20:43:55 UTC, Steven 
Schveighoffer wrote:
 1. is short for:
 (T)(T v) {
   return v.foo;
 }
This technically isn't true... the lambda expression actually does context-dependent magic that this template can't represent either. Like that is *part* of its implementation detail, but there's more to it. So since it is indeed impossible to duplicate its context-dependent magic, I made it a parse error: https://github.com/dlang/dmd/pull/11833/commits/acd15ce776af9bab336c14df20d77fbdc708e368 should be a happy enough compromise.
Oct 11 2020
parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 11.10.20 15:50, Adam D. Ruppe wrote:
 On Saturday, 10 October 2020 at 20:43:55 UTC, Steven Schveighoffer wrote:
 1. is short for:
 (T)(T v) {
   return v.foo;
 }
This technically isn't true... the lambda expression actually does context-dependent magic that this template can't represent either. Like that is *part* of its implementation detail, but there's more to it. So since it is indeed impossible to duplicate its context-dependent magic, I made it a parse error: https://github.com/dlang/dmd/pull/11833/commits/acd15ce776af9bab336c 4df20d77fbdc708e368 should be a happy enough compromise.
Just... why? Why add incidental complexity like this all? It's not like this has anything to do with the syntax of the lambda body. The original reasoning did not make any sense and this restriction is unnecessary.
Oct 11 2020
parent reply Adam D. Ruppe <destructionator gmail.com> writes:
On Sunday, 11 October 2020 at 15:38:26 UTC, Timon Gehr wrote:
 Why add incidental complexity like this all?
That's why I kept the two commits separate. I'm not in love with it either but if it is what people want, it was simple enough to implement too. Or just skip that commit.
Oct 11 2020
parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 11.10.20 17:43, Adam D. Ruppe wrote:
 On Sunday, 11 October 2020 at 15:38:26 UTC, Timon Gehr wrote:
 Why add incidental complexity like this all?
That's why I kept the two commits separate. I'm not in love with it either but if it is what people want,
My point was that nobody should want that. alias bar0=(v)=>v; void foo0(v)=>v; // why special-case this, alias bar1=(v){ return v; } void foo1(v){ return v; } // but not this? void baz0(int){ return 2; } // why is this fine, void baz1(int)=>2; // but this is not? alias baz2=(int)=>2; // and this is allowed! The complaint is _orthogonal_ to what's being discussed. This would add another special case just for the sake of making the language specification a bit longer. (args)=>e is a shorthand for (args){ return e; } and this is a simple, consistent rule. What happens later in semantic is not the business of the parser.
 it was simple enough to implement 
 too. Or just skip that commit.
+1.
Oct 11 2020
parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 10/11/20 12:04 PM, Timon Gehr wrote:
 On 11.10.20 17:43, Adam D. Ruppe wrote:
 On Sunday, 11 October 2020 at 15:38:26 UTC, Timon Gehr wrote:
 Why add incidental complexity like this all?
That's why I kept the two commits separate. I'm not in love with it either but if it is what people want,
My point was that nobody should want that. alias bar0=(v)=>v;
In here, v is a parameter name.
 void foo0(v)=>v; // why special-case this,
here, v is a type, and this is not a valid function (functions cannot return types). We are not talking about invalid functions, but valid ones.
 
 alias bar1=(v){ return v; }
 void foo1(v){ return v; } // but not this?
For a function declaration, if you want a templated value, you have to declare the template parameter. There is no short-hand syntax, like for lambdas.
 void baz0(int){ return 2; } // why is this fine,
 void baz1(int)=>2;          // but this is not?
 
 alias baz2=(int)=>2;        // and this is allowed!
Lol, that last one, it only "works" because it's a keyword. try this instead: alias Int = int; alias baz3= (Int) => 2; baz3("hello"); // compiles, it's a function with a templated parameter named Int. baz2("hello"); // error Why make it not work? Because we have an opportunity to alleviate the confusion when introducing a new feature. We can relax it later if it makes sense to. But we can't impose a rule later that breaks code. Right now, no compiling code will be broken by this restriction.
 The complaint is _orthogonal_ to what's being discussed.
 This would add another special case just for the sake of making the 
 language specification a bit longer.
To prevent confusion and inconsistency. these two are equivalent "function-like" things: alias x= (T t) => expr; auto x(T t) { return expr;} These two are not: alias x = (t) => expr; // t is a parameter auto x(t) => expr; // t is a type
 (args)=>e is a shorthand for (args){ return e; } and this is a simple, 
 consistent rule. What happens later in semantic is not the business of 
 the parser.
I don't think it needs to be a parser error. -Steve
Oct 11 2020
parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 11.10.20 20:48, Steven Schveighoffer wrote:
 
 The complaint is _orthogonal_ to what's being discussed.
 This would add another special case just for the sake of making the 
 language specification a bit longer.
To prevent confusion and inconsistency. ...
This specifically adds more inconsistency. It does nothing useful on top of that, as our examples have demonstrated.
 these two are equivalent "function-like" things:
 
 alias x= (T t) => expr;
 auto x(T t) { return expr;}
 
alias x=(T t){ return expr; } auto x(T t){ return expr; }
 These two are not:
 
 alias x = (t) => expr; // t is a parameter
 auto x(t) => expr; // t is a type
 ...
alias x=(t){ return expr; } auto x(t){ return expr; } Not sure what you are trying to achieve by varying the syntax this way. `=>` or not `=>` has nothing to do with function literal semantics.
 (args)=>e is a shorthand for (args){ return e; } and this is a simple, 
 consistent rule. What happens later in semantic is not the business of 
 the parser.
I don't think it needs to be a parser error.
The rewrite is performed in the parser.
Oct 11 2020
parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 10/11/20 2:59 PM, Timon Gehr wrote:
 alias x=(t){ return expr; }
 auto x(t){ return expr; }
 
 Not sure what you are trying to achieve by varying the syntax this way. 
 `=>` or not `=>` has nothing to do with function literal semantics.
You're right, it's already confusing. I guess we can add more confusion as long as it's added consistently. -Steve
Oct 11 2020
parent Timon Gehr <timon.gehr gmx.ch> writes:
On 11.10.20 21:07, Steven Schveighoffer wrote:
 On 10/11/20 2:59 PM, Timon Gehr wrote:
 alias x=(t){ return expr; }
 auto x(t){ return expr; }

 Not sure what you are trying to achieve by varying the syntax this 
 way. `=>` or not `=>` has nothing to do with function literal semantics.
You're right, it's already confusing. I guess we can add more confusion as long as it's added consistently. -Steve
`auto f(args)=>expr;` being transformed to `auto f(args){ return expr; }` is not confusing. Without the new syntax, the second form is what would occur in the source code, with identical semantics, confusing or not. No confusion is added.
Oct 11 2020
prev sibling parent Q. Schroll <qs.il.paperinik gmail.com> writes:
On Saturday, 10 October 2020 at 20:43:55 UTC, Steven 
Schveighoffer wrote:
 I think if D is going to go this route, it needs to at least 
 get rid of the ambiguity of => {return expr;}, which is 
 currently "return a delegate/function that returns expr".
Agreed. I've filed an enhancement request to make => { } illegal in 2017: https://issues.dlang.org/show_bug.cgi?id=17951 It's a long-standing hurdle for newcomers and nobody really needs double delegates of this form on such a regular basis that such a hurdle for newcomers is justified.
Oct 19 2020
prev sibling parent Petar Kirov [ZombineDev] <petar.p.kirov gmail.com> writes:
On Friday, 9 October 2020 at 14:44:25 UTC, Adam D. Ruppe wrote:
 After a brief chat yesterday, I slapped this together:

 https://github.com/dlang/dmd/pull/11833

 In short, in a function declaration, it rewrites `=> ...;` into 
 `{ return ...; }`

 One benefit is shorter property accessors:

     private int _x = 34;
      property x() => _x;
      property x(int v) => _x = v;

 But it also works basically anywhere

     bool isNull() => this is null;
     auto identity(T)(T a) => a;
      property y() in(true) => _x; // contracts still work too

 So it just extends the existing lambda shorthand to full 
 declarations too.

 See more in the PR description and the test case there.
Thanks! Looking forward to beautifying our projects ;) At work we already converted one of our projects that was written makes reading and writing code with the new style much more pleasant :) https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/statements-expressions-operators/expression-bodied-members https://dotnettutorials.net/lesson/expression-bodied-members-csharp/ https://www.informit.com/articles/article.aspx?p=2414582
Oct 12 2020