digitalmars.D - proposal: short => rewrite for function declarations
- Adam D. Ruppe (15/15) Oct 09 2020 After a brief chat yesterday, I slapped this together:
- 12345swordy (5/20) Oct 09 2020 This needs a dip and a preview switch. I was working on a dip
- Adam D. Ruppe (3/4) Oct 09 2020 This works with @property of course, but it is not specific to it
- Jacob Carlborg (4/24) Oct 09 2020 Yes please.
- Andre Pany (8/23) Oct 09 2020 If I remember correctly, the property setter in your example
- Adam D. Ruppe (23/27) Oct 09 2020 Well, it will actually sometimes work.
- Andre Pany (4/10) Oct 09 2020 Thanks for the explanation, makes sense.
- James Blachly (5/9) Oct 09 2020 Very much support!
- Adam D. Ruppe (5/7) Oct 09 2020 Yeah, D already has it very similarly to that too, you can use it
- Steven Schveighoffer (15/37) Oct 09 2020 It's kind of weird. You usually name a lambda outside the definition. Li...
- Adam D. Ruppe (12/15) Oct 09 2020 Yeah, but we could (and did) say the same thing about the other
- claptrap (13/28) Oct 10 2020 From the recent discussions I got the impression that needless
- Andre Pany (14/50) Oct 10 2020 I assume, if you follow the style guide, the second example
- claptrap (4/12) Oct 10 2020 A better solution is to modify the style guide to allow one
- Steven Schveighoffer (10/69) Oct 10 2020 The D style guide is here:
- Imperatorn (3/17) Oct 10 2020 What do you mean. It removes stuff. I'd say Adam's proposal is
- IGotD- (7/9) Oct 10 2020 I don't experience it as more readable. However, the biggest
- Imperatorn (5/15) Oct 10 2020 Sure, readability is subjective. It's shorter though. And I agree
- Mike Parker (3/15) Oct 10 2020 Not to me. Taking away the braces and the return statement turns
- Imperatorn (6/22) Oct 10 2020 Might be a bit of a stretch to say it becomes a "foreign
- Patrick Schluter (11/35) Oct 10 2020 It's a question of point of view.
- =?UTF-8?Q?Ali_=c3=87ehreli?= (3/6) Oct 10 2020 That.
- Mike Parker (6/8) Oct 10 2020 What I mean is that my brain is conditioned to see the braces and
- Imperatorn (4/13) Oct 10 2020 Well ok, I guess "foreign" because it's not in the language atm.
- Fred (4/20) Oct 10 2020 It's literally how lambda's are defined.
- claptrap (4/29) Oct 10 2020 How quickly you can visually parse either of them is probably 99%
- Q. Schroll (23/27) Oct 17 2020 Maybe it's nothing for you, but to me, your second paragraph is
- claptrap (9/36) Oct 18 2020 To me "readability" is how quickly you can look at some code and
- Timon Gehr (3/25) Oct 10 2020 https://issues.dlang.org/show_bug.cgi?id=7176
- Sebastiaan Koppe (3/11) Oct 10 2020 Obvious addition, don't understand much of the resistance. My
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (8/10) Oct 10 2020 I assume that TypeScript and Dart allows "=> expr" as a shortcut
- Steven Schveighoffer (29/39) Oct 10 2020 In JavaScript (TypeScript), it looks like => {return expr} and yes, just...
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (7/9) Oct 10 2020 That would be more difficult for newbies than not having => for
- Paul Backus (5/8) Oct 10 2020 IMO this is a good idea regardless. I've fallen into the `=> {
- Adam D. Ruppe (6/7) Oct 10 2020 Yeah, I've said before we should deprecate the whole {} thing and
- Adam D. Ruppe (7/9) Oct 10 2020 The latter is almost guaranteed to issue a compile time error
- Adam D. Ruppe (11/15) Oct 11 2020 This technically isn't true... the lambda expression actually
- Timon Gehr (4/22) Oct 11 2020 Just... why? Why add incidental complexity like this all? It's not like
- Adam D. Ruppe (4/5) Oct 11 2020 That's why I kept the two commits separate. I'm not in love with
- Timon Gehr (16/23) Oct 11 2020 My point was that nobody should want that.
- Steven Schveighoffer (27/51) Oct 11 2020 here, v is a type, and this is not a valid function (functions cannot
- Timon Gehr (10/32) Oct 11 2020 This specifically adds more inconsistency. It does nothing useful on top...
- Steven Schveighoffer (4/9) Oct 11 2020 You're right, it's already confusing.
- Timon Gehr (5/17) Oct 11 2020 `auto f(args)=>expr;` being transformed to `auto f(args){ return expr;
- Q. Schroll (7/10) Oct 19 2020 Agreed. I've filed an enhancement request to make => { } illegal
- Petar Kirov [ZombineDev] (10/25) Oct 12 2020 Thanks! Looking forward to beautifying our projects ;)
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
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
On Friday, 9 October 2020 at 14:46:28 UTC, 12345swordy wrote:I was working on a dip that makes propertyThis works with property of course, but it is not specific to it in any way. It might even help your dip.
Oct 09 2020
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
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
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
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:Thanks for the explanation, makes sense. Kind regards Andre[...]Well, it will actually sometimes work. Remember it just rewrites => x; into { return x; } And dmd *sometimes* lets you: [...]
Oct 09 2020
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
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
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
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
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
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: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 AndreAfter 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
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:A better solution is to modify the style guide to allow one liners where reasonable.. And you can just ignore it till then. :)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).
Oct 10 2020
On 10/10/20 6:25 AM, Andre Pany wrote:On Saturday, 10 October 2020 at 10:18:15 UTC, claptrap wrote: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. -SteveOn Friday, 9 October 2020 at 14:44:25 UTC, Adam D. Ruppe wrote: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).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
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:What do you mean. It removes stuff. I'd say Adam's proposal is more readable.[...]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
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
On Saturday, 10 October 2020 at 12:36:15 UTC, IGotD- wrote:On Saturday, 10 October 2020 at 12:30:24 UTC, Imperatorn wrote: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.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
On Saturday, 10 October 2020 at 12:30:24 UTC, Imperatorn wrote:Not to me. Taking away the braces and the return statement turns it into a foreign language.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
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: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.Not to me. Taking away the braces and the return statement turns it into a foreign language.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
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: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.On Saturday, 10 October 2020 at 12:30:24 UTC, Imperatorn wrote: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.Not to me. Taking away the braces and the return statement turns it into a foreign language.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
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
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
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: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.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
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:It's literally how lambda's are defined. auto x = () => _x; // no return statement, no braces auto x = () { return _x; }; // exactly the sameNot to me. Taking away the braces and the return statement turns it into a foreign language.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
On Saturday, 10 October 2020 at 12:30:24 UTC, Imperatorn wrote:On Saturday, 10 October 2020 at 10:18:15 UTC, claptrap wrote: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.On Friday, 9 October 2020 at 14:44:25 UTC, Adam D. Ruppe wrote:What do you mean. It removes stuff. I'd say Adam's proposal is more readable.[...]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
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.togethercause the important thing to me is that my code is simple, readable, expressiveMaybe 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
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: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.From the recent discussions I got the impression that needless syntax sugar shouldn't be added any more.togethercause the important thing to me is that my code is simple, readable, expressiveMaybe 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 18 2020
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
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
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
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: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".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.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
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
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
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
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
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
On 11.10.20 15:50, Adam D. Ruppe wrote:On Saturday, 10 October 2020 at 20:43:55 UTC, Steven Schveighoffer wrote: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.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.
Oct 11 2020
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
On 11.10.20 17:43, Adam D. Ruppe wrote:On Sunday, 11 October 2020 at 15:38:26 UTC, Timon Gehr wrote: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.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.+1.
Oct 11 2020
On 10/11/20 12:04 PM, Timon Gehr wrote:On 11.10.20 17:43, Adam D. Ruppe wrote:In here, v is a parameter name.On Sunday, 11 October 2020 at 15:38:26 UTC, Timon Gehr wrote:My point was that nobody should want that. alias bar0=(v)=>v;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,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
On 11.10.20 20:48, Steven Schveighoffer wrote:This specifically adds more inconsistency. It does nothing useful on top of that, as our examples have demonstrated.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;}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.The rewrite is performed in the parser.(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.
Oct 11 2020
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
On 11.10.20 21:07, Steven Schveighoffer wrote:On 10/11/20 2:59 PM, Timon Gehr wrote:`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.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
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
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