digitalmars.D - DIP 1030--Named Arguments--Community Review Round 1 Discussion
- Mike Parker (23/23) Feb 05 2020 This is the feedback thread for the first round of Community
- Mike Parker (3/6) Feb 05 2020 The feedback thread is here:
- Andrea Fontana (3/5) Feb 06 2020 What about UFSC + named arguments?
- Steven Schveighoffer (18/23) Feb 06 2020 Responding to this and the one in the feedback thread.
- Andrea Fontana (4/7) Feb 06 2020 I wonder whether or not "(c: 3).doStuff(3,4);" could be useful...
- H. S. Teoh (21/26) Feb 06 2020 IMO it not only adds noise, it opens the door for expanding UFCS far
- Paul Backus (5/13) Feb 06 2020 Remmeber, UFCS is only tried when property lookup fails. Since
- Walter Bright (4/5) Feb 06 2020 Your analysis is correct and inevitable and doesn't need discussion in t...
- Lim (26/28) Feb 06 2020 How about template arguments? Can we still omit the parentheses
- Lim (3/4) Feb 06 2020 Should be:
- Steven Schveighoffer (15/23) Feb 06 2020 I think this is ambiguous:
- Lim (5/11) Feb 06 2020 Yep, that's what I mean. We should make it impossible or have a
- Steven Schveighoffer (9/20) Feb 06 2020 I'm not sure it needs mentioning, as long as we are going to continue to...
- Lim (3/5) Feb 06 2020 I'm sold.
- Walter Bright (3/5) Feb 06 2020 Note that C++ stepped into a similar mess when picking < > for template ...
- Lim (18/19) Feb 06 2020 And another example of this issue:
- Dennis (4/7) Feb 06 2020 One token, not one argument.
- Jonathan M Davis (13/37) Feb 06 2020 Well, I'll say again that I don't like the idea of having named argument...
- Piotrek (20/25) Feb 07 2020 On Friday, 7 February 2020 at 03:33:26 UTC, Jonathan M Davis
- bachmeier (10/13) Feb 07 2020 This has been discussed many times already, but a big problem
- matheus (8/16) Feb 07 2020 +1. I never used this feature in C# for example.
- H. S. Teoh (22/38) Feb 07 2020 [...]
- matheus (18/28) Feb 07 2020 Yes this is one case that people will argue in favor of named
-
H. S. Teoh
(31/58)
Feb 07 2020
- matheus (12/48) Feb 07 2020 But of course seeing a code like:
- H. S. Teoh (37/61) Feb 07 2020 I know. But you struck a nerve. ;-)
- bachmeier (5/8) Feb 07 2020 It actively encourages a style of "just add another function
- Paul Backus (9/17) Feb 07 2020 People will do this anyway, whether or not the language has named
- Walter Bright (9/20) Feb 07 2020 I appreciate your thoughts on this. But I like the feature even if all i...
- Paolo Invernizzi (14/43) Feb 08 2020 Honestly, I like the Flag template ...
- Walter Bright (5/8) Feb 08 2020 This PR would discourage gratuitous name changes of parameters, just lik...
- FeepingCreature (17/25) Feb 08 2020 I'm sorry, I need to hammer this in.
- Jonathan M Davis (18/39) Feb 11 2020 That is an upside to it, though I don't think that it's worth having to ...
- Paul Backus (23/30) Feb 11 2020 This strikes me as a false dichotomy, in two ways.
- aliak (26/78) Feb 11 2020 Named arguments is the difference between spending 1 second
- SashaGreat (18/26) Feb 12 2020 You're using an example in favor of a point, because it's hard to
- Steven Schveighoffer (21/52) Feb 12 2020 I agree with you! But it depends on the situation.
- Sasha (10/15) Feb 12 2020 Since I never used named arguments, I mean I never opted to and
- Paul Backus (15/19) Feb 12 2020 The only official, publicly-available information I could find on
- Steven Schveighoffer (22/34) Feb 13 2020 Swift is notorious for making breaking changes, including function and
- Jonathan Marler (18/36) Feb 12 2020 You could use variables to make it look nicer at the call-side,
- Sasha (23/40) Feb 12 2020 OK, now let's see a problem with named arguments, imagine this:
- JN (8/12) Feb 12 2020 Which pretty much doesn't exist in the existing languages that
- Jonathan Marler (11/58) Feb 12 2020 My point was the the error is caught at compile-time rather than
- Walter Bright (4/6) Feb 12 2020 As an aside, this is why I encourage URLs to be put right in the source ...
- Jon Degenhardt (31/39) Feb 08 2020 I am in definitely in favor of named arguments in the language.
- Adam D. Ruppe (12/14) Feb 08 2020 Does it change your view at all that parameter names are *already
- Jon Degenhardt (13/28) Feb 08 2020 Probably not, but let me give some thoughts and ask a clarifying
- Adam D. Ruppe (22/26) Feb 08 2020 We can do named parameters in a library already, something like:
- Jon Degenhardt (7/21) Feb 08 2020 That's a useful example, thanks! It doesn't change my overall
- Adam D. Ruppe (15/17) Feb 08 2020 I would kinda love user-defined warnings. pragma(msg) comes close
- Timon Gehr (4/15) Feb 11 2020 int justDoThis(int,int){
- Walter Bright (5/22) Feb 12 2020 static if (condition) pragma(msg, "Look, Ma!");
- Adam D. Ruppe (32/35) Feb 12 2020 In this context, the condition there would be someone using the
- Walter Bright (9/14) Feb 13 2020 It's a good idea, but I've found it to be pragmatic to not worry much ab...
- Steven Schveighoffer (25/52) Feb 08 2020 If you name your parameters something unintuitive, like "a". Likely
- Jon Degenhardt (19/39) Feb 08 2020 Well, I personally wouldn't recommend this as a general remedy.
- Steven Schveighoffer (37/42) Feb 09 2020 I think the evolution goes like this:
- Adam D. Ruppe (17/19) Feb 09 2020 We can always just `alias a = milliseconds;` inside the function.
- Steven Schveighoffer (3/26) Feb 09 2020 Agree with all of this.
- Paul Backus (9/19) Feb 09 2020 You can alias the parameter inside the function:
- Walter Bright (11/14) Feb 09 2020 Since parameter names are not part of the name mangling, you can do thin...
- Jon Degenhardt (35/72) Feb 09 2020 Yes, this is representative of what I had in mind. Another is
- FeepingCreature (15/35) Feb 09 2020 I feel like this increase in surface area is actually
- rikki cattermole (6/10) Feb 09 2020 Alternatively support implicit construction of structs as parameters i.e...
- rb3 (23/35) Feb 09 2020 This sounds like a good unification between struct initialization
- rikki cattermole (5/50) Feb 09 2020 That is not what I suggested.
- rb3 (7/12) Feb 09 2020 That sounds like what I just described. Not sure what the
- rikki cattermole (6/18) Feb 09 2020 I have commented on that PR.
- Zoadian (3/17) Feb 09 2020 vibe.d uses parameter names to generate REST api bindings
- Walter Bright (6/9) Feb 09 2020 Note that D already has "named parameters" for struct initializers. That...
- Arine (13/24) Feb 09 2020 struct A {
- Walter Bright (2/3) Feb 09 2020 Please report all bugs to bugzilla.
- Walter Bright (3/15) Feb 09 2020 C has it, too. Never heard a single complaint about it, either.
- Timon Gehr (4/22) Feb 11 2020 If you change the name of a field, code that accesses the field in the
- Walter Bright (4/7) Feb 12 2020 If the code followed good encapsulation techniques, it wouldn't any more...
- Timon Gehr (2/10) Feb 19 2020 Which is exactly what defeats the argument that spawned this sub-thread.
- Arine (13/28) Feb 11 2020 struct A {
- Patrick Schluter (3/34) Feb 11 2020 only since C11. anonymous unions and structs are gcc extension
- Steven Schveighoffer (22/26) Feb 10 2020 I find this assertion lacking evidence.
- H. S. Teoh (9/18) Feb 10 2020 [...]
- Steven Schveighoffer (6/20) Feb 10 2020 So basically, for each type you need to define another type to pass
- H. S. Teoh (7/30) Feb 10 2020 [...]
- Walter Bright (2/3) Feb 10 2020 Thanks, you said it better than I!
- Panke (14/26) Feb 10 2020 Let me give a data point to the contrary. I am a C++ programmer
- Jonathan M Davis (34/59) Feb 11 2020 The only time that the struct initialization equivalent of named paramet...
- Jesse Phillips (12/16) Feb 10 2020 I've had the opportunity to design some methods relying on named
- Yuxuan Shui (8/11) Feb 19 2020 Named parameters are not just for when there are too many
- Jonathan M Davis (22/33) Feb 19 2020 Named arguments are completely unnecessary in such a situation. The list...
- Adam D. Ruppe (8/12) Feb 19 2020 Eh, the thing with these is it is really easy to do it backwards.
- bachmeier (9/52) Feb 19 2020 I agree. I know there are complaints about being required to use
- 12345swordy (5/15) Feb 19 2020 What editor are you specifically talking about here and how
- Panke (6/22) Feb 19 2020 E.g. CLion does it. In renders the parameter names at the call
- 12345swordy (3/20) Feb 19 2020 Isn't that mainly due to cpp having header files?
- Panke (6/13) Feb 19 2020 I just can say that my professional experience leads me to
- Meta (8/30) Feb 20 2020 This is off the mark. Named arguments are very useful even in
- Steven Schveighoffer (10/19) Feb 06 2020 Does it? AliasSeq's template parameter (singular) is named TList, not a,...
- Steven Schveighoffer (4/6) Feb 06 2020 So do typesafe variadics. I think the DIP needs to be more explicit here...
- Timon Gehr (3/22) Feb 07 2020 It does add the syntax, and I would argue it is not ideal if this fails
- Steven Schveighoffer (10/33) Feb 07 2020 Yes, it's valid syntax, but shouldn't pass semantic -- you named
- Timon Gehr (4/19) Feb 08 2020 So you are arguing that e.g., std.typecons.Proxy should fail to work
- Steven Schveighoffer (20/40) Feb 08 2020 Technically, it doesn't today, so it's not a break. But it is a good
- Walter Bright (8/8) Feb 08 2020 It's clear that what should happen with named arguments and variadics is...
- Fynn =?UTF-8?B?U2NocsO2ZGVy?= (9/14) Feb 06 2020 I think this DIP is a solid approach to named arguments for D.
- jmh530 (13/21) Feb 07 2020 This was on the feedback thread, but I didn't want to pollute
- Timon Gehr (13/31) Feb 08 2020 Here's my answer from the feedback thread:
- Manu (43/87) Feb 10 2020 I don't have any horse in this race... but I do just want to echo that
- Adam D. Ruppe (28/31) Feb 10 2020 It is super simple. Consider this example:
- Timon Gehr (2/37) Feb 11 2020 What if fn is a template?
- Adam D. Ruppe (14/15) Feb 11 2020 Then, as I'm sure you already know, it won't work. It needs an
- Steven Schveighoffer (12/28) Feb 11 2020 Manu's example doesn't work, but this would (and I use this all the time...
- Adam D. Ruppe (15/19) Feb 11 2020 Yeah, I use that a lot too.
- Timon Gehr (5/21) Feb 11 2020 int troll(int ret){ return ret; }
- Adam D. Ruppe (2/6) Feb 11 2020 lol, indeed. There can be downsides to inheriting random names :)
- 12345swordy (7/17) Feb 10 2020 For me personalty, readability\reliability is a huge factor here.
- 12345swordy (3/22) Feb 10 2020 Meant to say "Named arguments prevent me from sending values to
- Manu (6/25) Feb 10 2020 That feels like a pretty washy justification.
- 12345swordy (4/29) Feb 10 2020 Manu, it boils down to mainly experience when it comes to wanting
- Manu (22/52) Feb 10 2020 I've seen some arguments, but I haven't understood them personally. I
- 12345swordy (4/73) Feb 10 2020 Yes, I have encounter the "API breakage" counter argument in
- Manu (13/88) Feb 10 2020 It's a huge problem today when a bad choice of function name is
- jmh530 (11/29) Feb 10 2020 I was leaning towards favoring this DIP, as I frequently use
- Adam D. Ruppe (18/22) Feb 10 2020 In Python it is different because there's no compiler to tell you
- Paolo Invernizzi (6/9) Feb 11 2020 That's true, but it's an hell when involving libraries: an
- Andrea Fontana (4/15) Feb 11 2020 If package dependencies are used correctly nothing is break :)
- Paolo Invernizzi (8/27) Feb 11 2020 What I mean, is that multiple authors can be involved in the
- Arine (10/13) Feb 11 2020 Only if you use the feature. That's part of the reason why I
- Manu (8/21) Feb 11 2020 As a library author, you can't control whether a client uses named
- Arine (31/60) Feb 13 2020 I meant that in terms of the user. A library author can choose
- Claude (14/25) Feb 11 2020 Yes, precisely... I was a bit circumspect about named arguments
- Andrea Fontana (4/7) Feb 11 2020 That's true for every dip we approve, not only for named
- Paolo Invernizzi (7/14) Feb 11 2020 No, there could be language improvements introduced with breaking
- Manu (33/84) Feb 10 2020 We deprecate and rename things all the time. If this DIP is accepted,
- aliak (8/39) Feb 10 2020 Off by 1 errors?
- Adam D. Ruppe (7/9) Feb 10 2020 Take a look at how easy it is to write a full forwarder function:
- Atila Neves (3/12) Feb 20 2020 Nope: https://www.python.org/dev/peps/pep-0570/
- jmh530 (49/51) Feb 20 2020 1) Pep 570 is opt-in*. It gives you a bit more control so you can
- Paolo Invernizzi (3/13) Feb 20 2020 That's the exact reason why they proposed 570: having named
- 12345swordy (5/19) Feb 20 2020 I don't think nor do I expect that people would used named
- 12345swordy (3/23) Feb 20 2020 *Unless it is mandate by the language obviously*
- jmh530 (7/11) Feb 20 2020 What's that saying? If some code can be written, it will be
- 12345swordy (3/17) Feb 20 2020 Which it is trivial to fix, if you have right tools.
- 12345swordy (14/103) Feb 10 2020 Which is a no big deal when the probability is very low to big
- Paolo Invernizzi (14/17) Feb 11 2020 I don't know since when you are around in D-land, but I'm here
- 12345swordy (7/25) Feb 11 2020 Then use cpp if you hate future code breakage that much. The
- Paolo Invernizzi (7/8) Feb 11 2020 I don't go down that rabbit hole ... I've seen it too many times
- 12345swordy (6/10) Feb 11 2020 What rabbit hole are you talking about here!? The cpp committee
- Paolo Invernizzi (30/43) Feb 11 2020 Probably I'm not able to explain myself clearly, so my fault ...
- 12345swordy (5/10) Feb 11 2020 Then don't rename the arguments at all if you don't want to break
- Paolo Invernizzi (8/21) Feb 11 2020 That's exactly the point.
- 12345swordy (6/29) Feb 11 2020 If you find yourself in a situation that you end up renaming the
- Paolo Invernizzi (2/6) Feb 11 2020 Ok, that's enough for me
- 12345swordy (13/20) Feb 11 2020 Look, C# has named arguments for over a decade now and you can't
- rikki cattermole (7/8) Feb 11 2020 If you start with opt-in, you can make it the default later on without
- 12345swordy (6/15) Feb 11 2020 Yes, I remember and even participate in one of the dip that makes
- IGotD- (12/17) Feb 10 2020 It's about my thoughts too. I think the question that needs to be
- Manu (9/27) Feb 10 2020 I doubt there's any meaningful implementation complexity inside DMD.
- Adam D. Ruppe (2/5) Feb 10 2020 This does not occur.
- aliak (12/63) Feb 10 2020 Before the DIP you'd call that like:
- Adam D. Ruppe (8/10) Feb 10 2020 I posted this earlier in this very thread:
- aliak (6/16) Feb 10 2020 Oh. Indeed :) Seems simple enough.
- H. S. Teoh (13/17) Feb 10 2020 Whoa. Just last week I was trying to look up this exact post, but
- Adam D. Ruppe (9/11) Feb 10 2020 Getting individual pieces out of it need some techniques (gotta
- Manu (13/23) Feb 10 2020 Sorry, I missed that above. Thanks for pointing this out.
- Steven Schveighoffer (10/33) Feb 11 2020 This has convinced me (along with reading the subsequent thread) that we...
- Jonathan Marler (30/54) Feb 10 2020 I'm curious what the current state of druntime/phobos is with
- Jonathan Marler (51/149) Feb 10 2020 I took some time to go through the "std.array" module to see how
- Manu (9/166) Feb 10 2020 Mmmm, wow.
- Vladimir Panteleev (7/8) Feb 10 2020 I'm not sure it's correct to say this, considering that parameter
- Walter Bright (5/23) Feb 10 2020 It isn't inconsistent. In math, z=x+iy is normal notation, i.e. x for re...
- Jonathan Marler (38/68) Feb 11 2020 conj and abs are using template parameters. So if you're passing
- Paul Backus (5/20) Feb 11 2020 Here's a better example: functions like move and memcpy that take
- Walter Bright (6/9) Feb 11 2020 The C99 Standard says:
- Walter Bright (15/36) Feb 11 2020 Sounds reasonable to me. But keep in mind that this will also result in
- Steven Schveighoffer (15/19) Feb 11 2020 Just wanted to point out without muddying the feedback thread, that this...
- Adam D. Ruppe (19/20) Feb 11 2020 I wrote about this in github comments when the dip pr was first
- Steven Schveighoffer (25/47) Feb 11 2020 ha, I just pushed back on the idea of a custom struct coming in and the
- Walter Bright (5/16) Feb 11 2020 Currently, no.
- Steven Schveighoffer (10/30) Feb 11 2020 I disagree. If you don't do something about this, the entire realm of
- SashaGreat (3/22) Feb 12 2020 Sorry but this is another half backed implementation.
This is the feedback thread for the first round of Community Review for DIP 1030, "Named Arguments": https://github.com/dlang/DIPs/blob/44b0d4ec0da6a2e797ede748fb1e81cd6db10371/DIPs/DIP1030.md 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... in other words, business as usual. However, if you have any specific feedback for how to improve the the proposal itself, then please post it in the feedback thread. The feedback thread will be the source for the review summary I 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 The review period will end at 11:59 PM ET on February 20, or when I make a post declaring it complete. Discussion in this thread may continue beyond that point. At the end of Round 1, if further review is deemed necessary, the DIP will be scheduled for another round of Community Review. Otherwise, it will be queued for the Final Review and Formal Assessment. Please stay on topic here. I will delete posts that are completely off topic.
Feb 05 2020
On Thursday, 6 February 2020 at 06:08:59 UTC, Mike Parker wrote:However, if you have any specific feedback for how to improve the the proposal itself, then please post it in the feedback thread.The feedback thread is here: https://forum.dlang.org/post/bizqhxszbobynrimsgai forum.dlang.org
Feb 05 2020
On Thursday, 6 February 2020 at 06:08:59 UTC, Mike Parker wrote:This is the feedback thread for the first round of Community Review for DIP 1030, "Named Arguments":What about UFSC + named arguments? Andrea
Feb 06 2020
On 2/6/20 4:39 AM, Andrea Fontana wrote:On Thursday, 6 February 2020 at 06:08:59 UTC, Mike Parker wrote:Responding to this and the one in the feedback thread. My understanding is that UFCS works like this: a.foo(...); translates to: foo(a, ...); So if you follow that logic, the rules apply after that translation as if you called the function that way. example: void doStuff(int a, string b, double c) {} 3.doStuff(6.7, b: "ham") => doStuff(3, 6.7, b: ham) => error, no match (6.7 doesn't match type to b) 3.doStuff(c: 6.7, b: "ham") => doStuff(3, c: 6.7, b: ham) => OK, all parameters match 3.doStuff(a: 5, "ham", 6.7) => doStuff(3, a: 5, "ham", 6.7) => error, cannot match a twice Might be a good point to add UFCS discussion to the DIP. -SteveThis is the feedback thread for the first round of Community Review for DIP 1030, "Named Arguments":What about UFSC + named arguments?
Feb 06 2020
On Thursday, 6 February 2020 at 15:30:40 UTC, Steven Schveighoffer wrote:On 2/6/20 4:39 AM, Andrea Fontana wrote: Might be a good point to add UFCS discussion to the DIP. -SteveI wonder whether or not "(c: 3).doStuff(3,4);" could be useful... Probably it just adds some noise.
Feb 06 2020
On Thu, Feb 06, 2020 at 05:03:06PM +0000, Andrea Fontana via Digitalmars-d wrote:On Thursday, 6 February 2020 at 15:30:40 UTC, Steven Schveighoffer wrote:[...]On 2/6/20 4:39 AM, Andrea Fontana wrote: Might be a good point to add UFCS discussion to the DIP.I wonder whether or not "(c: 3).doStuff(3,4);" could be useful... Probably it just adds some noise.IMO it not only adds noise, it opens the door for expanding UFCS far beyond its original charter. Because now, nothing stops you from doing this: struct A {} struct B {} struct C {} auto fun(A a, B b, C c) { ... } A a; B b; C c; (a: a).fun(b: b, c: c); (b: b).fun(a: a, c: c); (c: c).fun(a: a, b: b); IOW, you can now pull out any arbitrary parameter from any function and do UFCS on it. I honestly don't think this is a good idea, as it will open up whole cans o' worms esp. once it starts interacting with IFTI. T -- We are in class, we are supposed to be learning, we have a teacher... Is it too much that I expect him to teach me??? -- RL
Feb 06 2020
On Thursday, 6 February 2020 at 17:03:06 UTC, Andrea Fontana wrote:On Thursday, 6 February 2020 at 15:30:40 UTC, Steven Schveighoffer wrote:Remmeber, UFCS is only tried when property lookup fails. Since `(c: 3).doStuff` is not a valid property access, it cannot possibly be a valid UFCS call.On 2/6/20 4:39 AM, Andrea Fontana wrote: Might be a good point to add UFCS discussion to the DIP. -SteveI wonder whether or not "(c: 3).doStuff(3,4);" could be useful... Probably it just adds some noise.
Feb 06 2020
On 2/6/2020 7:30 AM, Steven Schveighoffer wrote:Might be a good point to add UFCS discussion to the DIP.Your analysis is correct and inevitable and doesn't need discussion in the DIP. It's another illustration why lowering is a good idea - it takes care of things like this renderubg further exposition and design work not necessary.
Feb 06 2020
On Thursday, 6 February 2020 at 06:08:59 UTC, Mike Parker wrote:This is the feedback thread for the first round of Community Review for DIP 1030, "Named Arguments"How about template arguments? Can we still omit the parentheses if it is one token long? i.e., template Example(int a = 0, alias b, int c = 0) => Example!b:1 If the answer is yes, considering the following code: template SomeTemplate(int a = 0, alias b, int c = 0) { alias SomeTemplate = b; } const b = 2; const c = 3; switch(someInt) { case 1: .. case SomeTemplate!b : c: writeln("we are in case"); break; default: writeln("we are in default"); goto c; } It's valid now and when someInt >= 3, "we are in default" and "we are in case" will both be printed. According to the rule "If an Identifier is present, it matches the Parameter with the corresponding Identifier", when this DIP come into power, this code won't compile as there is no LabeledStatement Identifier named c. Is this a potential compatibility issue? Or is there a misunderstanding of my interpretation of the new DIP?
Feb 06 2020
On Thursday, 6 February 2020 at 21:06:38 UTC, Lim wrote:template SomeTemplate(int a = 0, alias b, int c = 0)Should be: template SomeTemplate(alias b, int c = 0)
Feb 06 2020
On 2/6/20 4:06 PM, Lim wrote:On Thursday, 6 February 2020 at 06:08:59 UTC, Mike Parker wrote:I think this is ambiguous: template Example(int b) { enum Example = b + 5; } enum b = 5; auto x = true ? Example!b:1; or maybe: case Example!b: It could be worked out if one examines the whole expression/statement, but I think we're better off avoiding support for such things. Note that existing templates don't allow operators when omitting parentheses. -SteveThis is the feedback thread for the first round of Community Review for DIP 1030, "Named Arguments"How about template arguments? Can we still omit the parentheses if it is one token long? i.e., template Example(int a = 0, alias b, int c = 0) => Example!b:1
Feb 06 2020
On Thursday, 6 February 2020 at 21:37:11 UTC, Steven Schveighoffer wrote:It could be worked out if one examines the whole expression/statement, but I think we're better off avoiding support for such things. Note that existing templates don't allow operators when omitting parentheses. -SteveYep, that's what I mean. We should make it impossible or have a predictable behavior. Unfortunately, this case was not mentioned in DIP 1030.
Feb 06 2020
On 2/6/20 4:46 PM, Lim wrote:On Thursday, 6 February 2020 at 21:37:11 UTC, Steven Schveighoffer wrote:I'm not sure it needs mentioning, as long as we are going to continue to enforce the current rules (no operators are included unless you use parentheses). Allowing colons as part of the no-parentheses template arg would be a difference that required a grammar change. As the DIP isn't changing that grammar (it's here: https://dlang.org/spec/grammar.html#TemplateSingleArgument), we shouldn't need to discuss it. -SteveIt could be worked out if one examines the whole expression/statement, but I think we're better off avoiding support for such things. Note that existing templates don't allow operators when omitting parentheses.Yep, that's what I mean. We should make it impossible or have a predictable behavior. Unfortunately, this case was not mentioned in DIP 1030.
Feb 06 2020
On Thursday, 6 February 2020 at 21:58:19 UTC, Steven Schveighoffer wrote:https://dlang.org/spec/grammar.html#TemplateSingleArgument), we shouldn't need to discuss it.I'm sold.
Feb 06 2020
On 2/6/2020 1:37 PM, Steven Schveighoffer wrote:It could be worked out if one examines the whole expression/statement, but I think we're better off avoiding support for such things.Note that C++ stepped into a similar mess when picking < > for template arguments. We're not going that way.
Feb 06 2020
On Thursday, 6 February 2020 at 21:06:38 UTC, Lim wrote:Can we still omit the parentheses if it is one token long?And another example of this issue: template Example(alias x, int y = 0) { ... } // assume x defined before is(Example!x : int) { ... } Note: Although DIP 88 and DIP 1020 give some examples on using Named Arguments with single parameter template (all with parentheses). Nothing is mentioned on whether parentheses are required in this situation. According to current Spec: "If the TemplateArgument is one token long, the parentheses can be omitted", all two examples I showed are legal. As the indentifier tokens are not the same thing as TemplateArgument tokens: +TemplateNamedArgument: + Identifier : TemplateArgument + TemplateArgument Thus, the single-token parameter use case should be regulated in DIP 1030.
Feb 06 2020
On Thursday, 6 February 2020 at 21:41:33 UTC, Lim wrote:According to current Spec: "If the TemplateArgument is one token long, the parentheses can be omitted", all two examples I showed are legal.One token, not one argument. `a:b` and alike are three tokens long. See https://dlang.org/spec/lex.html#tokens
Feb 06 2020
On Wednesday, February 5, 2020 11:08:59 PM MST Mike Parker via Digitalmars-d wrote:This is the feedback thread for the first round of Community Review for DIP 1030, "Named Arguments": https://github.com/dlang/DIPs/blob/44b0d4ec0da6a2e797ede748fb1e81cd6db1037 1/DIPs/DIP1030.md 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... in other words, business as usual. However, if you have any specific feedback for how to improve the the proposal itself, then please post it in the feedback thread. The feedback thread will be the source for the review summary I 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 The review period will end at 11:59 PM ET on February 20, or when I make a post declaring it complete. Discussion in this thread may continue beyond that point. At the end of Round 1, if further review is deemed necessary, the DIP will be scheduled for another round of Community Review. Otherwise, it will be queued for the Final Review and Formal Assessment. Please stay on topic here. I will delete posts that are completely off topic.Well, I'll say again that I don't like the idea of having named arguments in the language, because it makes the parameter names part of the API, resulting in yet more bikeshedding and yet another thing that can't be changed without breaking existing code. Once in a while, named arguments may be useful, but for the most part, they're useful because a function has way too many parameters, in which case, the function should have been designed differently. Unfortunately, since it's Walter who created the DIP, and a number of people do like the idea of named arguments, I expect that some form of this will make it in, but I still think that it's a bad idea. - Jonathan M Davis
Feb 06 2020
On Friday, 7 February 2020 at 03:33:26 UTC, Jonathan M Davis wrote: [...]Well, I'll say again that I don't like the idea of having named arguments in the language, because it makes the parameter names part of the API, resulting in yet more bikeshedding and yet another thing that can't be changed without breaking existing code.For me, the DIP is on the top of the improvements list. I missed it many times. I found the code with named arguments much more readable no mater how many arguments are defined for the functions (i.e. including those with even 1 argument in some cases). Regarding API design. To some extent the names of arguments are already a part of API in any programming language. They form a documentation for users which can be referenced in many places. As for the "breaking change" problem. My opinion is that there should be an appropriate deprecation process available for any change in the language without an exception. Surly it needs some planning and rationale which is costly, making it not straightforward and not applicable in some cases. But the "braking change" problem shouldn't be an unbreakable barrier for improvements which are worth it. Additionally DIPs have trial period, don't they? Piotrek
Feb 07 2020
On Friday, 7 February 2020 at 17:06:21 UTC, Piotrek wrote:Regarding API design. To some extent the names of arguments are already a part of API in any programming language. They form a documentation for users which can be referenced in many places.This has been discussed many times already, but a big problem with named arguments is that it creates a lot of overhead when writing new functions. Rather than worrying about what the functionality is supposed to do, you have to think of argument names that are good for the long run.* That's a whole lot of overhead. * Of course, you can come back to it "in the future" after you have your library finished and tested. Nobody in the history of programming has ever done that.
Feb 07 2020
On Friday, 7 February 2020 at 03:33:26 UTC, Jonathan M Davis wrote:Well, I'll say again that I don't like the idea of having named arguments in the language, because it makes the parameter names part of the API, resulting in yet more bikeshedding and yet another thing that can't be changed without breaking existing code. Once in a while, named arguments may be useful, but for the most part, they're useful because a function has way too many parameters, in which case, the function should have been designed differently.Like you said: "...named arguments may be useful, but for the most part, they're useful because a function has way too many parameters, the function should have been designed differently.". Matheus.
Feb 07 2020
On Fri, Feb 07, 2020 at 07:02:14PM +0000, matheus via Digitalmars-d wrote:On Friday, 7 February 2020 at 03:33:26 UTC, Jonathan M Davis wrote:[...] I agree that this tends to be the use case, and I agree that when the number of function parameters exceed a certain threshold, it should be designed differently. At the very least, the parameters should be factored into a struct that can then be initialized by the caller and passed in as a whole, rather than isolated arguments. However, I *have* also found myself desiring nameable arguments for the sake of self-documenting code, for example: myRange.process(nRetries: 2); as opposed to: myRange.process(2); // what does '2' mean?! I can't say this is always desirable, but there are situations where it would be nice, maybe because the parameter is optional, or tangential to the function's main purpose, so it's not immediately obvious what it does. There are definitely times when I'd say this is a sign of bad API design, but I also can't say that 100% of the time. As with all things, there are exceptions, and in the exceptional cases named arguments can be just the thing to fill that need. T -- It's bad luck to be superstitious. -- YHLWell, I'll say again that I don't like the idea of having named arguments in the language, because it makes the parameter names part of the API, resulting in yet more bikeshedding and yet another thing that can't be changed without breaking existing code. Once in a while, named arguments may be useful, but for the most part, they're useful because a function has way too many parameters, in which case, the function should have been designed differently.Like you said: "...named arguments may be useful, but for the most part, they're useful because a function has way too many parameters, the function should have been designed differently.".
Feb 07 2020
On Friday, 7 February 2020 at 19:26:10 UTC, H. S. Teoh wrote:... However, I *have* also found myself desiring nameable arguments for the sake of self-documenting code, for example: myRange.process(nRetries: 2); as opposed to: myRange.process(2); // what does '2' mean?! ...Yes this is one case that people will argue in favor of named arguments, but on the other hand I would point out: Why is he using a magic number in a code? :) A define/enum/variable would fix this issue, at least in most documentations I read I usually see variables to explain the "expected parameters". Another thing is current Editors/IDE help with this problem too, they show what parameters a function is expected even the overloads while you typing. https://docs.microsoft.com/en-us/dotnet/api/system.dayofweek?view=netframework-4.8#examples You will see a example of DateTime usage like this:// Assume the current culture is en-US. // Create a DateTime for the first of May, 2003. DateTime dt = new DateTime(2003, 5, 1);They didn't even bother to use named arguments there. They just warned about culture en-US. :) Well in my opinion I would prefer to see development in other areas than in this particular case. Matheus.
Feb 07 2020
On Fri, Feb 07, 2020 at 07:59:41PM +0000, matheus via Digitalmars-d wrote:On Friday, 7 February 2020 at 19:26:10 UTC, H. S. Teoh wrote:<rant> IMNSHO, the obsession with getting rid of magic numbers is a bunch of hooey. There's a time and place for that, e.g., you don't want two pieces of code to go out of sync when the constants they use must match a common value. But pushing this to the extremes leads to stupid code like this: enum two = 2; // look, ma! I know how to name magic numbers! myRange.process(two); // yay, no more magic numbers! which is completely ridiculous. If the constant only appears in one place, just write the damn constant out already, that's why the programming language has integer literals, dammit. Giving it a name just because "magic numbers are Bad(tm)" is stupid. </rant> [...]... However, I *have* also found myself desiring nameable arguments for the sake of self-documenting code, for example: myRange.process(nRetries: 2); as opposed to: myRange.process(2); // what does '2' mean?! ...Yes this is one case that people will argue in favor of named arguments, but on the other hand I would point out: Why is he using a magic number in a code? :)https://docs.microsoft.com/en-us/dotnet/api/system.dayofweek?view=netframework-4.8#examples You will see a example of DateTime usage like this:Actually, that's not en-US. In *true* American style, the correct order of arguments should be (5, 1, 2003). :-P (Which IMNSHO is a stupid, illogical convention, which gets especially bad when they drop the first 2 digits of the year, and then you get incomprehensible dates like 10/12/11: is it Oct 12, 2011? Dec 10, 2011? Or Dec 11, 2010? Or maybe Nov 12, 2010? Who even knows. Everyone should just stick with ISO-style yyyy-mm-dd, dangit!!)// Assume the current culture is en-US. // Create a DateTime for the first of May, 2003. DateTime dt = new DateTime(2003, 5, 1);They didn't even bother to use named arguments there. They just warned about culture en-US. :)Well in my opinion I would prefer to see development in other areas than in this particular case.[...] True, Walter himself has said D needs to have a small number of powerful tools that are very expressive, rather than be a kitchen sink full of every feature you can think of but each is anemic and more-or-less redundant. T -- Do not reason with the unreasonable; you lose by definition.
Feb 07 2020
On Friday, 7 February 2020 at 21:57:18 UTC, H. S. Teoh wrote:On Fri, Feb 07, 2020 at 07:59:41PM +0000, matheus via Digitalmars-d wrote:Hold your rant buddy I was just replying to your example :)On Friday, 7 February 2020 at 19:26:10 UTC, H. S. Teoh wrote:<rant> IMNSHO, the obsession with getting rid of magic numbers is a bunch of hooey. There's a time and place for that, e.g., you don't want two pieces of code to go out of sync when the constants they use must match a common value. But pushing this to the extremes leads to stupid code like this: enum two = 2; // look, ma! I know how to name magic numbers! myRange.process(two); // yay, no more magic numbers! which is completely ridiculous. ...... However, I *have* also found myself desiring nameable arguments for the sake of self-documenting code, for example: myRange.process(nRetries: 2); as opposed to: myRange.process(2); // what does '2' mean?! ...Yes this is one case that people will argue in favor of named arguments, but on the other hand I would point out: Why is he using a magic number in a code? :)But of course seeing a code like:myRange.process(2); // what does '2' mean?!enum two = 2; // look, ma! I know how to name magic numbers! myRange.process(two); // yay, no more magic numbers!Would be totally nonsense to me too. On the other hand:myRange.process(nRetries);For me would be ok and a standard where I work. And the IDE would give me the hint about the value of nRetries. Talking about magic numbers, well I had enough of it after diving into code like[1]:tempy = 0x80000000; for(i=-131072;i<=131072;i+=(2048>>gride))plc = x1+mulscale12((2047-y1)&4095,inc); i = ((y1+2048)>>12); daend = ((y2+2048)>>12);And need to understand each number. :) Matheus. [1] - https://github.com/videogamepreservation/dukenukem3d/blob/master/SRC/ENGINE.C
Feb 07 2020
On Fri, Feb 07, 2020 at 10:28:27PM +0000, matheus via Digitalmars-d wrote: [...]Hold your rant buddy I was just replying to your example :)I know. But you struck a nerve. ;-)Fair enough. But it seems a bit onerous to have to write this: int nRetries = 2; myRange.process(nRetries); when you could just write: myRange.process(nRetries: 2);But of course seeing a code like:myRange.process(2); // what does '2' mean?!enum two = 2; // look, ma! I know how to name magic numbers! myRange.process(two); // yay, no more magic numbers!Would be totally nonsense to me too. On the other hand:myRange.process(nRetries);For me would be ok and a standard where I work. And the IDE would give me the hint about the value of nRetries.Talking about magic numbers, well I had enough of it after diving into code like[1]:I see nonsense like this all the time. It's common practice in "enterprise" code. It's one of the red flags that says "don't touch this spaghetti code unless you can eat the consequences". My policy is to stay away from such code unless you absolutely can't get out of touching it. And even then, touch as little as you can to get your job done, and then get outta there pronto, before the fragile tower of cards that is the code comes crashing down on your head. :-P In this particular case, clearly the constants aren't just one-off constants; they have a specific meaning and really should be refactored into named constants instead. So in this case, I'd say it's a *good* thing to get rid of the magic numbers. But I disagree with the hardline attitude of "there must be no integer literals in your code outside of constant declarations", which is apparently what some people actually believe. In each case, a judgment call must be made, and there is no one-size-fits-all answer. As Walter said once: I've been around long enough to have seen an endless parade of magic new techniques du jour, most of which purport to remove the necessity of thought about your programming problem. In the end they wind up contributing one or two pieces to the collective wisdom, and fade away in the rearview mirror. You cannot just take a rule of thumb like "avoid magic constants" as a crutch to avoid the necessity of thought about your present programming problem. Sometimes it makes sense, but sometimes it doesn't; it doesn't make any sense to have a knee-jerk reaction "aaaaah, magic constant!" every time you see a naked integer literal. T -- Obviously, some things aren't very obvious.tempy = 0x80000000; for(i=-131072;i<=131072;i+=(2048>>gride))plc = x1+mulscale12((2047-y1)&4095,inc); i = ((y1+2048)>>12); daend = ((y2+2048)>>12);And need to understand each number. :)
Feb 07 2020
On Friday, 7 February 2020 at 19:02:14 UTC, matheus wrote:"...named arguments may be useful, but for the most part, they're useful because a function has way too many parameters, the function should have been designed differently.".It actively encourages a style of "just add another function argument". You start small and as you decide to change your function, it's easy to fall into the trap of adding one more argument, because the end user is free to ignore it.
Feb 07 2020
On Friday, 7 February 2020 at 19:44:31 UTC, bachmeier wrote:On Friday, 7 February 2020 at 19:02:14 UTC, matheus wrote:People will do this anyway, whether or not the language has named arguments. In fact, here are a couple examples in D where it's been done in the past: - https://github.com/dlang/dmd/pull/8195 - https://github.com/dlang/druntime/pull/2376 At least with named arguments, I have the option of writing `destroy!(initialize: false)(foo)`, instead of just `destroy!false(foo)`."...named arguments may be useful, but for the most part, they're useful because a function has way too many parameters, the function should have been designed differently.".It actively encourages a style of "just add another function argument". You start small and as you decide to change your function, it's easy to fall into the trap of adding one more argument, because the end user is free to ignore it.
Feb 07 2020
On 2/6/2020 7:33 PM, Jonathan M Davis wrote:Well, I'll say again that I don't like the idea of having named arguments in the language, because it makes the parameter names part of the API, resulting in yet more bikeshedding and yet another thing that can't be changed without breaking existing code. Once in a while, named arguments may be useful, but for the most part, they're useful because a function has way too many parameters, in which case, the function should have been designed differently. Unfortunately, since it's Walter who created the DIP, and a number of people do like the idea of named arguments, I expect that some form of this will make it in, but I still think that it's a bad idea.I appreciate your thoughts on this. But I like the feature even if all it does is make the "Flag" template obsolete: https://dlang.org/library/std/typecons/flag.html So instead of: foo(Yes.caseSensitive) we'd write: foo(caseSensitive : true) There's no overhead or cognitive load of an extra type, and it doesn't look stupid.
Feb 07 2020
On Saturday, 8 February 2020 at 03:57:56 UTC, Walter Bright wrote:On 2/6/2020 7:33 PM, Jonathan M Davis wrote:Honestly, I like the Flag template ... I think Jonathan have nailed the point:. In my little, I've a PR waiting for months as it breaks a possible derived class of Phobos Socket, as none is marking methods 'final' when it's not intended to be part of the API. And that remember me that, once alone a time, you and Andrei agreed that turning the default to 'final' from 'virtual' was the correct thing to do, specifically for the above point: the default should encourage the writing of a "minimalist" API boundary. Now, I'm all with Jonathan on that, having the parameters name part of the API is just going in the wrong direction related to the above: we are enlarging the possibility of code breakage. Do we want to go further down that road?Well, I'll say again that I don't like the idea of having named arguments in the language, because it makes the parameter names part of the API, resulting in yet more bikeshedding and yet another thing that can't be changed without breaking existing code. Once in a while, named arguments may be useful, but for the most part, they're useful because a function has way too many parameters, in which case, the function should have been designed differently. Unfortunately, since it's Walter who created the DIP, and a number of people do like the idea of named arguments, I expect that some form of this will make it in, but I still think that it's a bad idea.I appreciate your thoughts on this. But I like the feature even if all it does is make the "Flag" template obsolete: https://dlang.org/library/std/typecons/flag.html So instead of: foo(Yes.caseSensitive) we'd write: foo(caseSensitive : true) There's no overhead or cognitive load of an extra type, and it doesn't look stupid.
Feb 08 2020
On 2/8/2020 12:42 AM, Paolo Invernizzi wrote:Now, I'm all with Jonathan on that, having the parameters name part of the API is just going in the wrong direction related to the above: we are enlarging the possibility of code breakage. Do we want to go further down that road?This PR would discourage gratuitous name changes of parameters, just like changing the name of a function causes breakage. The problem is easily avoided - don't change the parameter names. It's not the same thing as changing the behavior.
Feb 08 2020
On Saturday, 8 February 2020 at 08:42:57 UTC, Paolo Invernizzi wrote:I think Jonathan have nailed the point:. In my little, I've a PR waiting for months as it breaks a possible derived class of Phobos Socket, as none is marking methods 'final' when it's not intended to be part of the API. And that remember me that, once alone a time, you and Andrei agreed that turning the default to 'final' from 'virtual' was the correct thing to do, specifically for the above point: the default should encourage the writing of a "minimalist" API boundary.I'm sorry, I need to hammer this in. A nameless API is not minimal. An API is not made more minimal by ignoring the names! The *meaning* of parameters is part of the API! If you have a function DateTime(1, 2, 3), then you already have a function DateTime that takes day, month and year, whether or not you have named parameters! The only difference is that the *meanings* "day", "month" and "year", which are part of the API in either case(!), are attached to the *positions* of the parameters. So now the *positions* of parameters are an irreducible part of the public API. And frankly to me that's a lot worse than having the names being part of it. Names you can at least remember sometimes. Positions are fully arbitrary. Named parameters are just the API being honest about the meaning it *already* carries in its specification, instead of hiding it behind meaningless numbers.
Feb 08 2020
On Friday, February 7, 2020 8:57:56 PM MST Walter Bright via Digitalmars-d wrote:On 2/6/2020 7:33 PM, Jonathan M Davis wrote:That is an upside to it, though I don't think that it's worth having to deal with named arguments in general just get rid of Flag. I confess though that I've always thought that Flag was an unnecessary complication and have only used it because people have been insisting that it's best practice. I never use it in code that isn't in a library that I'm writing for other people to use. If you're familiar with the function, then a naked bool is enough to understand what the function call is doing and no sort of argument name at the call site is necessary. If you aren't familiar with the function, then you should be reading its documentation anyway instead of assuming that you understand what it does based simply on what it's called or what the names of its arguments are. And in that sense, named arguments seem to me like a further excuse to try to claim that you don't need to actually read the documentation to understand what functions do, which ultimately leads to shooting yourself in the foot when you make an assumption that doesn't match the assumptions that the function's author made. - Jonathan M DavisWell, I'll say again that I don't like the idea of having named arguments in the language, because it makes the parameter names part of the API, resulting in yet more bikeshedding and yet another thing that can't be changed without breaking existing code. Once in a while, named arguments may be useful, but for the most part, they're useful because a function has way too many parameters, in which case, the function should have been designed differently. Unfortunately, since it's Walter who created the DIP, and a number of people do like the idea of named arguments, I expect that some form of this will make it in, but I still think that it's a bad idea.I appreciate your thoughts on this. But I like the feature even if all it does is make the "Flag" template obsolete: https://dlang.org/library/std/typecons/flag.html So instead of: foo(Yes.caseSensitive) we'd write: foo(caseSensitive : true) There's no overhead or cognitive load of an extra type, and it doesn't look stupid.
Feb 11 2020
On Wednesday, 12 February 2020 at 05:03:49 UTC, Jonathan M Davis wrote:If you're familiar with the function, then a naked bool is enough to understand what the function call is doing and no sort of argument name at the call site is necessary. If you aren't familiar with the function, then you should be reading its documentation anyway instead of assuming that you understand what it does based simply on what it's called or what the names of its arguments are.This strikes me as a false dichotomy, in two ways. 1) It's entirely possible to be familiar enough with a function to understand what it does, but not so familiar that you have every detail of its parameter list memorized. For example, if I see `stdin.byLine(true)`, I may remember that the boolean argument has to do with whether it keeps or drops newlines, but not be sure which behavior `true` corresponds to. `stdin.byLine(keepTerminator: true)` makes it immediately obvious. 2) While function and argument names certainly communicate *less* information than documentation does, the amount they communicate is not zero. For example, if I'm reading some code in an unfamiliar language, and I see something like `Math.abs(x)`, I have a pretty good idea what that means even without looking at the documentation, because the name refers to an existing piece of background knowledge I possess. Names can't tell you everything, of course. If you need to know more, you can (and should) refer to the documentation, or failing that, the source code. But sometimes, you don't need to know everything, and in those situations, being able to get what you need from names is far more convenient than having to search the documentation every time.
Feb 11 2020
On Wednesday, 12 February 2020 at 05:03:49 UTC, Jonathan M Davis wrote:On Friday, February 7, 2020 8:57:56 PM MST Walter Bright via Digitalmars-d wrote:Named arguments is the difference between spending 1 second looking at this: makeWindow(x: 67, y: 98, width: 100, height: 100) Or taking about 1 to 5 minutes depending on how easy documentation is to find, and how bored you are to figure out what this is doing: makeWindow(67, 98, 100, 100) The 1 to 5 minutes is guesstimate work. But there's a lot of research out there about human task behavior. E.g. you have about 2-3 minutes of someone's attention before you switch tasks. It can take anywhere from a minute to 20 to get back to what you were doing after a context switch. Looking up and searching for documentation unnecessarily is most certainly a context switch. Add the fact that many libraries do not have documentation or poor documentation, that means browsing the source code. Throw in attention spans and anything you can do to make code readable/reviewable is a huge win to productivity. Unless you're a lone programmer working on your own project consistently this doesn't apply. But even then if you switch between projects it does, because there's no way you're remember what every bool or int parameter does. Coding in the professional world is mostly social. The languages that make it more social and help that aspect will win the long game.On 2/6/2020 7:33 PM, Jonathan M Davis wrote:That is an upside to it, though I don't think that it's worth having to deal with named arguments in general just get rid of Flag. I confess though that I've always thought that Flag was an unnecessary complication and have only used it because people have been insisting that it's best practice. I never use it in code that isn't in a library that I'm writing for other people to use. If you're familiar with the function, then a naked bool is enough to understand what the function call is doing and no sort of argument name at the call site is necessary. If you aren't familiar with the function, then you should be reading its documentation anyway instead of assuming that you understand what it does based simply on what it's called or what the names of its arguments are. And in that sense, named arguments seem to me like a further excuse to try to claim that you don't need to actually read the documentation to understand what functions do, which ultimately leads to shooting yourself in the foot when you make an assumption that doesn't match the assumptions that the function's author made.Well, I'll say again that I don't like the idea of having named arguments in the language, because it makes the parameter names part of the API, resulting in yet more bikeshedding and yet another thing that can't be changed without breaking existing code. Once in a while, named arguments may be useful, but for the most part, they're useful because a function has way too many parameters, in which case, the function should have been designed differently. Unfortunately, since it's Walter who created the DIP, and a number of people do like the idea of named arguments, I expect that some form of this will make it in, but I still think that it's a bad idea.I appreciate your thoughts on this. But I like the feature even if all it does is make the "Flag" template obsolete: https://dlang.org/library/std/typecons/flag.html So instead of: foo(Yes.caseSensitive) we'd write: foo(caseSensitive : true) There's no overhead or cognitive load of an extra type, and it doesn't look stupid.- Jonathan M Davis
Feb 11 2020
On Wednesday, 12 February 2020 at 07:42:32 UTC, aliak wrote:Named arguments is the difference between spending 1 second looking at this: makeWindow(x: 67, y: 98, width: 100, height: 100) Or taking about 1 to 5 minutes depending on how easy documentation is to find, and how bored you are to figure out what this is doing: makeWindow(67, 98, 100, 100)You're using an example in favor of a point, because it's hard to someone use constants for this kind of thing for a production code, at least for obvious reasons it shouldn't. Now let's compare:makeWindow(x: 67, y: 98, width: 100, height: 100)With: makeWindow(x, y, width, height); Of course 'x', 'y', 'width' and 'height' are variables defined elsewhere, but it's less noisy. Now to be honest I would prefer for this particular function to use a struct like "myWindow" to define the coordinates: makeWindow(myWindow); I barely use name parameters for languages that support and to be honest I barely see than in other codes. IDE are pretty much advanced these days, and if I need to check out at least in VS it shows me everything that I need about the arguments (Names, Types...). Sasha.
Feb 12 2020
On 2/12/20 2:44 PM, SashaGreat wrote:On Wednesday, 12 February 2020 at 07:42:32 UTC, aliak wrote:I agree with you! But it depends on the situation. I'll embelish with something else. Let's say that you have variables for some and you want to put in literals for others, which do you prefer? makeWindow(67, 98, width, height) or makeWindow(x: 67, y: 98, width, height) You see, you can use named parameters when it makes sense, and not when it doesn't. I think this is really just a greater mechanism to make calls more self-documenting, and code much easier to read and understand.Named arguments is the difference between spending 1 second looking at this: makeWindow(x: 67, y: 98, width: 100, height: 100) Or taking about 1 to 5 minutes depending on how easy documentation is to find, and how bored you are to figure out what this is doing: makeWindow(67, 98, 100, 100)You're using an example in favor of a point, because it's hard to someone use constants for this kind of thing for a production code, at least for obvious reasons it shouldn't. Now let's compare:makeWindow(x: 67, y: 98, width: 100, height: 100)With: makeWindow(x, y, width, height); Of course 'x', 'y', 'width' and 'height' are variables defined elsewhere, but it's less noisy.Now to be honest I would prefer for this particular function to use a struct like "myWindow" to define the coordinates: makeWindow(myWindow);This is just named parameters with extra types needed. Same as the Flag case. Removing all that cruft from the library and language is a net-win. And it doesn't help when you want to use expressions to generate new parameters -- the code is going to be ugly because you first have to construct a typeof(myWindow).I barely use name parameters for languages that support and to be honest I barely see than in other codes.My second most used language is Swift, which requires named parameters. There are some cool things you can do with function and parameter names when they are significant. I think it's going to be a net benefit. We just have to resolve the introspection issue. -Steve
Feb 12 2020
On Wednesday, 12 February 2020 at 20:11:14 UTC, Steven Schveighoffer wrote:My second most used language is Swift, which requires named parameters. There are some cool things you can do with function and parameter names when they are significant. I think it's going to be a net benefit. We just have to resolve the introspection issue.Since I never used named arguments, I mean I never opted to and since you have, can you share about the problems, because it must have some problems, changing the names will cause problem, but how this happen in production? Like I said above I'm curious about this feature, and why C/C++ which have a bigger user base never bothered about adding this feature. Sasha.
Feb 12 2020
On Wednesday, 12 February 2020 at 21:53:32 UTC, Sasha wrote:Like I said above I'm curious about this feature, and why C/C++ which have a bigger user base never bothered about adding this feature. Sasha.The only official, publicly-available information I could find on this [1] is frustratingly vague, but I did stumble across a reddit thread [2] that discusses some of the potential issues. One is that different implementations of the C and C++ standard libraries can (and do) use different parameter names for the same functions. Unless those names were standardized, any code that called such functions using named arguments would not be portable among different implementations. In D, this is not a problem, because there is only one implementation of Phobos and Druntime, so the names are de-facto standardized already. [1] [2] https://www.reddit.com/r/cpp/comments/5mdes5/what_happened_to_the_named_parameter_proposal/
Feb 12 2020
On 2/12/20 4:53 PM, Sasha wrote:On Wednesday, 12 February 2020 at 20:11:14 UTC, Steven Schveighoffer wrote:Swift is notorious for making breaking changes, including function and parameter names (which are technically part of the function name), but provides generally a rich tool in xcode to upgrade your code to deal with the differences. Of course, it's not always perfect. I was pissed when they removed for loops without providing a replacement. But renaming of function names AND parameters is handled quite easily. It is definitely a difference for a language that has had named parameters from the beginning vs. one that suddenly allows that. The mentality is different and the care for parameter names is different. If this DIP is accepted, I expect some growing pains, but it should be pretty much fine pretty quickly IMO.My second most used language is Swift, which requires named parameters. There are some cool things you can do with function and parameter names when they are significant. I think it's going to be a net benefit. We just have to resolve the introspection issue.Since I never used named arguments, I mean I never opted to and since you have, can you share about the problems, because it must have some problems, changing the names will cause problem, but how this happen in production?Like I said above I'm curious about this feature, and why C/C++ which have a bigger user base never bothered about adding this feature.There's lots of useful things C/C++ could add that they haven't. The bar to cross for C++ new features is going to be a difficult threshold for any feature, including named parameters, regardless of the utility or benefits. They just don't like to change much. I don't know that I would ascribe some inherent problem with named parameters as the cause of it not being in C++, or really any language. Changing a language always has to be worth it to the maintainers, and opinions on this feature differ widely even here. -Steve
Feb 13 2020
On Wednesday, 12 February 2020 at 19:44:52 UTC, SashaGreat wrote:On Wednesday, 12 February 2020 at 07:42:32 UTC, aliak wrote:You could use variables to make it look nicer at the call-side, but the downside is there's no guarantee that those variable names have any relation to the names of the parameters. For example, this would still compile: makeWindow(x, width, y, height); This problem can't happen with named arguments. Named arguments also saves you if the function arguments change names/meaning, i.e. ORIGINAL: void makeWindow(int x, int y, int width, int height) MODIFIED: void makeWindow(int left, int top, int right, int bottom); The version that doesn't use named arguments will still compile and run: makeWindow(x, y, width, height); But named arguments would catch the problem at compile-time: makeWindow(x: 67, y: 98, width: 100, height: 100); // error no argument named 'x', 'y', 'width', 'height'Named arguments is the difference between spending 1 second looking at this: makeWindow(x: 67, y: 98, width: 100, height: 100) Or taking about 1 to 5 minutes depending on how easy documentation is to find, and how bored you are to figure out what this is doing: makeWindow(67, 98, 100, 100)You're using an example in favor of a point, because it's hard to someone use constants for this kind of thing for a production code, at least for obvious reasons it shouldn't. Now let's compare:makeWindow(x: 67, y: 98, width: 100, height: 100)With: makeWindow(x, y, width, height);
Feb 12 2020
On Wednesday, 12 February 2020 at 21:11:12 UTC, Jonathan Marler wrote:You could use variables to make it look nicer at the call-side, but the downside is there's no guarantee that those variable names have any relation to the names of the parameters. For example, this would still compile: makeWindow(x, width, y, height); This problem can't happen with named arguments. Named arguments also saves you if the function arguments change names/meaning, i.e. ORIGINAL: void makeWindow(int x, int y, int width, int height) MODIFIED: void makeWindow(int left, int top, int right, int bottom); The version that doesn't use named arguments will still compile and run: makeWindow(x, y, width, height); But named arguments would catch the problem at compile-time: makeWindow(x: 67, y: 98, width: 100, height: 100); // error no argument named 'x', 'y', 'width', 'height'OK, now let's see a problem with named arguments, imagine this: makeWindow(x, y, width, height); You can call this function like: makeWindow(x: 67, y: 98, width: 100, height: 100); // Name Arguments makeWindow(67, 98, 100, 100); // Constants makeWindow(x, y, width, height); // Variables So far so good, but later someone decides to rename some parameters to: makeWindow(posx, posy, width, height); // Note: x => posx and y => posy makeWindow(x: 67, y: 98, width: 100, height: 100); // Ops not working anymore! makeWindow(67, 98, 100, 100); // Constants still works makeWindow(x, y, width, height); // Variables Still works What I mean is that we need to balance this better, you showed a defect without Named Arguments and I'm showing a problem with. But one thing that called my attention is that for what I see C++ doesn't has this feature, and proposes were rejected because the problems that would be created with this feature. Sasha.
Feb 12 2020
On Wednesday, 12 February 2020 at 21:47:12 UTC, Sasha wrote:But one thing that called my attention is that for what I see C++ doesn't has this feature, and proposes were rejected because the problems that would be created with this feature. Sasha.Which pretty much doesn't exist in the existing languages that At most you just add a note in release notes about the functions being renamed. I could see it an issue in dynamic languages like Python, because such a change could pass silently and then crash your program in runtime. But in D it just wouldn't compile, so it's an easy fix.
Feb 12 2020
On Wednesday, 12 February 2020 at 21:47:12 UTC, Sasha wrote:On Wednesday, 12 February 2020 at 21:11:12 UTC, Jonathan Marler wrote:My point was the the error is caught at compile-time rather than runtime, which I think is a pro in the named arguments column. That being said, the issue you brought up with named arguments is a valid issue and would be my biggest argument against them. They dramatically increase the surface area of the API which will lead to more breakage between libraries. For this reason and the fact that I think named arguments are only useful in a minority of cases (maybe 25%?) I think it would be better to make named arguments "opt-in" so that each library can choose when to make their parameter names apart of their API.You could use variables to make it look nicer at the call-side, but the downside is there's no guarantee that those variable names have any relation to the names of the parameters. For example, this would still compile: makeWindow(x, width, y, height); This problem can't happen with named arguments. Named arguments also saves you if the function arguments change names/meaning, i.e. ORIGINAL: void makeWindow(int x, int y, int width, int height) MODIFIED: void makeWindow(int left, int top, int right, int bottom); The version that doesn't use named arguments will still compile and run: makeWindow(x, y, width, height); But named arguments would catch the problem at compile-time: makeWindow(x: 67, y: 98, width: 100, height: 100); // error no argument named 'x', 'y', 'width', 'height'OK, now let's see a problem with named arguments, imagine this: makeWindow(x, y, width, height); You can call this function like: makeWindow(x: 67, y: 98, width: 100, height: 100); // Name Arguments makeWindow(67, 98, 100, 100); // Constants makeWindow(x, y, width, height); // Variables So far so good, but later someone decides to rename some parameters to: makeWindow(posx, posy, width, height); // Note: x => posx and y => posy makeWindow(x: 67, y: 98, width: 100, height: 100); // Ops not working anymore! makeWindow(67, 98, 100, 100); // Constants still works makeWindow(x, y, width, height); // Variables Still works What I mean is that we need to balance this better, you showed a defect without Named Arguments and I'm showing a problem with. But one thing that called my attention is that for what I see C++ doesn't has this feature, and proposes were rejected because the problems that would be created with this feature. Sasha.
Feb 12 2020
On 2/11/2020 11:42 PM, aliak wrote:Or taking about 1 to 5 minutes depending on how easy documentation is to find, and how bored you are to figure out what this is doing:As an aside, this is why I encourage URLs to be put right in the source code with links to relevant information like bugzilla issues, spec pages, API documentation, etc.
Feb 12 2020
On Friday, 7 February 2020 at 03:33:26 UTC, Jonathan M Davis wrote:Well, I'll say again that I don't like the idea of having named arguments in the language, because it makes the parameter names part of the API, resulting in yet more bikeshedding and yet another thing that can't be changed without breaking existing code. Once in a while, named arguments may be useful, but for the most part, they're useful because a function has way too many parameters, in which case, the function should have been designed differently.I am in definitely in favor of named arguments in the language. Overall I think the benefits of this specific DIP proposal outweigh the negatives identified. That said, having parameter names automatically become part of a function's API is a meaningful downside. (Specifically, that a parameter name cannot be changed without risk of breaking existing callers.) The reasons are likely self-evident, but to spell out my thoughts: * Additional design time when initially creating functions (good names are hard). * More time required from code reviewers (both open-source and corporate). * Barrier to incrementally improving a function (and documentation) over-time by improving the quality of the parameter names. The above are more reflective of waterfall than an agile approach, a disadvantage in situations where a more iterative development style is preferable. Another part of the equation is simply that when I'm developing a function, I usually have a pretty good idea whether named arguments are going to be a material benefit. In those cases I'm willing to spend time on the quality of the names. I do think the benefits of the DIP outweigh this concern. However, if there is a reasonable way to allow the developer of a function to control whether the function can invoked via named arguments that would be an enhancement worth considering. This control need not be at the level of each individual parameter. It could be at the function level. --Jon
Feb 08 2020
On Sunday, 9 February 2020 at 00:56:15 UTC, Jon Degenhardt wrote:(Specifically, that a parameter name cannot be changed without risk of breaking existing callers.)Does it change your view at all that parameter names are *already public* per both spec and reality and have been for a long, long time? (my web.d framework used their availability as early as 2012ish) https://dlang.org/spec/expression.html#IsExpression "the parameter sequence of a function, delegate, or function pointer. This includes the parameter types, names, and default values." And, of course, documentation though that isn't strictly part of the compiler breakage.
Feb 08 2020
On Sunday, 9 February 2020 at 01:07:03 UTC, Adam D. Ruppe wrote:On Sunday, 9 February 2020 at 00:56:15 UTC, Jon Degenhardt wrote:Probably not, but let me give some thoughts and ask a clarifying question. Main thing - As a pragmatic matter, I'd expect it to be much more likely that named argument invocation would be a source of breakage than usage arising from introspection. Related - There is significant difference between parameter names being public and having the names be sources of backward compatibility in function calls. Now my question - I know function parameters names can be retrieved by type introspection. What I don't know is the ways those names can be used such that programs can break if a parameter names change. Can you give some examples?(Specifically, that a parameter name cannot be changed without risk of breaking existing callers.)Does it change your view at all that parameter names are *already public* per both spec and reality and have been for a long, long time? (my web.d framework used their availability as early as 2012ish) https://dlang.org/spec/expression.html#IsExpression "the parameter sequence of a function, delegate, or function pointer. This includes the parameter types, names, and default values." And, of course, documentation though that isn't strictly part of the compiler breakage.
Feb 08 2020
On Sunday, 9 February 2020 at 01:47:35 UTC, Jon Degenhardt wrote:Now my question - I know function parameters names can be retrieved by type introspection. What I don't know is the ways those names can be used such that programs can break if a parameter names change. Can you give some examples?We can do named parameters in a library already, something like: void func(int param) { } int item; callNamed!(func, param => item)(); // possible today. It pulls param name of func and from the given lambda to match up the item. If func's param name were to change, that callNamed would fail, just like with this dip. Of course since the syntax is weird and you need to import a lib... I never use this thing and I doubt anyone else does either. (I can't even find my implementation right now, though I know I have it somewhere). I do use it extensively for runtime things though like generating command line parsers and web apis which can break, but that's expected on that interface anyway so of course I design for it. But my policy on breakage though is I avoid it... unless I specifically mention in the documentation that you can't rely on it. Then if you do, that's your problem. So if I didn't want to do reliable names, I'd just do /// $(WARNING the parameter names are NOT stable and may change without notice. ) and then there we go, disclaimer of liability :)
Feb 08 2020
On Sunday, 9 February 2020 at 02:03:42 UTC, Adam D. Ruppe wrote:On Sunday, 9 February 2020 at 01:47:35 UTC, Jon Degenhardt wrote:That's a useful example, thanks! It doesn't change my overall opinion though. I like the DIP, even this downside. However, it would be an improvement if there was a way for the developer of a function to disable named parameter invocation. Or perhaps a way to discourage it, for example, a compile-time warning about no-backward compatibility for parameter names.Now my question - I know function parameters names can be retrieved by type introspection. What I don't know is the ways those names can be used such that programs can break if a parameter names change. Can you give some examples?We can do named parameters in a library already, something like: void func(int param) { } int item; callNamed!(func, param => item)(); // possible today. It pulls param name of func and from the given lambda to match up the item. If func's param name were to change, that callNamed would fail, just like with this dip.
Feb 08 2020
On Sunday, 9 February 2020 at 02:15:36 UTC, Jon Degenhardt wrote:Or perhaps a way to discourage it, for example, a compile-time warning about no-backward compatibility for parameter names.I would kinda love user-defined warnings. pragma(msg) comes close sometimes but there is no way to conditionally trigger it. (You can sort of conditionally disable via `version()` though.) Of course, you could just name your parameters `_randomNameYouReallyDontWantToUse_like_seriously_dont_rely_on_this_name_lol` :P A reasonable thing for the compiler to do btw would be to call out when function names change. Suppose you have: foo(bar: 1, baz: 4) and later you change the signature to foo(int bar, int coolness) the compiler could reasonably issue an error: error: foo has no parameter named `baz`. Did you mean `coolness`? based on process of elimination to suggest the names not yet specified to ease transition.
Feb 08 2020
On 09.02.20 03:31, Adam D. Ruppe wrote:On Sunday, 9 February 2020 at 02:15:36 UTC, Jon Degenhardt wrote:int justDoThis(int,int){ return _param_0+_param_1; }Or perhaps a way to discourage it, for example, a compile-time warning about no-backward compatibility for parameter names.I would kinda love user-defined warnings. pragma(msg) comes close sometimes but there is no way to conditionally trigger it. (You can sort of conditionally disable via `version()` though.) Of course, you could just name your parameters `_randomNameYouReallyDontWantToUse_like_seriously_dont_rely_on_this_name_lol` :P
Feb 11 2020
On 2/8/2020 6:31 PM, Adam D. Ruppe wrote:I would kinda love user-defined warnings. pragma(msg) comes close sometimes but there is no way to conditionally trigger it.static if (condition) pragma(msg, "Look, Ma!"); Or static assert().A reasonable thing for the compiler to do btw would be to call out when function names change. Suppose you have: foo(bar: 1, baz: 4) and later you change the signature to foo(int bar, int coolness) the compiler could reasonably issue an error: error: foo has no parameter named `baz`. Did you mean `coolness`? based on process of elimination to suggest the names not yet specified to ease transition.Note that the compiler already uses a spell checker to look for close symbol matches.
Feb 12 2020
On Thursday, 13 February 2020 at 01:37:58 UTC, Walter Bright wrote:static if (condition) pragma(msg, "Look, Ma!");In this context, the condition there would be someone using the parameter names. That's impossible to find in static if.Note that the compiler already uses a spell checker to look for close symbol matches.A spell checker wouldn't necessarily catch a name change like this since the distance between old and new name may be significant. (e.g. ms to milliseconds has an edit distance of ... what, 11?) The current spell checker doesn't do it: int milliseconds() { return 0; } void main() { int a = ms(); } // wer.d(4): Error: undefined identifier ms // note no suggestion given But since the number of parameters is so limited, process of elimination means even with a very large edit distance, it is still probable that you meant one of the few missing parameters. Like dmd will right now suggest: wer.d(4): Error: function wer.milliseconds(int ms) is not callable using argument types () So a natural extension of this could be given named argument `milliseconds` does not match any parameter And just those two messages next to each other, spell check or no, would probably clue the user in. I doubt this will even need additional code, but nevertheless, given the importance of good error messages to user productivity, I think all DIPs ought to have a section on diagnostics and any implementation should ensure it is addressed one way or another.
Feb 12 2020
On 2/12/2020 6:00 PM, Adam D. Ruppe wrote:And just those two messages next to each other, spell check or no, would probably clue the user in. I doubt this will even need additional code, but nevertheless, given the importance of good error messages to user productivity, I think all DIPs ought to have a section on diagnostics and any implementation should ensure it is addressed one way or another.It's a good idea, but I've found it to be pragmatic to not worry much about error message quality during the initial implementation, just focus on getting the semantics right. (Doing great error messages often is a significant increase in complexity.) Having some experience with the kinds of mistakes people tend to make (and it isn't random) helps a lot to guide error message development. Hence is it something for the future, and is premature to add in the DIP for the feature. Doing it later also would not require a DIP. Good error messages are always a work in progress.
Feb 13 2020
On 2/8/20 8:47 PM, Jon Degenhardt wrote:On Sunday, 9 February 2020 at 01:07:03 UTC, Adam D. Ruppe wrote:If you name your parameters something unintuitive, like "a". Likely nobody is going to use them via named parameters. For example, if you have; Date makeDate(int year, int month, int day) What would be the reason to change these? Likely you already picked those names. But if you named them: Date makeDate(int a, int b, int c) Now, changing it to the more appropriate names as above would be technically a "breaking change". But who cares? Nobody is writing makeDate(b: 1, c: 2, a: 3), and if they are, they deserve broken code IMO. I don't think there's going to be a lot of problems here. Take a look at the history of phobos and see if you can find places where someone changed an appropriate parameter name to another appropriate name. Chances are it's close to never. And even if it was changed, is the change something that would have to be made? Was the original parameter name so bad that it needed changing in light of the code breakage that would now take place? The one annoying downside is that there is no possibly way to deprecate this. You can't have: deprecated("use better names please") Date makeDate(int a, int b, int c) Date makeDate(int year, int month, int day) This is one huge departure from current mechanisms. -SteveOn Sunday, 9 February 2020 at 00:56:15 UTC, Jon Degenhardt wrote:Probably not, but let me give some thoughts and ask a clarifying question. Main thing - As a pragmatic matter, I'd expect it to be much more likely that named argument invocation would be a source of breakage than usage arising from introspection. Related - There is significant difference between parameter names being public and having the names be sources of backward compatibility in function calls.(Specifically, that a parameter name cannot be changed without risk of breaking existing callers.)Does it change your view at all that parameter names are *already public* per both spec and reality and have been for a long, long time? (my web.d framework used their availability as early as 2012ish) https://dlang.org/spec/expression.html#IsExpression "the parameter sequence of a function, delegate, or function pointer. This includes the parameter types, names, and default values." And, of course, documentation though that isn't strictly part of the compiler breakage.
Feb 08 2020
On Sunday, 9 February 2020 at 02:40:30 UTC, Steven Schveighoffer wrote:On 2/8/20 8:47 PM, Jon Degenhardt wrote:Well, I personally wouldn't recommend this as a general remedy. Parameter names help to document the implementation. In many environments it's important that developers other than the original author be able to read, debug, enhance, or take over code. Having good parameter and variable names is helpful from this perspective. Naming conventions are a common element of coding standards for this reason. In general, what I typically try to do (and recommend) is taking a good shot at creating meaningful names, but not spend excessive amounts of time on it. And, depending the situation, look at improving the names over time (and other elements of the code as well).On Sunday, 9 February 2020 at 01:07:03 UTC, Adam D. Ruppe wrote:[...snip...] If you name your parameters something unintuitive, like "a". Likely nobody is going to use them via named parameters. For example, if you have; Date makeDate(int year, int month, int day) What would be the reason to change these? Likely you already picked those names. But if you named them: Date makeDate(int a, int b, int c)On Sunday, 9 February 2020 at 00:56:15 UTC, Jon Degenhardt wrote:(Specifically, that a parameter name cannot be changed without risk of breaking existing callers.)I don't think there's going to be a lot of problems here. Take a look at the history of phobos and see if you can find places where someone changed an appropriate parameter name to another appropriate name. Chances are it's close to never.For Phobos this would be my expectation as well. I'm admittedly thinking of project environments with meaningful size teams more than the standard library of a major programming language. Environments where there is a fair bit of code in earlier stages of development and subject to more evolution.
Feb 08 2020
On 2/8/20 11:10 PM, Jon Degenhardt wrote:For Phobos this would be my expectation as well. I'm admittedly thinking of project environments with meaningful size teams more than the standard library of a major programming language. Environments where there is a fair bit of code in earlier stages of development and subject to more evolution.I think the evolution goes like this: void foo(int tmpName); ... // all callers: foo(5); // didn't use named parameters because I have no idea what "tmpName" means now, we evolve foo: void foo(int milliseconds); Now, all calls still work because nobody used the bad name as "documentation". New calls now use the name sometimes because it's helpful. My point is simply that the name itself is going to not require, but probably result in, people using or not using the name. Bad names naturally aren't going to get name usage, because they suck and aren't helpful. Good names are. I understand though, there are possible bikeshed problems here. For example, someone who implements foo might be tired of typing out "milliseconds" and change the parameter name to "ms". Now that person has to worry about what happens for callers. So instead he has to leave milliseconds in the name, and create a temporary ms in his function. At that point, you have to weigh how important it is to change that parameter name against the breakage that might occur. How much does it cost to repaint the shed? Might not be worth it. Note that Swift (which has parameter names as part of the function name) has a mechanism to deal with this. A function in swift looks like: func foo(a : int) -> Void You MUST call the function with foo(a: 5). foo(5) doesn't work. But you can name the parameter to the outside and name the parameter differently on the inside: func foo(milliseconds a: int) -> Void Now, you call the function with foo(milliseconds: 5), and inside the function, the parameter is named 'a'. Not sure this could be doable in D. But for a main language that started out with significant naming of parameters (inheriting this from objective-C), it's a good place to look for inspiration here. -Steve
Feb 09 2020
On Sunday, 9 February 2020 at 18:32:45 UTC, Steven Schveighoffer wrote:Now, you call the function with foo(milliseconds: 5), and inside the function, the parameter is named 'a'.We can always just `alias a = milliseconds;` inside the function. Changing inside alone is easy, though changing the outside one is a bit trickier. We can't overload on name alone so no way to use function-level `deprecated` messages. But maybe a pragma or deprecated alias syntax on names could be enough. Users changing is easy too, just the lib implementer wanting to provide some range of compatibility would probably want the deprecated alias to keep working for a while. So we might consider adding such a thing. void foo(int milliseconds deprecated alias ms) {} wow ugly syntax lol but i think the grammar would allow that and now the param has two names for inside and outside and gives a place for us to put a message. but i kinda suggest just not worrying about it until experience proves this is a real problem that needs to be solved.
Feb 09 2020
On 2/9/20 1:45 PM, Adam D. Ruppe wrote:On Sunday, 9 February 2020 at 18:32:45 UTC, Steven Schveighoffer wrote:Agree with all of this. -SteveNow, you call the function with foo(milliseconds: 5), and inside the function, the parameter is named 'a'.We can always just `alias a = milliseconds;` inside the function. Changing inside alone is easy, though changing the outside one is a bit trickier. We can't overload on name alone so no way to use function-level `deprecated` messages. But maybe a pragma or deprecated alias syntax on names could be enough. Users changing is easy too, just the lib implementer wanting to provide some range of compatibility would probably want the deprecated alias to keep working for a while. So we might consider adding such a thing. void foo(int milliseconds deprecated alias ms) {} wow ugly syntax lol but i think the grammar would allow that and now the param has two names for inside and outside and gives a place for us to put a message. but i kinda suggest just not worrying about it until experience proves this is a real problem that needs to be solved.
Feb 09 2020
On Sunday, 9 February 2020 at 18:32:45 UTC, Steven Schveighoffer wrote:But you can name the parameter to the outside and name the parameter differently on the inside: func foo(milliseconds a: int) -> Void Now, you call the function with foo(milliseconds: 5), and inside the function, the parameter is named 'a'. Not sure this could be doable in D. But for a main language that started out with significant naming of parameters (inheriting this from objective-C), it's a good place to look for inspiration here. -SteveYou can alias the parameter inside the function: void foo(int milliseconds) { alias ms = milliseconds; // Use 'ms' from here on // ... }
Feb 09 2020
On 2/9/2020 10:32 AM, Steven Schveighoffer wrote:Not sure this could be doable in D. But for a main language that started out with significant naming of parameters (inheriting this from objective-C), it's a good place to look for inspiration here.Since parameter names are not part of the name mangling, you can do things like: ---- A.di void foo(int x); ---- A.d void foo(int y) { ... } And, of course, you can also do: ---- A.di void foo(int); ---- A.d void foo(int y) { ... }
Feb 09 2020
On Sunday, 9 February 2020 at 18:32:45 UTC, Steven Schveighoffer wrote:On 2/8/20 11:10 PM, Jon Degenhardt wrote:Yes, this is representative of what I had in mind. Another is changes in the ambiguity of a name. As an example, assume 'height' is an important element of a number of calculations in a system. Early on there is no ambiguity about what 'height' means. The word 'height' gets used in the names of functions, parameters, variables, etc. Then use cases arise where it is important to distinguish interior and exterior heights, so names like 'interiorHeight' and 'exteriorHeight' are preferable. Over time the name 'height' by itself becomes more and more ambiguous. Any place the name 'height' is exposed in a manner that other code becomes dependent on the name is a source of technical debt. Often this form of technical debt just happens. It's hard to predict these changes. But developers often do spend time thinking about forward compatibility of names that are part of a public API contract. This DIP will increase this surface area. As I said, I don't think this is a deal breaker for the DIP. I think it is a positive change even with this downside. My only recommendation is to consider whether there are mechanisms that can help reduce this form technical debt, without requiring material additional developer time when initially writing code. My thought was to allow explicit expression by the developer of whether a function was intended for named argument invocation (several possibilities). But there may be other approaches to achieving the same goal. For example, considering what Swift does:For Phobos this would be my expectation as well. I'm admittedly thinking of project environments with meaningful size teams more than the standard library of a major programming language. Environments where there is a fair bit of code in earlier stages of development and subject to more evolution.I think the evolution goes like this: void foo(int tmpName); ... // all callers: foo(5); // didn't use named parameters because I have no idea what "tmpName" means now, we evolve foo: void foo(int milliseconds); Now, all calls still work because nobody used the bad name as "documentation". New calls now use the name sometimes because it's helpful. My point is simply that the name itself is going to not require, but probably result in, people using or not using the name. Bad names naturally aren't going to get name usage, because they suck and aren't helpful. Good names are. I understand though, there are possible bikeshed problems here. For example, someone who implements foo might be tired of typing out "milliseconds" and change the parameter name to "ms". Now that person has to worry about what happens for callers. So instead he has to leave milliseconds in the name, and create a temporary ms in his function. At that point, you have to weigh how important it is to change that parameter name against the breakage that might occur. How much does it cost to repaint the shed? Might not be worth it.Note that Swift (which has parameter names as part of the function name) has a mechanism to deal with this. [... details excluded... ] Not sure this could be doable in D. But for a main language that started out with significant naming of parameters (inheriting this from objective-C), it's a good place to look for inspiration here.This is very nice callout. Even if it cannot be done in D just putting it consideration set is worthwhile. Also, several people have pointed out that aliasing parameter names within functions can help with these cases. I agree. It doesn't completely address the issue, but it is helpful, and a tool I hadn't thought of. --Jon
Feb 09 2020
On Sunday, 9 February 2020 at 21:05:43 UTC, Jon Degenhardt wrote:As an example, assume 'height' is an important element of a number of calculations in a system. Early on there is no ambiguity about what 'height' means. The word 'height' gets used in the names of functions, parameters, variables, etc. Then use cases arise where it is important to distinguish interior and exterior heights, so names like 'interiorHeight' and 'exteriorHeight' are preferable. Over time the name 'height' by itself becomes more and more ambiguous. Any place the name 'height' is exposed in a manner that other code becomes dependent on the name is a source of technical debt. Often this form of technical debt just happens. It's hard to predict these changes. But developers often do spend time thinking about forward compatibility of names that are part of a public API contract. This DIP will increase this surface area. As I said, I don't think this is a deal breaker for the DIP. I think it is a positive change even with this downside. My only recommendation is to consider whether there are mechanisms that can help reduce this form technical debt, without requiring material additional developer time when initially writing code.I feel like this increase in surface area is actually straightforwardly a good thing. Even if the parameter is not used as a named parameter, we are seeing a shift in the meaning of the parameter as understood by the caller. With the DIP, this change in meaning will necessarily lead to a reevaluation of the callsite and clarification of whether you meant interiorHeight or exteriorHeight. With the current state of affairs, absent a change in type, there is absolutely no indication to the caller that their call has become ambiguous. Again, the thing that is happening here is a drift in meaning, which is *already* a breaking change of the API. The language has simply previously allowed developers to obfuscate and ignore this fact. Inasmuch as this DIP makes this more difficult, it's a benefit, not a drawback.
Feb 09 2020
On 10/02/2020 7:32 AM, Steven Schveighoffer wrote:Not sure this could be doable in D. But for a main language that started out with significant naming of parameters (inheriting this from objective-C), it's a good place to look for inspiration here.Alternatively support implicit construction of structs as parameters i.e. void foo(Nullable!int ms); foo(ms: 3); You have to do some mapping internally but it means even if you deprecate a name, you can still keep the old ones.
Feb 09 2020
On Monday, 10 February 2020 at 02:25:07 UTC, rikki cattermole wrote:On 10/02/2020 7:32 AM, Steven Schveighoffer wrote:This sounds like a good unification between struct initialization and named arguments. So to "enable" named arguments, one would simply declare a struct like this: struct BufferCreateInfo { const(char)* type; size_t size; } and then use the struct type in a function argument list: Buffer createBuffer(BufferCreateInfo info); and call it like this: auto buffer = createBuffer({ type: "BufferType", size: 16 }); // or createBuffer(type: "BufferType", size: 16) for syntax sugar or if you want mixed named and non-named arguments: Buffer createBuffer(BufferCreateInfo info, size_t howMany); // createBuffer(type: "BufferType", size: 16, 10); The only change is allowing struct construction on a function parameter, then maybe take it a step further by eliminating the curly braces in function calls. But I don't know anything about compilers...Not sure this could be doable in D. But for a main language that started out with significant naming of parameters (inheriting this from objective-C), it's a good place to look for inspiration here.Alternatively support implicit construction of structs as parameters i.e. void foo(Nullable!int ms); foo(ms: 3); You have to do some mapping internally but it means even if you deprecate a name, you can still keep the old ones.
Feb 09 2020
On 10/02/2020 5:31 PM, rb3 wrote:On Monday, 10 February 2020 at 02:25:07 UTC, rikki cattermole wrote:That is not what I suggested. What I suggested was given a single argument, automatically construct+call the constructor on a struct as defined in a parameter. It is a 1 to 1 rewrite and would be very simple to do.On 10/02/2020 7:32 AM, Steven Schveighoffer wrote:This sounds like a good unification between struct initialization and named arguments. So to "enable" named arguments, one would simply declare a struct like this: struct BufferCreateInfo { const(char)* type; size_t size; } and then use the struct type in a function argument list: Buffer createBuffer(BufferCreateInfo info); and call it like this: auto buffer = createBuffer({ type: "BufferType", size: 16 }); // or createBuffer(type: "BufferType", size: 16) for syntax sugar or if you want mixed named and non-named arguments: Buffer createBuffer(BufferCreateInfo info, size_t howMany); // createBuffer(type: "BufferType", size: 16, 10); The only change is allowing struct construction on a function parameter, then maybe take it a step further by eliminating the curly braces in function calls. But I don't know anything about compilers...Not sure this could be doable in D. But for a main language that started out with significant naming of parameters (inheriting this from objective-C), it's a good place to look for inspiration here.Alternatively support implicit construction of structs as parameters i.e. void foo(Nullable!int ms); foo(ms: 3); You have to do some mapping internally but it means even if you deprecate a name, you can still keep the old ones.
Feb 09 2020
On Monday, 10 February 2020 at 04:36:17 UTC, rikki cattermole wrote:That is not what I suggested. What I suggested was given a single argument, automatically construct+call the constructor on a struct as defined in a parameter. It is a 1 to 1 rewrite and would be very simple to do.That sounds like what I just described. Not sure what the difference is. Anyway, there's already a PR for what I described written by Wilzbach, it was opened in 2017: https://github.com/dlang/DIPs/pull/71. Is this not the same as what you suggested?
Feb 09 2020
On 10/02/2020 5:47 PM, rb3 wrote:On Monday, 10 February 2020 at 04:36:17 UTC, rikki cattermole wrote:I have commented on that PR. The difference is: 1. in place struct initialization supports multiple arguments 2. and it requires extra syntax during construction 3. and finally is fully replaced by this DIPThat is not what I suggested. What I suggested was given a single argument, automatically construct+call the constructor on a struct as defined in a parameter. It is a 1 to 1 rewrite and would be very simple to do.That sounds like what I just described. Not sure what the difference is. Anyway, there's already a PR for what I described written by Wilzbach, it was opened in 2017: https://github.com/dlang/DIPs/pull/71. Is this not the same as what you suggested?
Feb 09 2020
On Sunday, 9 February 2020 at 01:47:35 UTC, Jon Degenhardt wrote:On Sunday, 9 February 2020 at 01:07:03 UTC, Adam D. Ruppe wrote:vibe.d uses parameter names to generate REST api bindings see: https://vibed.org/docs#rest-interface-generator[...]Probably not, but let me give some thoughts and ask a clarifying question. Main thing - As a pragmatic matter, I'd expect it to be much more likely that named argument invocation would be a source of breakage than usage arising from introspection. Related - There is significant difference between parameter names being public and having the names be sources of backward compatibility in function calls. Now my question - I know function parameters names can be retrieved by type introspection. What I don't know is the ways those names can be used such that programs can break if a parameter names change. Can you give some examples?
Feb 09 2020
On 2/8/2020 4:56 PM, Jon Degenhardt wrote:That said, having parameter names automatically become part of a function's API is a meaningful downside. (Specifically, that a parameter name cannot be changed without risk of breaking existing callers.)Note that D already has "named parameters" for struct initializers. That means, for example, that the names of the struct field cannot be changed without breaking any initializer relying on it. I've never heard a single comment about this, let alone any complaint, nor any indication that anyone's code broke.
Feb 09 2020
On Sunday, 9 February 2020 at 19:45:20 UTC, Walter Bright wrote:On 2/8/2020 4:56 PM, Jon Degenhardt wrote:struct A { int foo; } struct A { int bar; // renamed from foo deprecated alias foo = bar; }; False equivalency, you have many tools at your disposal to deal with this for structs. Also found a bug. A a = { foo: 10 }; // no deprecation warning, when foo is the deprecated aliasThat said, having parameter names automatically become part of a function's API is a meaningful downside. (Specifically, that a parameter name cannot be changed without risk of breaking existing callers.)Note that D already has "named parameters" for struct initializers. That means, for example, that the names of the struct field cannot be changed without breaking any initializer relying on it. I've never heard a single comment about this, let alone any complaint, nor any indication that anyone's code broke.
Feb 09 2020
On 2/9/2020 11:51 AM, Arine wrote:Also found a bug.Please report all bugs to bugzilla.
Feb 09 2020
On 2/9/2020 11:51 AM, Arine wrote:struct A { int foo; } struct A { int bar; // renamed from foo deprecated alias foo = bar; }; False equivalency, you have many tools at your disposal to deal with this for structs.C has it, too. Never heard a single complaint about it, either. https://en.cppreference.com/w/c/language/struct_initialization
Feb 09 2020
On 09.02.20 21:59, Walter Bright wrote:On 2/9/2020 11:51 AM, Arine wrote:If you change the name of a field, code that accesses the field in the standard way also breaks. It would be rather weird if people complained specifically about broken initializers.struct A { int foo; } struct A { int bar; // renamed from foo deprecated alias foo = bar; }; False equivalency, you have many tools at your disposal to deal with this for structs.C has it, too. Never heard a single complaint about it, either. https://en.cppreference.com/w/c/language/struct_initialization
Feb 11 2020
On 2/11/2020 12:49 AM, Timon Gehr wrote:If you change the name of a field, code that accesses the field in the standard way also breaks. It would be rather weird if people complained specifically about broken initializers.If the code followed good encapsulation techniques, it wouldn't any more than changing the name of a parameter would necessitate changing the body of the function.
Feb 12 2020
On 13.02.20 02:40, Walter Bright wrote:On 2/11/2020 12:49 AM, Timon Gehr wrote:Which is exactly what defeats the argument that spawned this sub-thread.If you change the name of a field, code that accesses the field in the standard way also breaks. It would be rather weird if people complained specifically about broken initializers.If the code followed good encapsulation techniques, it wouldn't any more than changing the name of a parameter would necessitate changing the body of the function.
Feb 19 2020
On Sunday, 9 February 2020 at 20:59:52 UTC, Walter Bright wrote:On 2/9/2020 11:51 AM, Arine wrote:struct A { int foo; }; struct A { union { int foo; int bar; // renamed to bar }; }; struct A a = { .foo = 10 }; False equivalency, you have some tools at your disposal to deal with this for structs in C.struct A { int foo; } struct A { int bar; // renamed from foo deprecated alias foo = bar; }; False equivalency, you have many tools at your disposal to deal with this for structs.C has it, too. Never heard a single complaint about it, either. https://en.cppreference.com/w/c/language/struct_initialization
Feb 11 2020
On Tuesday, 11 February 2020 at 15:11:18 UTC, Arine wrote:On Sunday, 9 February 2020 at 20:59:52 UTC, Walter Bright wrote:only since C11. anonymous unions and structs are gcc extension (or C++).On 2/9/2020 11:51 AM, Arine wrote:struct A { int foo; }; struct A { union { int foo; int bar; // renamed to bar }; };struct A { int foo; } struct A { int bar; // renamed from foo deprecated alias foo = bar; }; False equivalency, you have many tools at your disposal to deal with this for structs.C has it, too. Never heard a single complaint about it, either. https://en.cppreference.com/w/c/language/struct_initializationstruct A a = { .foo = 10 }; False equivalency, you have some tools at your disposal to deal with this for structs in C.
Feb 11 2020
On 2/6/20 10:33 PM, Jonathan M Davis wrote:Once in a while, named arguments may be useful, but for the most part, they're useful because a function has way too many parameters, in which case, the function should have been designed differently.I find this assertion lacking evidence. How does one design a constructor that initializes all the fields of a type without including all the parameters to initialize that type? If you reduce the number of parameters, what do you do with the data not specified? I suppose you can just have a minimal constructor and then just expect the user to set all the pieces up, but what if you need to use it in an expression? How do you decide which pieces are "important" enough to initialize first, and which ones get initialized later? What if the parameters are initializing things that can only be initialized in the constructor (e.g. immutable data). I focus on constructors because structs ALREADY support named parameters in this instance (when there is a lack of constructor), and we haven't seen the problems you are asserting. I can imagine with this DIP instead of 15 different constructors for all the different ways you want to construct said type (yes, I've seen this kind of stuff), you have one that has default arguments for all of the optional pieces (or maybe you split them up with ones that can be safe/pure and ones that can't, etc). And then the call interface is much better looking and self-explanatory. And I like that you can pick which way you want to call it, even for individual parameters. -Steve
Feb 10 2020
On Mon, Feb 10, 2020 at 01:27:49PM -0500, Steven Schveighoffer via Digitalmars-d wrote:On 2/6/20 10:33 PM, Jonathan M Davis wrote:[...] Ostensibly, by encapsulating the parameters into a struct and passing said struct up the ctor chain. ;-) T -- English has the lovely word "defenestrate", meaning "to execute by throwing someone out a window", or more recently "to remove Windows from a computer and replace it with something useful". :-) -- John CowanOnce in a while, named arguments may be useful, but for the most part, they're useful because a function has way too many parameters, in which case, the function should have been designed differently.I find this assertion lacking evidence. How does one design a constructor that initializes all the fields of a type without including all the parameters to initialize that type?
Feb 10 2020
On 2/10/20 1:36 PM, H. S. Teoh wrote:On Mon, Feb 10, 2020 at 01:27:49PM -0500, Steven Schveighoffer via Digitalmars-d wrote:So basically, for each type you need to define another type to pass parameters? Sounds... excessive ;) And the benefit of having a POD struct to pass as a parameter to cut down on constructor parameters is... you get named parameters! -SteveOn 2/6/20 10:33 PM, Jonathan M Davis wrote:[...] Ostensibly, by encapsulating the parameters into a struct and passing said struct up the ctor chain. ;-)Once in a while, named arguments may be useful, but for the most part, they're useful because a function has way too many parameters, in which case, the function should have been designed differently.I find this assertion lacking evidence. How does one design a constructor that initializes all the fields of a type without including all the parameters to initialize that type?
Feb 10 2020
On Mon, Feb 10, 2020 at 01:39:12PM -0500, Steven Schveighoffer via Digitalmars-d wrote:On 2/10/20 1:36 PM, H. S. Teoh wrote:[...] And there you have it, we already have named parameters. :-P Albeit in a verbose, circumlocutious way. :-P T -- English has the lovely word "defenestrate", meaning "to execute by throwing someone out a window", or more recently "to remove Windows from a computer and replace it with something useful". :-) -- John CowanOn Mon, Feb 10, 2020 at 01:27:49PM -0500, Steven Schveighoffer via Digitalmars-d wrote:So basically, for each type you need to define another type to pass parameters? Sounds... excessive ;) And the benefit of having a POD struct to pass as a parameter to cut down on constructor parameters is... you get named parameters!On 2/6/20 10:33 PM, Jonathan M Davis wrote:[...] Ostensibly, by encapsulating the parameters into a struct and passing said struct up the ctor chain. ;-)Once in a while, named arguments may be useful, but for the most part, they're useful because a function has way too many parameters, in which case, the function should have been designed differently.I find this assertion lacking evidence. How does one design a constructor that initializes all the fields of a type without including all the parameters to initialize that type?
Feb 10 2020
On 2/10/2020 10:39 AM, Steven Schveighoffer wrote:[...]Thanks, you said it better than I!
Feb 10 2020
On Monday, 10 February 2020 at 18:27:49 UTC, Steven Schveighoffer wrote:On 2/6/20 10:33 PM, Jonathan M Davis wrote:Let me give a data point to the contrary. I am a C++ programmer at work and using CLion as my IDE. Recently CLion got the ability to display parameter names inline at call sides, that is given a function invocationOnce in a while, named arguments may be useful, but for the most part, they're useful because a function has way too many parameters, in which case, the function should have been designed differently.I find this assertion lacking evidence.foo(bar, baz, baraz)of a functionfoo(parametertype1 parametername1, parametertype2 parametername2, ptype3 pname3)it will be displayed like this with the parameter names in a slight gray:foo(parametername1: bar, parametername2: baz, pname3: baraz).This already saved hours by preventing bugs and is unanimously considered an improvement by all my colleagues. I am convinced named parameters can improve code quality and even expect that tooling will show up to insert them automatically in existing code, when they get into the language.
Feb 10 2020
On Monday, February 10, 2020 11:27:49 AM MST Steven Schveighoffer via Digitalmars-d wrote:On 2/6/20 10:33 PM, Jonathan M Davis wrote:The only time that the struct initialization equivalent of named parameters comes into play is when you have a POD type which exposes its member variables. Most structs don't do that, because it's usually bad practice to expose members that way unless they're POD types, and most structs aren't POD types. They usually encpasulate their data and have functions for manipulating it. So, while struct initializers may exist in the language, they're very limited in how they can be used, whereas named arguments could be used pretty much anywhere. I have rarely seen structs where it made sense to have a long list of parameters to their constructors. In almost all cases, when that sort of thing happens, it makes far more sense to group such data into multiple structs so that the data is more organized instead of a huge blob of values all shoved directly into a single object. And in general, if a function parameter list is long, it's usually because the API didn't use structs to group and encapsulate data cleanly. I have rarely seen code where I would have considered it reasonable to have a large list of parameters to a function. As far as I can tell, named parameters are primarily an excuse to be able to have overly long parameter lists instead of properly organizing data, and they encourage what I would consider to be poor programming practices. Regardless, my biggest problem with this DIP (and any DIP with named arguments) is that it adds function parameter names to the API. IMHO, it adds minimal benefit, and in return, it adds yet another set of names which are going to be bikeshedded, and yet another thing that you can't change without risking breaking code. If D were set up so that you normally had function prototypes separate from the functions themselves like you do in C/C++, I would almost certainly stop putting names on _any_ function prototypes if named parameters were added. I don't want to have to worry about breaking someone else's code because of a change to a parameter's name, and IMHO, there are already far too many arguments over the names of functions and types without adding parameter names to the list. - Jonathan M DavisOnce in a while, named arguments may be useful, but for the most part, they're useful because a function has way too many parameters, in which case, the function should have been designed differently.I find this assertion lacking evidence. How does one design a constructor that initializes all the fields of a type without including all the parameters to initialize that type? If you reduce the number of parameters, what do you do with the data not specified? I suppose you can just have a minimal constructor and then just expect the user to set all the pieces up, but what if you need to use it in an expression? How do you decide which pieces are "important" enough to initialize first, and which ones get initialized later? What if the parameters are initializing things that can only be initialized in the constructor (e.g. immutable data). I focus on constructors because structs ALREADY support named parameters in this instance (when there is a lack of constructor), and we haven't seen the problems you are asserting. I can imagine with this DIP instead of 15 different constructors for all the different ways you want to construct said type (yes, I've seen this kind of stuff), you have one that has default arguments for all of the optional pieces (or maybe you split them up with ones that can be safe/pure and ones that can't, etc). And then the call interface is much better looking and self-explanatory. And I like that you can pick which way you want to call it, even for individual parameters.
Feb 11 2020
On Friday, 7 February 2020 at 03:33:26 UTC, Jonathan M Davis wrote:Once in a while, named arguments may be useful, but for the most part, they're useful because a function has way too many parameters, in which case, the function should have been designed differently.I've had the opportunity to design some methods relying on named methods having too many arguments comes from parameters being positional. I find the old advice to package it into a structure as pretending like you're reducing the number of arguments. While a method with many arguments would indicate doing too many things, but I think as you move up in the call stack you have to add to all the different functionality you're trying to abstract away.
Feb 10 2020
On Friday, 7 February 2020 at 03:33:26 UTC, Jonathan M Davis wrote:but for the most part, they're useful because a function has way too many parameters, in which case, the function should have been designed differently.Named parameters are not just for when there are too many parameters. Easy example: dup2(a, b); vs dup2(src: a, dst: b);
Feb 19 2020
On Wednesday, February 19, 2020 8:31:00 AM MST Yuxuan Shui via Digitalmars-d wrote:On Friday, 7 February 2020 at 03:33:26 UTC, Jonathan M Davis wrote:Named arguments are completely unnecessary in such a situation. The list of arguments is short enough that it's trivial to know which is which and what they're for. Having the parameter names listed at the call site is just unnecessary cruft, and having named arguments in the language opens up the whole issue of whether the names src and dst were the best names for dup2. Just like there's often too much arguing over what a function should be named, you then have arguing over what the function's parameters should be named and whether they're consistent with other functions, which isn't an issue right now. Right now, if the programmer maintaining dup2 wants to change the parameter names as part of working on the function's implementation, doing so is not a problem, whereas with named arguments, it would break code. Personally, I don't think that named arguments provide much value, and I _really_ don't want parameters to become part of the API. We have enough bikeshedding over names as it is and don't need to introduce yet more ways that changing libraries can break existing code. Unfortunately, given Walter's current position on this, I'm likely going to have to deal with named arguments and the problems that they bring, but I really don't have much good to say about them, and I do not look forward to having to deal with them in the least. - Jonathan M Davisbut for the most part, they're useful because a function has way too many parameters, in which case, the function should have been designed differently.Named parameters are not just for when there are too many parameters. Easy example: dup2(a, b); vs dup2(src: a, dst: b);
Feb 19 2020
On Wednesday, 19 February 2020 at 19:13:01 UTC, Jonathan M Davis wrote:Eh, the thing with these is it is really easy to do it backwards. I come from intel assembly so I always think it is `mov dst, src`. Unless it is `cp src dst` which is the one exception baked into my brain. So listing it here can legitimately be useful as a reminder when you aren't sure which style this particular function used.dup2(src: a, dst: b);Named arguments are completely unnecessary in such a situation. The list of arguments is short enough that it's trivial to know which is which and what they're for.
Feb 19 2020
On Wednesday, 19 February 2020 at 19:13:01 UTC, Jonathan M Davis wrote:On Wednesday, February 19, 2020 8:31:00 AM MST Yuxuan Shui via Digitalmars-d wrote:I agree. I know there are complaints about being required to use a particular tool to use a language, but this particular argument for named parameters uses a language change - one with big side effects - to do something that should be done by an IDE. The nice thing about proper editor support is that it continues to work exactly as expected even if you do change the parameter names in the library.On Friday, 7 February 2020 at 03:33:26 UTC, Jonathan M Davis wrote:Named arguments are completely unnecessary in such a situation. The list of arguments is short enough that it's trivial to know which is which and what they're for. Having the parameter names listed at the call site is just unnecessary cruft, and having named arguments in the language opens up the whole issue of whether the names src and dst were the best names for dup2. Just like there's often too much arguing over what a function should be named, you then have arguing over what the function's parameters should be named and whether they're consistent with other functions, which isn't an issue right now. Right now, if the programmer maintaining dup2 wants to change the parameter names as part of working on the function's implementation, doing so is not a problem, whereas with named arguments, it would break code. Personally, I don't think that named arguments provide much value, and I _really_ don't want parameters to become part of the API. We have enough bikeshedding over names as it is and don't need to introduce yet more ways that changing libraries can break existing code. Unfortunately, given Walter's current position on this, I'm likely going to have to deal with named arguments and the problems that they bring, but I really don't have much good to say about them, and I do not look forward to having to deal with them in the least. - Jonathan M Davisbut for the most part, they're useful because a function has way too many parameters, in which case, the function should have been designed differently.Named parameters are not just for when there are too many parameters. Easy example: dup2(a, b); vs dup2(src: a, dst: b);
Feb 19 2020
On Wednesday, 19 February 2020 at 19:34:53 UTC, bachmeier wrote:On Wednesday, 19 February 2020 at 19:13:01 UTC, Jonathan M Davis wrote:What editor are you specifically talking about here and how should it be done? Generating comments like this? go(\*a*\ 1); Alex[...]I agree. I know there are complaints about being required to use a particular tool to use a language, but this particular argument for named parameters uses a language change - one with big side effects - to do something that should be done by an IDE. The nice thing about proper editor support is that it continues to work exactly as expected even if you do change the parameter names in the library.
Feb 19 2020
On Wednesday, 19 February 2020 at 19:57:06 UTC, 12345swordy wrote:On Wednesday, 19 February 2020 at 19:34:53 UTC, bachmeier wrote:E.g. CLion does it. In renders the parameter names at the call site without changing the code at all (it does not insert comments). It is a very useful feature. Granted, if that support was readily available for D than the argument for named parameters would be weaker.On Wednesday, 19 February 2020 at 19:13:01 UTC, Jonathan M Davis wrote:What editor are you specifically talking about here and how should it be done? Generating comments like this? go(\*a*\ 1); Alex[...]I agree. I know there are complaints about being required to use a particular tool to use a language, but this particular argument for named parameters uses a language change - one with big side effects - to do something that should be done by an IDE. The nice thing about proper editor support is that it continues to work exactly as expected even if you do change the parameter names in the library.
Feb 19 2020
On Wednesday, 19 February 2020 at 20:04:56 UTC, Panke wrote:On Wednesday, 19 February 2020 at 19:57:06 UTC, 12345swordy wrote:Isn't that mainly due to cpp having header files? -AlexOn Wednesday, 19 February 2020 at 19:34:53 UTC, bachmeier wrote:E.g. CLion does it. In renders the parameter names at the call site without changing the code at all (it does not insert comments). It is a very useful feature. Granted, if that support was readily available for D than the argument for named parameters would be weaker.[...]What editor are you specifically talking about here and how should it be done? Generating comments like this? go(\*a*\ 1); Alex
Feb 19 2020
On Wednesday, 19 February 2020 at 20:09:25 UTC, 12345swordy wrote:On Wednesday, 19 February 2020 at 20:04:56 UTC, Panke wrote:parameter names, rather than the names being embedded in the code. So not really limited to header files.On Wednesday, 19 February 2020 at 19:57:06 UTC, 12345swordy wrote:Isn't that mainly due to cpp having header files? -AlexOn Wednesday, 19 February 2020 at 19:34:53 UTC, bachmeier wrote:E.g. CLion does it. In renders the parameter names at the call site without changing the code at all (it does not insert comments). It is a very useful feature. Granted, if that support was readily available for D than the argument for named parameters would be weaker.[...]What editor are you specifically talking about here and how should it be done? Generating comments like this? go(\*a*\ 1); Alex
Feb 19 2020
On Wednesday, 19 February 2020 at 20:09:25 UTC, 12345swordy wrote:Isn't that mainly due to cpp having header files? -AlexIt displays the argument names where the function is used, so I see no connection to header files.
Feb 20 2020
On Wednesday, 19 February 2020 at 19:13:01 UTC, Jonathan M Davis wrote:On Wednesday, February 19, 2020 8:31:00 AM MST Yuxuan Shui via Named arguments are completely unnecessary in such a situation. The list of arguments is short enough that it's trivial to know which is which and what they're for. Having the parameter names listed at the call site is just unnecessary cruft, and having named arguments in the language opens up the whole issue of whether the names src and dst were the best names for dup2.I just can say that my professional experience leads me to believe the complete opposite. Named parameters and parameter names at the call site are useful, aid in understanding the code and prevent bugs.
Feb 19 2020
On Wednesday, 19 February 2020 at 19:13:01 UTC, Jonathan M Davis wrote:On Wednesday, February 19, 2020 8:31:00 AM MST Yuxuan Shui via Digitalmars-d wrote:This is off the mark. Named arguments are very useful even in this case (maybe *especially* in this case, when you have to rely on the convention that src always comes first and dst always comes second). I've been using Groovy a lot at work lately, which has support for named arguments (and interpolated strings, by the way), and it allows for writing some very clear and readable code.On Friday, 7 February 2020 at 03:33:26 UTC, Jonathan M Davis wrote:Named arguments are completely unnecessary in such a situation. The list of arguments is short enough that it's trivial to know which is which and what they're for.but for the most part, they're useful because a function has way too many parameters, in which case, the function should have been designed differently.Named parameters are not just for when there are too many parameters. Easy example: dup2(a, b); vs dup2(src: a, dst: b);
Feb 20 2020
Replying to Timon's post on the feedback thread: On 2/6/20 10:49 PM, Timon Gehr wrote:This introduces syntax like: import std.typecons; alias t=AliasSeq!(c:1, a:2, b:3); // valid according to DIP void foo(int a,int b,int c){ writeln(a," ",b," ",c); } void main(){ foo(t); }Does it? AliasSeq's template parameter (singular) is named TList, not a, b, or c. So I would expect this to fail to compile. This does bring up a valid point though. The DIP talks about variadic parameters, but template variadic parameters actually have a name. So what does this mean? Is it valid? AliasSeq!(TList: 1, 2, 3) -Steve
Feb 06 2020
On 2/7/20 12:00 AM, Steven Schveighoffer wrote:This does bring up a valid point though. The DIP talks about variadic parameters, but template variadic parameters actually have a name.So do typesafe variadics. I think the DIP needs to be more explicit here with what it means. -Steve
Feb 06 2020
On 07.02.20 06:00, Steven Schveighoffer wrote:Replying to Timon's post on the feedback thread: On 2/6/20 10:49 PM, Timon Gehr wrote: > This introduces syntax like: > > import std.typecons; > alias t=AliasSeq!(c:1, a:2, b:3); // valid according to DIP > void foo(int a,int b,int c){ > writeln(a," ",b," ",c); > } > > void main(){ > foo(t); > } Does it? AliasSeq's template parameter (singular) is named TList, not a, b, or c. So I would expect this to fail to compile.It does add the syntax, and I would argue it is not ideal if this fails to pass semantic analysis.
Feb 07 2020
On 2/7/20 5:52 AM, Timon Gehr wrote:On 07.02.20 06:00, Steven Schveighoffer wrote:Yes, it's valid syntax, but shouldn't pass semantic -- you named arguments that aren't present (AliasSeq does not have parameters named a b or c). But the DIP isn't 100% clear that named variadics cannot receive NamedParameter items. It says extra parameters match the "trailing ... of variadic parameter lists and Identifiers are not allowed". Not all variadic functions have a trailing ... without a name. I would think AliasSeq!(TList: 1, 2, 3) should be valid. -SteveReplying to Timon's post on the feedback thread: On 2/6/20 10:49 PM, Timon Gehr wrote: > This introduces syntax like: > > import std.typecons; > alias t=AliasSeq!(c:1, a:2, b:3); // valid according to DIP > void foo(int a,int b,int c){ > writeln(a," ",b," ",c); > } > > void main(){ > foo(t); > } Does it? AliasSeq's template parameter (singular) is named TList, not a, b, or c. So I would expect this to fail to compile.It does add the syntax, and I would argue it is not ideal if this fails to pass semantic analysis.
Feb 07 2020
On 07.02.20 16:28, Steven Schveighoffer wrote:So you are arguing that e.g., std.typecons.Proxy should fail to work with named arguments?It does add the syntax, and I would argue it is not ideal if this fails to pass semantic analysis.Yes, it's valid syntax, but shouldn't pass semantic -- you named arguments that aren't present (AliasSeq does not have parameters named a b or c). ...But the DIP isn't 100% clear that named variadics cannot receive NamedParameter items. It says extra parameters match the "trailing ... of variadic parameter lists and Identifiers are not allowed". Not all variadic functions have a trailing ... without a name. I would think AliasSeq!(TList: 1, 2, 3) should be valid. -SteveWhy is that more useful than support for forwarding?
Feb 08 2020
On 2/8/20 5:04 AM, Timon Gehr wrote:On 07.02.20 16:28, Steven Schveighoffer wrote:Technically, it doesn't today, so it's not a break. But it is a good point. opDispatch in general will fail to support named parameters without a ton of extra mixins and boilerplate (potentially, you could have opDispatch specify all parameters and names).So you are arguing that e.g., std.typecons.Proxy should fail to work with named arguments?It does add the syntax, and I would argue it is not ideal if this fails to pass semantic analysis.Yes, it's valid syntax, but shouldn't pass semantic -- you named arguments that aren't present (AliasSeq does not have parameters named a b or c). ...Not more useful, but unambiguous. For example, what does AliasSeq!(TList: 1) mean? Did you mean to assign a 1 to the template parameter already named TList, or did you mean to submit a parameter named TList? Should this then fail to compile or pass? void foo(int a); alias params = AliasSeq!(TList: 1); foo(params); // does this mean foo(1) or foo(TList: 1)? Potentially, we could specify with some syntax that a parameter could consume all named arguments not already tagged, and that name wouldn't matter. An interesting artifact of this, is that we could potentially eliminate std.typecons.Tuple. But I feel this would be an additional proposal on top of named parameters, even though it's related. -SteveBut the DIP isn't 100% clear that named variadics cannot receive NamedParameter items. It says extra parameters match the "trailing ... of variadic parameter lists and Identifiers are not allowed". Not all variadic functions have a trailing ... without a name. I would think AliasSeq!(TList: 1, 2, 3) should be valid.Why is that more useful than support for forwarding?
Feb 08 2020
It's clear that what should happen with named arguments and variadics is far from clear-cut. Therefore, the proper way forward for the time being is to simply disallow matching them with a ... Nothing is being broken by this, as currently named arguments do not work at all. If a decent design for it is developed in the future, we can always add it. But adding a design now that turns out later to be inferior or botched is going to be hard to remove. Just look at the trouble we have with alias this and autodecoding.
Feb 08 2020
On Thursday, 6 February 2020 at 06:08:59 UTC, Mike Parker wrote:This is the feedback thread for the first round of Community Review for DIP 1030, "Named Arguments":I think this DIP is a solid approach to named arguments for D. However, I second Timon's concern from the feedback thread regarding point 5If there are more NamedArguments than Parameters, the remainder match the trailing ... of variadic parameter lists, and Identifiers are not allowed.Either leftover named arguments should go into the variadic parameters (and it must be able to tell whether a parameter in the list was given with an Identifier or not) OR a template could decide to catch leftover NamedArguments in another form of variadic named parameters (similar to Python's kwargs).
Feb 06 2020
On Friday, 7 February 2020 at 20:02:18 UTC, Walter Bright wrote:[snip] So, void foo(int a, ...); called with: foo(b:1, 2) should be the equivalent of: foo(2, 1) ?This was on the feedback thread, but I didn't want to pollute that... This reminds me of what **kwargs in Python is trying to address. Basically, the identifier b is dropped. For instance, foo(c:3, b:1, 2) would be equivalent to foo(2, 3, 1) under the DIP and the information that you might have wanted to use to make it actually foo(2, 1, 3) is no longer available.
Feb 07 2020
On 07.02.20 21:49, jmh530 wrote:On Friday, 7 February 2020 at 20:02:18 UTC, Walter Bright wrote:Here's my answer from the feedback thread: I was thinking about template variadics, not sure about the C-style ones. I think your example would not match in any case, because unnamed arguments after a named argument match the next parameter, so actually you don't provide a value for 'a'. Also, the name would have to be preserved through the template instantiation. void foo(T...)(int a, T args){ ... } foo(b: 1, a: 2) <=> foo!(b: int)(2, 1); Constructs like https://dlang.org/library/std/typecons/proxy.html should ideally not break.[snip] So, void foo(int a, ...); called with: foo(b:1, 2) should be the equivalent of: foo(2, 1) ?This was on the feedback thread, but I didn't want to pollute that...
Feb 08 2020
On Thu, Feb 6, 2020 at 7:34 PM Jonathan M Davis via Digitalmars-d <digitalmars-d puremagic.com> wrote:On Wednesday, February 5, 2020 11:08:59 PM MST Mike Parker via Digitalmars-d wrote:I don't have any horse in this race... but I do just want to echo that I don't understand this feature at all. I don't know what it's for. I've never felt I wanted named arguments personally, and Jonathan's criticism feels very real to me. Here's a thought, which I haven't considered how it interacts with this DIP deeply, but it should be on the table: I do an immense amount of generative meta; generate wrappers, shims, bindings etc, which wrap existing functions. When the parameter names become part of the API, it means any such meta must pay extra attention to properly mirror the parameter names, and it must also carefully mirror the default args from the function it's wrapping. While most of my code takes care to do this anyway, there are cases where it's unnecessary and inconvenient. Some tasks can be completed with a tool like: ReturnType!originalFunction wrapper(alias originalFunction)(Parameters!originalFunction args) { // special sauce... return originalFunction(args); } It is possible to write many forms of glue this way. If we must mirror the argument names and default arguments, you must fall back into string mixin territory, and the code to emit the proper prototype is complex and intensive. In a named-arguments world, shim's like the one I showed above are no longer valid where calling code would use named arguments. I don't there is existing language that could make this possible: ReturnType!originalFunction wrapper(alias originalFunction)(ParametersWithNamesAndDefaultArgs!originalFunction args) { ... } For me to get excited about this DIP sufficiently to offset my fears, I need to know what it's for... and I don't. If it's useful in the rare case where functions have way too many parameters... personally, I resolve that by making my functions NOT have way too many parameters. I'm not sure that too-many-parameters is a pattern that should be encouraged by the core language. I would not to do this unless we can provide a really compelling case to support its existence. I'm not satisfied that case exists here. Maybe I missed it? (I'm not really following this topic)This is the feedback thread for the first round of Community Review for DIP 1030, "Named Arguments": https://github.com/dlang/DIPs/blob/44b0d4ec0da6a2e797ede748fb1e81cd6db1037 1/DIPs/DIP1030.md 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... in other words, business as usual. However, if you have any specific feedback for how to improve the the proposal itself, then please post it in the feedback thread. The feedback thread will be the source for the review summary I 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 The review period will end at 11:59 PM ET on February 20, or when I make a post declaring it complete. Discussion in this thread may continue beyond that point. At the end of Round 1, if further review is deemed necessary, the DIP will be scheduled for another round of Community Review. Otherwise, it will be queued for the Final Review and Formal Assessment. Please stay on topic here. I will delete posts that are completely off topic.Well, I'll say again that I don't like the idea of having named arguments in the language, because it makes the parameter names part of the API, resulting in yet more bikeshedding and yet another thing that can't be changed without breaking existing code. Once in a while, named arguments may be useful, but for the most part, they're useful because a function has way too many parameters, in which case, the function should have been designed differently. Unfortunately, since it's Walter who created the DIP, and a number of people do like the idea of named arguments, I expect that some form of this will make it in, but I still think that it's a bad idea. - Jonathan M Davis
Feb 10 2020
On Monday, 10 February 2020 at 19:38:34 UTC, Manu wrote:If we must mirror the argument names and default arguments, you must fall back into string mixin territoryIt is super simple. Consider this example: --- int foo(string s = null, int a = 12) { return a + 12; } template wrapWithPrint(alias fn) { static if(is(typeof(fn) P == __parameters)) auto wrapWithPrint(P params) { import std.stdio; writeln(params); auto ret = fn(params); writeln("returned: ", ret); return ret; } else static assert(0); } void main() { wrapWithPrint!foo(); wrapWithPrint!foo("cool"); wrapWithPrint!foo("cool", 20); } --- Default values and param names are included in the __parameters thing and just works if you use it directly. I saw people overcomplicating this just a few hours ago too which is why I have this example ready. There's plenty of techniques to do this though I guess they aren't well known.
Feb 10 2020
On 10.02.20 20:46, Adam D. Ruppe wrote:On Monday, 10 February 2020 at 19:38:34 UTC, Manu wrote:What if fn is a template?If we must mirror the argument names and default arguments, you must fall back into string mixin territoryIt is super simple. Consider this example: --- int foo(string s = null, int a = 12) { return a + 12; } template wrapWithPrint(alias fn) { static if(is(typeof(fn) P == __parameters)) auto wrapWithPrint(P params) { import std.stdio; writeln(params); auto ret = fn(params); writeln("returned: ", ret); return ret; } else static assert(0); } void main() { wrapWithPrint!foo(); wrapWithPrint!foo("cool"); wrapWithPrint!foo("cool", 20); } --- Default values and param names are included in the __parameters thing and just works if you use it directly. I saw people overcomplicating this just a few hours ago too which is why I have this example ready. There's plenty of techniques to do this though I guess they aren't well known.
Feb 11 2020
On Tuesday, 11 February 2020 at 09:02:03 UTC, Timon Gehr wrote:What if fn is a template?Then, as I'm sure you already know, it won't work. It needs an instantiation to wrap in this style. Same with Manu's code though so we've lost nothing. Can be slightly annoying with stuff like `to!int`, you'd have to `wrap!(to!it)...` A generic forwarder would be variadic and thus this DIP doesn't apply to it regardless. (Though, in a previous review on github for this I proposed a way to handle that - make a variadic template with named params form an anonymous struct that the receiving template can process. Similar to Python's kwargs I'm told. Got pushback and I decided to table it, even though it would provide a lot of cool flexibility so hoping we can come back to it later.)
Feb 11 2020
On 2/11/20 8:56 AM, Adam D. Ruppe wrote:On Tuesday, 11 February 2020 at 09:02:03 UTC, Timon Gehr wrote:Manu's example doesn't work, but this would (and I use this all the time): auto wrapper(alias originalFunction, T...)(T args) if (...) // makes sure we can call the function { return originalFunction(args); }What if fn is a template?Then, as I'm sure you already know, it won't work. It needs an instantiation to wrap in this style. Same with Manu's code though so we've lost nothing.Can be slightly annoying with stuff like `to!int`, you'd have to `wrap!(to!it)...` A generic forwarder would be variadic and thus this DIP doesn't apply to it regardless. (Though, in a previous review on github for this I proposed a way to handle that - make a variadic template with named params form an anonymous struct that the receiving template can process. Similar to Python's kwargs I'm told. Got pushback and I decided to table it, even though it would provide a lot of cool flexibility so hoping we can come back to it later.)What if fn has 10 different overloads? You have to provide all of them. Where as a template forwarder as above just works. I think we need to solve this problem in a "just works" way before having named parameters. -Steve
Feb 11 2020
On Tuesday, 11 February 2020 at 14:22:30 UTC, Steven Schveighoffer wrote:Manu's example doesn't work, but this would (and I use this all the time): auto wrapper(alias originalFunction, T...)(T args) if (...) //Yeah, I use that a lot too.What if fn has 10 different overloads?static foreach(overload; __traits(getOverloads, item, fun)) static if(is(typeof(overload) Params == __parameters)) auto wrap(Params p) { return overload(p); } Which has advantages over the T... in terms of error messages and future reflection. Also works in interfaces and similar. So I agree with you that the names in variadics would be super cool for lots of reasons. I'm meh on if it is *required* but I certainly do prefer it. Just still knowing these techniques are useful anyway so I take any chance to educate :)
Feb 11 2020
On 10.02.20 20:46, Adam D. Ruppe wrote:It is super simple. Consider this example: --- template wrapWithPrint(alias fn) { static if(is(typeof(fn) P == __parameters)) auto wrapWithPrint(P params) { import std.stdio; writeln(params); auto ret = fn(params); writeln("returned: ", ret); return ret; } else static assert(0); } ---int troll(int ret){ return ret; } void main(){ wrapWithPrint!troll(2); }
Feb 11 2020
On Tuesday, 11 February 2020 at 09:29:22 UTC, Timon Gehr wrote:int troll(int ret){ return ret; } void main(){ wrapWithPrint!troll(2); }lol, indeed. There can be downsides to inheriting random names :)
Feb 11 2020
On Monday, 10 February 2020 at 19:38:34 UTC, Manu wrote:On Thu, Feb 6, 2020 at 7:34 PM Jonathan M Davis via Digitalmars-d <digitalmars-d puremagic.com> wrote:For me personalty, readability\reliability is a huge factor here. Knowing what values should go to where is a big plus for me, when to web development, and the default parameters prevent me sending values to the wrong parameter. -Alex[...]I don't have any horse in this race... but I do just want to echo that I don't understand this feature at all. I don't know what it's for. I've never felt I wanted named arguments personally, and Jonathan's criticism feels very real to me. [...]
Feb 10 2020
On Monday, 10 February 2020 at 19:49:24 UTC, 12345swordy wrote:On Monday, 10 February 2020 at 19:38:34 UTC, Manu wrote:Meant to say "Named arguments prevent me from sending values to the wrong parameter"On Thu, Feb 6, 2020 at 7:34 PM Jonathan M Davis via Digitalmars-d <digitalmars-d puremagic.com> wrote:For me personalty, readability\reliability is a huge factor here. Knowing what values should go to where is a big plus for when it comes to web development, and the default parameters prevent me sending values to the wrong parameter. -Alex[...]I don't have any horse in this race... but I do just want to echo that I don't understand this feature at all. I don't know what it's for. I've never felt I wanted named arguments personally, and Jonathan's criticism feels very real to me. [...]
Feb 10 2020
On Mon, Feb 10, 2020 at 11:50 AM 12345swordy via Digitalmars-d <digitalmars-d puremagic.com> wrote:On Monday, 10 February 2020 at 19:38:34 UTC, Manu wrote:That feels like a pretty washy justification. Do you have an answer to my actual criticisms? I feel like generative meta is one of D's biggest features and selling points, and making that very difficult feels like a material loss.On Thu, Feb 6, 2020 at 7:34 PM Jonathan M Davis via Digitalmars-d <digitalmars-d puremagic.com> wrote:For me personalty, readability\reliability is a huge factor here. Knowing what values should go to where is a big plus for me, when to web development, and the default parameters prevent me sending values to the wrong parameter. -Alex[...]I don't have any horse in this race... but I do just want to echo that I don't understand this feature at all. I don't know what it's for. I've never felt I wanted named arguments personally, and Jonathan's criticism feels very real to me. [...]
Feb 10 2020
On Monday, 10 February 2020 at 20:45:22 UTC, Manu wrote:On Mon, Feb 10, 2020 at 11:50 AM 12345swordy via Digitalmars-d <digitalmars-d puremagic.com> wrote:Manu, it boils down to mainly experience when it comes to wanting named arguments. I have argue in favor of them in the past already in other DIP. I have no interest of repeating them.On Monday, 10 February 2020 at 19:38:34 UTC, Manu wrote:That feels like a pretty washy justification.On Thu, Feb 6, 2020 at 7:34 PM Jonathan M Davis via Digitalmars-d <digitalmars-d puremagic.com> wrote:For me personalty, readability\reliability is a huge factor here. Knowing what values should go to where is a big plus for when it comes to web development, and the default parameters prevent me sending values to the wrong parameter. -Alex[...]I don't have any horse in this race... but I do just want to echo that I don't understand this feature at all. I don't know what it's for. I've never felt I wanted named arguments personally, and Jonathan's criticism feels very real to me. [...]
Feb 10 2020
On Mon, Feb 10, 2020 at 1:05 PM 12345swordy via Digitalmars-d <digitalmars-d puremagic.com> wrote:On Monday, 10 February 2020 at 20:45:22 UTC, Manu wrote:I've seen some arguments, but I haven't understood them personally. I don't have a feel for their value, I can't judge that. I have described an important material loss associated with this. I'd like to see that important issue addressed in the form of "use this pattern instead" or, "we accept we are abandoning that important pattern, we feel it was less important than this DIP, and we accept code that uses that pattern will be broken", which, incidentally, is almost all D code I've ever written in a professional capacity... :/ I also have a fear that where making parameter names part of the API; renaming parameter == breaking change, this feels bad to me. It's resistant to improving API clarity over time. In my experience, API clarity is an ongoing maintenance challenge, where your poor choice in names is only discovered some time later as you have experience with other humans sense of intuition differing from your own initial judgement. That argument is about equally washy as your core argument, except from my personal point of view, I know that my argument here absolutely applies to me frequently over decades of experience, while I've never wanted names arguments once; so weighing the value judgement in that particular compromise seems obvious to me.On Mon, Feb 10, 2020 at 11:50 AM 12345swordy via Digitalmars-d <digitalmars-d puremagic.com> wrote:Manu, it boils down to mainly experience when it comes to wanting named arguments. I have argue in favor of them in the past already in other DIP. I have no interest of repeating them.On Monday, 10 February 2020 at 19:38:34 UTC, Manu wrote:That feels like a pretty washy justification.On Thu, Feb 6, 2020 at 7:34 PM Jonathan M Davis via Digitalmars-d <digitalmars-d puremagic.com> wrote:For me personalty, readability\reliability is a huge factor here. Knowing what values should go to where is a big plus for when it comes to web development, and the default parameters prevent me sending values to the wrong parameter. -Alex[...]I don't have any horse in this race... but I do just want to echo that I don't understand this feature at all. I don't know what it's for. I've never felt I wanted named arguments personally, and Jonathan's criticism feels very real to me. [...]
Feb 10 2020
On Monday, 10 February 2020 at 21:17:45 UTC, Manu wrote:On Mon, Feb 10, 2020 at 1:05 PM 12345swordy via Digitalmars-d <digitalmars-d puremagic.com> wrote:Yes, I have encounter the "API breakage" counter argument in other threads already. Still not convinced that it is a big issue as they make it out to be.On Monday, 10 February 2020 at 20:45:22 UTC, Manu wrote:I've seen some arguments, but I haven't understood them personally. I don't have a feel for their value, I can't judge that. I have described an important material loss associated with this. I'd like to see that important issue addressed in the form of "use this pattern instead" or, "we accept we are abandoning that important pattern, we feel it was less important than this DIP, and we accept code that uses that pattern will be broken", which, incidentally, is almost all D code I've ever written in a professional capacity... :/ I also have a fear that where making parameter names part of the API; renaming parameter == breaking change, this feels bad to me. It's resistant to improving API clarity over time. In my experience, API clarity is an ongoing maintenance challenge, where your poor choice in names is only discovered some time later as you have experience with other humans sense of intuition differing from your own initial judgement. That argument is about equally washy as your core argument, except from my personal point of view, I know that my argument here absolutely applies to me frequently over decades of experience, while I've never wanted names arguments once; so weighing the value judgement in that particular compromise seems obvious to me.On Mon, Feb 10, 2020 at 11:50 AM 12345swordy via Digitalmars-d <digitalmars-d puremagic.com> wrote:Manu, it boils down to mainly experience when it comes to wanting named arguments. I have argue in favor of them in the past already in other DIP. I have no interest of repeating them.On Monday, 10 February 2020 at 19:38:34 UTC, Manu wrote:That feels like a pretty washy justification.On Thu, Feb 6, 2020 at 7:34 PM Jonathan M Davis via Digitalmars-d <digitalmars-d puremagic.com> wrote:For me personalty, readability\reliability is a huge factor here. Knowing what values should go to where is a big plus code when it comes to web development, and the default parameters prevent me sending values to the wrong parameter. -Alex[...]I don't have any horse in this race... but I do just want to echo that I don't understand this feature at all. I don't know what it's for. I've never felt I wanted named arguments personally, and Jonathan's criticism feels very real to me. [...]
Feb 10 2020
On Mon, Feb 10, 2020 at 1:30 PM 12345swordy via Digitalmars-d <digitalmars-d puremagic.com> wrote:On Monday, 10 February 2020 at 21:17:45 UTC, Manu wrote:It's a huge problem today when a bad choice of function name is calcified; we'll be multiplying the probability of making bad naming choices by 2-3x. We can correct a bad function name by renaming it and producing a deprecated alias for the old name. We have no such way to correct a change in parameter name; we can't use alias because the parameter names are not part of the signature. Don't ignore the material issue I've shown that demands one of the 2 responses I suggested. If you push for acceptable of this DIP, then I think you must have a response to my primary issue.On Mon, Feb 10, 2020 at 1:05 PM 12345swordy via Digitalmars-d <digitalmars-d puremagic.com> wrote:Yes, I have encounter the "API breakage" counter argument in other threads already. Still not convinced that it is a big issue as they make it out to be.On Monday, 10 February 2020 at 20:45:22 UTC, Manu wrote:I've seen some arguments, but I haven't understood them personally. I don't have a feel for their value, I can't judge that. I have described an important material loss associated with this. I'd like to see that important issue addressed in the form of "use this pattern instead" or, "we accept we are abandoning that important pattern, we feel it was less important than this DIP, and we accept code that uses that pattern will be broken", which, incidentally, is almost all D code I've ever written in a professional capacity... :/ I also have a fear that where making parameter names part of the API; renaming parameter == breaking change, this feels bad to me. It's resistant to improving API clarity over time. In my experience, API clarity is an ongoing maintenance challenge, where your poor choice in names is only discovered some time later as you have experience with other humans sense of intuition differing from your own initial judgement. That argument is about equally washy as your core argument, except from my personal point of view, I know that my argument here absolutely applies to me frequently over decades of experience, while I've never wanted names arguments once; so weighing the value judgement in that particular compromise seems obvious to me.On Mon, Feb 10, 2020 at 11:50 AM 12345swordy via Digitalmars-d <digitalmars-d puremagic.com> wrote:Manu, it boils down to mainly experience when it comes to wanting named arguments. I have argue in favor of them in the past already in other DIP. I have no interest of repeating them.On Monday, 10 February 2020 at 19:38:34 UTC, Manu wrote:That feels like a pretty washy justification.On Thu, Feb 6, 2020 at 7:34 PM Jonathan M Davis via Digitalmars-d <digitalmars-d puremagic.com> wrote:For me personalty, readability\reliability is a huge factor here. Knowing what values should go to where is a big plus code when it comes to web development, and the default parameters prevent me sending values to the wrong parameter. -Alex[...]I don't have any horse in this race... but I do just want to echo that I don't understand this feature at all. I don't know what it's for. I've never felt I wanted named arguments personally, and Jonathan's criticism feels very real to me. [...]
Feb 10 2020
On Monday, 10 February 2020 at 21:41:02 UTC, Manu wrote:[snip] It's a huge problem today when a bad choice of function name is calcified; we'll be multiplying the probability of making bad naming choices by 2-3x. We can correct a bad function name by renaming it and producing a deprecated alias for the old name. We have no such way to correct a change in parameter name; we can't use alias because the parameter names are not part of the signature. Don't ignore the material issue I've shown that demands one of the 2 responses I suggested. If you push for acceptable of this DIP, then I think you must have a response to my primary issue.I was leaning towards favoring this DIP, as I frequently use named arguments in R and like the flexibility they offer in some cases. However, I came across two functions, written in python, at work. One takes a parameter and the other takes a slightly different parameter name. No good reason why these two do not use the same parameter names. They should be the same. However, python has named arguments for everything, so changing the names would mean that any code that uses the named version breaks. It definitely would make people much more conservative about changing their functions.
Feb 10 2020
On Monday, 10 February 2020 at 21:54:53 UTC, jmh530 wrote:However, python has named arguments for everything, so changing the names would mean that any code that uses the named version breaks. It definitely would make people much more conservative about changing their functions.In Python it is different because there's no compiler to tell you where changes occur. In D, this is the most trivial type of breakage - the compiler tells you where the change is and can make a good guess as to what the fix is too and can suggest it. It is a slight hassle - I remember renaming of functions in std.string driving me nuts in D ~2012ish. But it never *broke* my code per se, it wasn't something throwing at runtime when it didn't before, it was just an annoying half hour of find/replace tedium when I chose to update. (and note an option was just to defer the update too) And now the names are legit better. Like I said earlier in the thread, I can see a middle-man wanting compatibility across versions being a maybe, and we could do a deprecated alias for that, but I doubt it will be that hard. Consider it a minor version bump and - in theory - updates should be easy enough to schedule and do that tedious find/replace.
Feb 10 2020
On Monday, 10 February 2020 at 22:20:21 UTC, Adam D. Ruppe wrote:In D, this is the most trivial type of breakage - the compiler tells you where the change is and can make a good guess as to what the fix is too and can suggest it.That's true, but it's an hell when involving libraries: an external library author changes a parameter names, and break not only your codebase, that you can easily fix, but also other external libraries, and so on. It's a cascade process.
Feb 11 2020
On Tuesday, 11 February 2020 at 09:18:38 UTC, Paolo Invernizzi wrote:On Monday, 10 February 2020 at 22:20:21 UTC, Adam D. Ruppe wrote:If package dependencies are used correctly nothing is break :) AndreaIn D, this is the most trivial type of breakage - the compiler tells you where the change is and can make a good guess as to what the fix is too and can suggest it.That's true, but it's an hell when involving libraries: an external library author changes a parameter names, and break not only your codebase, that you can easily fix, but also other external libraries, and so on. It's a cascade process.
Feb 11 2020
On Tuesday, 11 February 2020 at 09:27:52 UTC, Andrea Fontana wrote:On Tuesday, 11 February 2020 at 09:18:38 UTC, Paolo Invernizzi wrote:What I mean, is that multiple authors can be involved in the necessary fix: it's not a matter of find/replace on your own codebase. Let's put It simple, and let's boil this down to essential: there's MORE probability of FUTURE breakage with named parameters, and that's a fact.On Monday, 10 February 2020 at 22:20:21 UTC, Adam D. Ruppe wrote:If package dependencies are used correctly nothing is break :) AndreaIn D, this is the most trivial type of breakage - the compiler tells you where the change is and can make a good guess as to what the fix is too and can suggest it.That's true, but it's an hell when involving libraries: an external library author changes a parameter names, and break not only your codebase, that you can easily fix, but also other external libraries, and so on. It's a cascade process.
Feb 11 2020
On Tuesday, 11 February 2020 at 09:46:35 UTC, Paolo Invernizzi wrote:Let's put It simple, and let's boil this down to essential: there's MORE probability of FUTURE breakage with named parameters, and that's a fact.Only if you use the feature. That's part of the reason why I don't think you should be able to set a default of the middle argument. This just forces someone to use the feature if they a default parameter in the middle without the rest that follow also having default values. Other than that, if you don't want your code to break potentially from argument changes, then don't use named parameters.
Feb 11 2020
On Tue, Feb 11, 2020 at 5:30 AM Arine via Digitalmars-d <digitalmars-d puremagic.com> wrote:On Tuesday, 11 February 2020 at 09:46:35 UTC, Paolo Invernizzi wrote:As a library author, you can't control whether a client uses named arguments or not. You must assume that they might use them anywhere and everywhere. This is huge for phobos and druntime, which should have a major pass over all function argument names to achieve dignity before we set them in stone.Let's put It simple, and let's boil this down to essential: there's MORE probability of FUTURE breakage with named parameters, and that's a fact.Only if you use the feature. That's part of the reason why I don't think you should be able to set a default of the middle argument. This just forces someone to use the feature if they a default parameter in the middle without the rest that follow also having default values. Other than that, if you don't want your code to break potentially from argument changes, then don't use named parameters.
Feb 11 2020
On Tuesday, 11 February 2020 at 19:02:38 UTC, Manu wrote:On Tue, Feb 11, 2020 at 5:30 AM Arine via Digitalmars-d <digitalmars-d puremagic.com> wrote:I meant that in terms of the user. A library author can choose what they want to do, they can break code just by changing the internal implementation that isn't exposed. Without changing the API. Ultimately you are at the mercy of the library author for basically everything anyways. If a library author doesn't take into consideration parameter names, the user can avoid breaking changes by simply not using them. Whether the author is right not to care about that can be debated, and whether it is their reponsibility. Anyways I agree, druntime and phobos names should be fixed, even if this DIP doesn't pass. Someone way back in the thread said something that I feel was overlooked. If this is only for readability, then creating a tool like in CLion seems like the better option. It'll have the same functionality (including the problem with template wrappers), won't burden library authors and you can opt in to use it. https://www.jetbrains.com/help/rider/Inline_Parameter_Name_Hints.html If you can get the desired effect without introducing a new feature, it should definitely be investigated. I also don't like that you can rearrange the parameters any which cause more problems trying to figure out which overload was called. The way it is currently written can make it more difficult to read code. I do want named parameters so that I don't have to write out all the default parameters just to get to use a different value for the last one. I can't think of a better solution than what he has, the way it is designed and used is simple. Named parameters would benefit it. https://github.com/ocornut/imgui/blob/v1.75/imgui.h#L451On Tuesday, 11 February 2020 at 09:46:35 UTC, Paolo Invernizzi wrote:As a library author, you can't control whether a client uses named arguments or not. You must assume that they might use them anywhere and everywhere. This is huge for phobos and druntime, which should have a major pass over all function argument names to achieve dignity before we set them in stone.Let's put It simple, and let's boil this down to essential: there's MORE probability of FUTURE breakage with named parameters, and that's a fact.Only if you use the feature. That's part of the reason why I don't think you should be able to set a default of the middle argument. This just forces someone to use the feature if they set a default parameter in the middle without the rest that follow also having default values. Other than that, if you don't want your code to break potentially from argument changes, then don't use named parameters.
Feb 13 2020
On Tuesday, 11 February 2020 at 09:46:35 UTC, Paolo Invernizzi wrote:On Tuesday, 11 February 2020 at 09:27:52 UTC, Andrea Fontana wrote:Yes, precisely... I was a bit circumspect about named arguments (coming from the C world, I don't use them, and don't feel the need to), and I was agreeing with Jonathan point of view. But I've changed my mind about it: I reckon naming things is quite important when writing a library. So that feature would make you think twice before naming a parameter, and care about how you name (and therefore design) things. So sure, it can break stuff, so that would probably be good if we could annotate parameter names with 'deprecated'. And replacing the awkward 'Flag' template is a nice plus. Therefore I'm all for that DIP (and we can probably wait later for a design working with variadic arguments).If package dependencies are used correctly nothing is break :) AndreaWhat I mean, is that multiple authors can be involved in the necessary fix: it's not a matter of find/replace on your own codebase. Let's put It simple, and let's boil this down to essential: there's MORE probability of FUTURE breakage with named parameters, and that's a fact.
Feb 11 2020
On Tuesday, 11 February 2020 at 09:46:35 UTC, Paolo Invernizzi wrote:Let's put It simple, and let's boil this down to essential: there's MORE probability of FUTURE breakage with named parameters, and that's a fact.That's true for every dip we approve, not only for named paramaters.
Feb 11 2020
On Tuesday, 11 February 2020 at 14:05:08 UTC, Andrea Fontana wrote:On Tuesday, 11 February 2020 at 09:46:35 UTC, Paolo Invernizzi wrote:No, there could be language improvements introduced with breaking changes, like the final-by-default that I endlessly put on the table as an example, that turns D into a language that's more resilient to breaking changes, on the contrary of named parameters.Let's put It simple, and let's boil this down to essential: there's MORE probability of FUTURE breakage with named parameters, and that's a fact.That's true for every dip we approve, not only for named paramaters.
Feb 11 2020
On Mon, Feb 10, 2020 at 1:55 PM jmh530 via Digitalmars-d <digitalmars-d puremagic.com> wrote:On Monday, 10 February 2020 at 21:41:02 UTC, Manu wrote:We deprecate and rename things all the time. If this DIP is accepted, I think it would be the case that we need a working pattern to deprecate argument names the same as we can with function names today. We can't use alias, because names are not part of the signature. We can't use overloads as backwards-compatibility wrappers, because they're ambiguous calls (again, because names are not pert of the signature). Calcification of API will increase. Poor name choices will be cemented in. On Mon, Feb 10, 2020 at 2:00 PM 12345swordy via Digitalmars-d <digitalmars-d puremagic.com> wrote:[snip] It's a huge problem today when a bad choice of function name is calcified; we'll be multiplying the probability of making bad naming choices by 2-3x. We can correct a bad function name by renaming it and producing a deprecated alias for the old name. We have no such way to correct a change in parameter name; we can't use alias because the parameter names are not part of the signature. Don't ignore the material issue I've shown that demands one of the 2 responses I suggested. If you push for acceptable of this DIP, then I think you must have a response to my primary issue.I was leaning towards favoring this DIP, as I frequently use named arguments in R and like the flexibility they offer in some cases. However, I came across two functions, written in python, at work. One takes a parameter and the other takes a slightly different parameter name. No good reason why these two do not use the same parameter names. They should be the same. However, python has named arguments for everything, so changing the names would mean that any code that uses the named version breaks. It definitely would make people much more conservative about changing their functions.On Monday, 10 February 2020 at 21:41:02 UTC, Manu wrote:Ummm... you're saying bad API names has a "very low probability"? Finish this sentence: "There are 2 hard problems in computer science..." I mean, I'm constantly tweaking API's for intuitive appeal. Programmers do this _all the time_.It's a huge problem today when a bad choice of function name is calcified; we'll be multiplying the probability of making bad naming choices by 2-3x.Which is a no big deal when the probability is very low to big with.We literally have two named arguments DIP that are postponed for this DIP. The discussion has been made so many times already in which your concerns and objections has brought up time and time again. Which frankly I don't have time nor the energy to argue in favor it again when you can look into those discussions threads already.I've never posted a single comment in a named argument thread. It's just not a thing I care about. I commented today because I feel like this DIP has a high probability of acceptance (because Walter wrote it), and I wanted to understand what was about to happen. I'm still mostly ambivalent about this, but I'm concerned you're still carefully avoiding my key concern; I showed an entire class of code that will be broken, you need to have a response to that. Basically everything I've ever written in a professional capacity will cease working if clients can call with named arguments.named arguments.They didn't have a decade of existing and important code that will break. I think accepting this DIP must be coupled with a recommended pattern to address the code I described, because it will be broken, and must be migrated. On Mon, Feb 10, 2020 at 2:10 PM Adam D. Ruppe via Digitalmars-d <digitalmars-d puremagic.com> wrote:On Monday, 10 February 2020 at 20:50:40 UTC, Manu wrote:I don't understand... ?Not being able to easily produce call shims or wrappers is a huge loss without some sort of solution analogous to existing reflection tools.This does not occur.
Feb 10 2020
On Monday, 10 February 2020 at 23:48:05 UTC, Manu wrote:Ummm... you're saying bad API names has a "very low probability"? Finish this sentence: "There are 2 hard problems in computer science..."Off by 1 errors? :)I mean, I'm constantly tweaking API's for intuitive appeal. Programmers do this _all the time_.Agreed. If it's any conciliation (i assume probably not but anyway), in swift you take a little bit more time to name things, but in my experience maintainability goes up 10x. Also, it has not really been an issue when doing scala or kotlin.We literally have two named arguments DIP that are postponed for this DIP. The discussion has been made so many times already in which your concerns and objections has brought up time and time again. Which frankly I don't have time nor the energy to argue in favor it again when you can look into those discussions threads already.I've never posted a single comment in a named argument thread. It's just not a thing I care about. I commented today because I feel like this DIP has a high probability of acceptance (because Walter wrote it), and I wanted to understand what was about to happen. I'm still mostly ambivalent about this, but I'm concerned you're still carefully avoiding my key concern; I showed an entire class of code that will be broken, you need to have a response to that. Basically everything I've ever written in a professional capacity will cease working if clients can call with named arguments.to named arguments.They didn't have a decade of existing and important code that will break.
Feb 10 2020
On Monday, 10 February 2020 at 23:48:05 UTC, Manu wrote:I showed an entire class of code that will be broken, you need to have a response to that.Take a look at how easy it is to write a full forwarder function: https://forum.dlang.org/post/cfcgecteoeynumsamjwe forum.dlang.org Note that the parameter names of the wrapper as seen from the outside (or even the inside if you fetch it off that tuple) are identical to the original. This has been defined in the language for years.
Feb 10 2020
On Monday, 10 February 2020 at 21:54:53 UTC, jmh530 wrote:On Monday, 10 February 2020 at 21:41:02 UTC, Manu wrote:<snip>[...]I was leaning towards favoring this DIP, as I frequently use named arguments in R and like the flexibility they offer in some cases. However, I came across two functions, written in python, at work. One takes a parameter and the other takes a slightly different parameter name. No good reason why these two do not use the same parameter names. They should be the same.However, python has named arguments for everything,Nope: https://www.python.org/dev/peps/pep-0570/
Feb 20 2020
On Thursday, 20 February 2020 at 11:00:16 UTC, Atila Neves wrote:[snip] Nope: https://www.python.org/dev/peps/pep-0570/1) Pep 570 is opt-in*. It gives you a bit more control so you can have positional-only and key-word only arguments. However, if you do not opt-in, then python still has a mixed of positional and named arguments for everything. See the standard_arg function in function examples: https://www.python.org/dev/peps/pep-0570/#function-examples In particular, I was thinking of situation where you have two functions def foo(arg1, arg2): def bar(arg1 other1): The following code is completely valid, both pre and post pep 570 foo(a, b) bar(a, b) foo(arg2=b, arg1=a) bar(other1=b, arg1=a) In my case, I was noticing that other1 is a lot like arg2, so you want to change other1's name to arg2. However, that will break the last line. Under pep 570, you could have instead written def foo(arg1, arg2, /): def bar(arg1 other1, /): and it won't break when you re-name it, but then you can't use the last two lines. Alternately, if try to use something like def foo(*, arg1, arg2): def bar(*, arg1 other1): then the first two lines calling foo and bar won't work. So even under pep 570, you would still be breaking code to re-name it. The problem comes from the standard method of mixing positional or keyword arguments. 2) Referring again to the pep 570 function examples, they have def combined_example(pos_only, /, mixed, *, kwd_only): where mixed (called standard in their example) is the mix of positional and keyword arguments. If D were to move in this direction, then we would have a similar function like void combined_example(Type1 pos_only, /, Type2 mixed, *, Type3 kwd_only) The only thing I would change is that pos_only should remain the default. So that would imply that the python function examples would instead be something like below in D. void standard_arg(Type1 pos_only) void mixed_arg(/, Type2 mixed) void kwd_only_arg(*, Type3 kwd_only) This would make named arguments opt-in and reduce the risk of people causing code breakage by changing APIs. One could start with just the mixed and consider adding the keyword only approach in the future if people want/need it. * That pep only was implemented in Python 3.8, which only came out in October of last year, I think I'm using 3.7 at work...so admittedly less familiar with it.
Feb 20 2020
On Thursday, 20 February 2020 at 11:59:13 UTC, jmh530 wrote:On Thursday, 20 February 2020 at 11:00:16 UTC, Atila Neves wrote:That's the exact reason why they proposed 570: having named argument is not alway a win.[snip] Nope: https://www.python.org/dev/peps/pep-0570/1) Pep 570 is opt-in*. It gives you a bit more control so you can have positional-only and key-word only arguments. However, if you do not opt-in, then python still has a mixed of positional and named arguments for everything. See the standard_arg function in function examples:
Feb 20 2020
On Thursday, 20 February 2020 at 14:49:42 UTC, Paolo Invernizzi wrote:On Thursday, 20 February 2020 at 11:59:13 UTC, jmh530 wrote:I don't think nor do I expect that people would used named arguments all the time when using another persons code. -AlexOn Thursday, 20 February 2020 at 11:00:16 UTC, Atila Neves wrote:That's the exact reason why they proposed 570: having named argument is not alway a win.[snip] Nope: https://www.python.org/dev/peps/pep-0570/1) Pep 570 is opt-in*. It gives you a bit more control so you can have positional-only and key-word only arguments. However, if you do not opt-in, then python still has a mixed of positional and named arguments for everything. See the standard_arg function in function examples:
Feb 20 2020
On Thursday, 20 February 2020 at 15:34:31 UTC, 12345swordy wrote:On Thursday, 20 February 2020 at 14:49:42 UTC, Paolo Invernizzi wrote:*Unless it is mandate by the language obviously* -AlexOn Thursday, 20 February 2020 at 11:59:13 UTC, jmh530 wrote:I don't think nor do I expect that people would used named arguments all the time when using another persons code. -AlexOn Thursday, 20 February 2020 at 11:00:16 UTC, Atila Neves wrote:That's the exact reason why they proposed 570: having named argument is not alway a win.[snip] Nope: https://www.python.org/dev/peps/pep-0570/1) Pep 570 is opt-in*. It gives you a bit more control so you can have positional-only and key-word only arguments. However, if you do not opt-in, then python still has a mixed of positional and named arguments for everything. See the standard_arg function in function examples:
Feb 20 2020
On Thursday, 20 February 2020 at 15:34:31 UTC, 12345swordy wrote:[snip] I don't think nor do I expect that people would used named arguments all the time when using another persons code. -AlexWhat's that saying? If some code can be written, it will be written. Regardless, it's a problem even for your own code too. If you have a big code base that uses a mix of positional and keyword arguments, then changing the names of function parameters causes code to break.
Feb 20 2020
On Thursday, 20 February 2020 at 15:51:57 UTC, jmh530 wrote:On Thursday, 20 February 2020 at 15:34:31 UTC, 12345swordy wrote:Which it is trivial to fix, if you have right tools. -Alex[snip] I don't think nor do I expect that people would used named arguments all the time when using another persons code. -AlexWhat's that saying? If some code can be written, it will be written. Regardless, it's a problem even for your own code too. If you have a big code base that uses a mix of positional and keyword arguments, then changing the names of function parameters causes code to break.
Feb 20 2020
On Monday, 10 February 2020 at 21:41:02 UTC, Manu wrote:On Mon, Feb 10, 2020 at 1:30 PM 12345swordy via Digitalmars-d <digitalmars-d puremagic.com> wrote:Which is a no big deal when the probability is very low to big with. Besides I don't need to justified it to you when are not the person who I need to be convinced in order for the dip to be accepted. We literally have two named arguments DIP that are postponed for this DIP. The discussion has been made so many times already in which your concerns and objections has brought up time and time again. Which frankly I don't have time nor the energy to argue in favor it again when you can look into those discussions threads already. named arguments. -AlexOn Monday, 10 February 2020 at 21:17:45 UTC, Manu wrote:It's a huge problem today when a bad choice of function name is calcified; we'll be multiplying the probability of making bad naming choices by 2-3x.On Mon, Feb 10, 2020 at 1:05 PM 12345swordy via Digitalmars-d <digitalmars-d puremagic.com> wrote:Yes, I have encounter the "API breakage" counter argument in other threads already. Still not convinced that it is a big issue as they make it out to be.On Monday, 10 February 2020 at 20:45:22 UTC, Manu wrote:I've seen some arguments, but I haven't understood them personally. I don't have a feel for their value, I can't judge that. I have described an important material loss associated with this. I'd like to see that important issue addressed in the form of "use this pattern instead" or, "we accept we are abandoning that important pattern, we feel it was less important than this DIP, and we accept code that uses that pattern will be broken", which, incidentally, is almost all D code I've ever written in a professional capacity... :/ I also have a fear that where making parameter names part of the API; renaming parameter == breaking change, this feels bad to me. It's resistant to improving API clarity over time. In my experience, API clarity is an ongoing maintenance challenge, where your poor choice in names is only discovered some time later as you have experience with other humans sense of intuition differing from your own initial judgement. That argument is about equally washy as your core argument, except from my personal point of view, I know that my argument here absolutely applies to me frequently over decades of experience, while I've never wanted names arguments once; so weighing the value judgement in that particular compromise seems obvious to me.On Mon, Feb 10, 2020 at 11:50 AM 12345swordy via Digitalmars-d <digitalmars-d puremagic.com> wrote:Manu, it boils down to mainly experience when it comes to wanting named arguments. I have argue in favor of them in the past already in other DIP. I have no interest of repeating them.On Monday, 10 February 2020 at 19:38:34 UTC, Manu wrote:That feels like a pretty washy justification.On Thu, Feb 6, 2020 at 7:34 PM Jonathan M Davis via Digitalmars-d <digitalmars-d puremagic.com> wrote:For me personalty, readability\reliability is a huge factor here. Knowing what values should go to where is a big plus for me, when dealing with default arguments. I the default parameters prevent me sending values to the wrong parameter. -Alex[...]I don't have any horse in this race... but I do just want to echo that I don't understand this feature at all. I don't know what it's for. I've never felt I wanted named arguments personally, and Jonathan's criticism feels very real to me. [...]
Feb 10 2020
On Monday, 10 February 2020 at 21:29:41 UTC, 12345swordy wrote:Yes, I have encounter the "API breakage" counter argument in other threads already. Still not convinced that it is a big issue as they make it out to be.I don't know since when you are around in D-land, but I'm here since pre-1.0. Not ad hominem, but believe me, I think it's difficult to understand the immane efforts to convince the leadership that breakage for a solid reason is not an evil thing. The pendulum is waving between "breakage is not even taken in account" to "let's introduce more ways to have MORE breakage opportunity in the future". Maybe it's not a "bit issue" for someone, Walter included, but that's non sense, plain and simple. Until I will see a shift from 'virtual by default' to 'final by default' mentality, aka let's try to reduce FUTURE opportunity for breakage, I will push toward that direction. /P
Feb 11 2020
On Tuesday, 11 February 2020 at 09:15:05 UTC, Paolo Invernizzi wrote:On Monday, 10 February 2020 at 21:29:41 UTC, 12345swordy wrote:Then use cpp if you hate future code breakage that much. The appeal of d to me is that it is not afraid to break code if it turns out to be a bad idea or that the improvements outweigh the breakage. -AlexYes, I have encounter the "API breakage" counter argument in other threads already. Still not convinced that it is a big issue as they make it out to be.I don't know since when you are around in D-land, but I'm here since pre-1.0. Not ad hominem, but believe me, I think it's difficult to understand the immane efforts to convince the leadership that breakage for a solid reason is not an evil thing. The pendulum is waving between "breakage is not even taken in account" to "let's introduce more ways to have MORE breakage opportunity in the future". Maybe it's not a "bit issue" for someone, Walter included, but that's non sense, plain and simple. Until I will see a shift from 'virtual by default' to 'final by default' mentality, aka let's try to reduce FUTURE opportunity for breakage, I will push toward that direction. /P
Feb 11 2020
On Tuesday, 11 February 2020 at 14:22:48 UTC, 12345swordy wrote:Then use cpp if you hate future code breakage that much.I don't go down that rabbit hole ... I've seen it too many times here. I think I've exposed my complains on named parameters enough, and I think in a clear manner, so I will stop arguing here. But, as usual, I'm listening to argumentation, as I try to discuss to understand better a topic
Feb 11 2020
On Tuesday, 11 February 2020 at 14:31:51 UTC, Paolo Invernizzi wrote:On Tuesday, 11 February 2020 at 14:22:48 UTC, 12345swordy wrote:What rabbit hole are you talking about here!? The cpp committee have religious like zeal when it comes to backwards compatibility. You want d to have that mentality as well? -AlexThen use cpp if you hate future code breakage that much.I don't go down that rabbit hole ... I've seen it too many times here.
Feb 11 2020
On Tuesday, 11 February 2020 at 14:45:30 UTC, 12345swordy wrote:On Tuesday, 11 February 2020 at 14:31:51 UTC, Paolo Invernizzi wrote:Probably I'm not able to explain myself clearly, so my fault ... let's try in this way. - I'm not against changing D language specifications or Phobos with breaking changes, on the contrary, I'm an historical baker of doing it also with _major_ breaking changes, in times where talking about "breaking customer code in ANY way" was an heresy :-P - Stated that, and coming back to named arguments, I prefer a language that encourage writing code that's difficult to break: virtual-by-default, for example, is against that principle. You should "explicitly" mark the methods that are parts of the API with virtual, turning encapsulation the default, and not the way round. - The fact that fields _names_ are already part of the API is _not_ an excuse to add more stuff like that, with named parameters. The "he is doing wrong, so I can do wrong as well" is not an argumentation (and add to that "I've never had complains on that in other languages") My reasoning is that, since months ago: a) breaking user codebase, in any way, was BAD b) so, a language feature that try to minimise (a) is GOOD c) but now, we want to improve the language, so we can _sometime_ go against rule (a) ... why rule (b) is not longer valid today? what is the _strong_ reason for turning D in a language _less_ robust to code refactories, encouraging a small and encapsulated API? please, be sure to reply only if the first part of the post is clear enough ... :-)On Tuesday, 11 February 2020 at 14:22:48 UTC, 12345swordy wrote:What rabbit hole are you talking about here!? The cpp committee have religious like zeal when it comes to backwards compatibility. You want d to have that mentality as well? -AlexThen use cpp if you hate future code breakage that much.I don't go down that rabbit hole ... I've seen it too many times here.
Feb 11 2020
On Tuesday, 11 February 2020 at 15:05:48 UTC, Paolo Invernizzi wrote:On Tuesday, 11 February 2020 at 14:45:30 UTC, 12345swordy wrote:Then don't rename the arguments at all if you don't want to break userspace. Same principle goes to renaming functions. -Alex[...]Probably I'm not able to explain myself clearly, so my fault ... let's try in this way. [...]
Feb 11 2020
On Tuesday, 11 February 2020 at 15:10:35 UTC, 12345swordy wrote:On Tuesday, 11 February 2020 at 15:05:48 UTC, Paolo Invernizzi wrote:That's exactly the point. If you don't change anything, you break anything. The more you _can_ change _without_ breaking other code is proper encapsulation, and with this DIP the amount of things that you _can't_ change is just increasing. Named arguments _enlarge_ the amount of code that you are exposing and that you _can't_ change without breaking someone else code.On Tuesday, 11 February 2020 at 14:45:30 UTC, 12345swordy wrote:Then don't rename the arguments at all if you don't want to break userspace. Same principle goes to renaming functions. -Alex[...]Probably I'm not able to explain myself clearly, so my fault ... let's try in this way. [...]
Feb 11 2020
On Tuesday, 11 February 2020 at 15:26:41 UTC, Paolo Invernizzi wrote:On Tuesday, 11 February 2020 at 15:10:35 UTC, 12345swordy wrote:If you find yourself in a situation that you end up renaming the arguments over and over again, then you got bigger issues to worry about besides named arguments. -AlexOn Tuesday, 11 February 2020 at 15:05:48 UTC, Paolo Invernizzi wrote:That's exactly the point. If you don't change anything, you break anything. The more you _can_ change _without_ breaking other code is proper encapsulation, and with this DIP the amount of things that you _can't_ change is just increasing. Named arguments _enlarge_ the amount of code that you are exposing and that you _can't_ change without breaking someone else code.On Tuesday, 11 February 2020 at 14:45:30 UTC, 12345swordy wrote:Then don't rename the arguments at all if you don't want to break userspace. Same principle goes to renaming functions. -Alex[...]Probably I'm not able to explain myself clearly, so my fault ... let's try in this way. [...]
Feb 11 2020
On Tuesday, 11 February 2020 at 16:26:59 UTC, 12345swordy wrote:If you find yourself in a situation that you end up renaming the arguments over and over again, then you got bigger issues to worry about besides named arguments. -AlexOk, that's enough for me
Feb 11 2020
On Tuesday, 11 February 2020 at 16:37:20 UTC, Paolo Invernizzi wrote:On Tuesday, 11 February 2020 at 16:26:59 UTC, 12345swordy wrote:opt-out of it. Breakage because of the function arguments has changed rarely happens in practice, and if it does happen, it is trivial to fix. I am going to be blunt on this, but some of the plausible scenarios being brought up is massively overblown to nonsense territory. One of the goals of Named Arguments is readability and so far no one has provided an alternative that is both useful and satisfactory to me. Opt-in named arguments? Makes the named arguments dead on arrival. -AlexIf you find yourself in a situation that you end up renaming the arguments over and over again, then you got bigger issues to worry about besides named arguments. -AlexOk, that's enough for me
Feb 11 2020
On 12/02/2020 6:46 AM, 12345swordy wrote:Opt-in named arguments? Makes the named arguments dead on arrival.If you start with opt-in, you can make it the default later on without breaking code. If you start with as default you cannot make it opt-in without breaking code. To not consider an opt-in design is quite frankly over confident that other languages experiences will map 1:1 to D.
Feb 11 2020
On Tuesday, 11 February 2020 at 17:58:48 UTC, rikki cattermole wrote:On 12/02/2020 6:46 AM, 12345swordy wrote:Yes, I remember and even participate in one of the dip that makes it opt-in. I consider that a terrible idea for reasons that I had already gave. -AlexOpt-in named arguments? Makes the named arguments dead on arrival.If you start with opt-in, you can make it the default later on without breaking code. If you start with as default you cannot make it opt-in without breaking code. To not consider an opt-in design is quite frankly over confident that other languages experiences will map 1:1 to D.
Feb 11 2020
On Monday, 10 February 2020 at 19:38:34 UTC, Manu wrote:I don't have any horse in this race... but I do just want to echo that I don't understand this feature at all. I don't know what it's for. I've never felt I wanted named argumentsIt's about my thoughts too. I think the question that needs to be solved by named parameters isn't strong enough. Optional named parameters are handy but D already offers a variety of methods in order to pass those. My fear as already other people pointed out is that named arguments will give D split personality. Some people adore named arguments and will use them for everything and others will not touch them. Libraries will use either methods and therefore make D feel schizophrenic. Also what would the implementation complexity be if this would be implemented?
Feb 10 2020
On Mon, Feb 10, 2020 at 12:25 PM IGotD- via Digitalmars-d <digitalmars-d puremagic.com> wrote:On Monday, 10 February 2020 at 19:38:34 UTC, Manu wrote:I doubt there's any meaningful implementation complexity inside DMD. I showed examples of how this split personality will affect authors of meta libraries. Not being able to easily produce call shims or wrappers is a huge loss without some sort of solution analogous to existing reflection tools. I also think 'renaming a parameter (to improve API clarity) == breaking API change' is a frustrating world to live in.I don't have any horse in this race... but I do just want to echo that I don't understand this feature at all. I don't know what it's for. I've never felt I wanted named argumentsIt's about my thoughts too. I think the question that needs to be solved by named parameters isn't strong enough. Optional named parameters are handy but D already offers a variety of methods in order to pass those. My fear as already other people pointed out is that named arguments will give D split personality. Some people adore named arguments and will use them for everything and others will not touch them. Libraries will use either methods and therefore make D feel schizophrenic. Also what would the implementation complexity be if this would be implemented?
Feb 10 2020
On Monday, 10 February 2020 at 20:50:40 UTC, Manu wrote:Not being able to easily produce call shims or wrappers is a huge loss without some sort of solution analogous to existing reflection tools.This does not occur.
Feb 10 2020
On Monday, 10 February 2020 at 19:38:34 UTC, Manu wrote:On Thu, Feb 6, 2020 at 7:34 PM Jonathan M Davis via Digitalmars-d <digitalmars-d puremagic.com> wrote:Before the DIP you'd call that like: wrapper(1, 2, 3); After the DIP you'd call that like: wrapper(1, 2, 3); Or are you saying meta must mirror parameter names as well? If so why? You can't do the default args today anyway, and I'm not sure if it's ever been a problem? I do agree that having something like ParametersWithNamesAndDefaultArgs is infeasible. Not only from a technical point of view but maintenance, programming burden, and migratory.On Wednesday, February 5, 2020 11:08:59 PM MST Mike Parker via Digitalmars-d wrote:I don't have any horse in this race... but I do just want to echo that I don't understand this feature at all. I don't know what it's for. I've never felt I wanted named arguments personally, and Jonathan's criticism feels very real to me. Here's a thought, which I haven't considered how it interacts with this DIP deeply, but it should be on the table: I do an immense amount of generative meta; generate wrappers, shims, bindings etc, which wrap existing functions. When the parameter names become part of the API, it means any such meta must pay extra attention to properly mirror the parameter names, and it must also carefully mirror the default args from the function it's wrapping. While most of my code takes care to do this anyway, there are cases where it's unnecessary and inconvenient. Some tasks can be completed with a tool like: ReturnType!originalFunction wrapper(alias originalFunction)(Parameters!originalFunction args) { // special sauce... return originalFunction(args); }[...]Well, I'll say again that I don't like the idea of having named arguments in the language, because it makes the parameter names part of the API, resulting in yet more bikeshedding and yet another thing that can't be changed without breaking existing code. Once in a while, named arguments may be useful, but for the most part, they're useful because a function has way too many parameters, in which case, the function should have been designed differently. Unfortunately, since it's Walter who created the DIP, and a number of people do like the idea of named arguments, I expect that some form of this will make it in, but I still think that it's a bad idea. - Jonathan M Davis
Feb 10 2020
On Tuesday, 11 February 2020 at 00:03:01 UTC, aliak wrote:I do agree that having something like ParametersWithNamesAndDefaultArgs is infeasible.I posted this earlier in this very thread: https://forum.dlang.org/post/cfcgecteoeynumsamjwe forum.dlang.org It is not only feasible... but trivial. ParametersWithNamesAndDefaultArgs is a *built-in language feature* - see 5.6 under here https://dlang.org/spec/expression.html#IsExpression Forwarding this stuff is not difficult at all.
Feb 10 2020
On Tuesday, 11 February 2020 at 00:40:58 UTC, Adam D. Ruppe wrote:On Tuesday, 11 February 2020 at 00:03:01 UTC, aliak wrote:Oh. Indeed :) Seems simple enough. But that darned __parameters thing. It's the devil. Reminded me of the first time I encountered that insomnia inducer, courtesy of H. S. Teoh (thanks HST) - https://forum.dlang.org/post/mailman.1565.1379620490.1719.digitalmars-d-learn puremagic.comI do agree that having something like ParametersWithNamesAndDefaultArgs is infeasible.I posted this earlier in this very thread: https://forum.dlang.org/post/cfcgecteoeynumsamjwe forum.dlang.org It is not only feasible... but trivial. ParametersWithNamesAndDefaultArgs is a *built-in language feature* - see 5.6 under here https://dlang.org/spec/expression.html#IsExpression Forwarding this stuff is not difficult at all.
Feb 10 2020
On Tue, Feb 11, 2020 at 12:58:23AM +0000, aliak via Digitalmars-d wrote: [...]But that darned __parameters thing. It's the devil. Reminded me of the first time I encountered that insomnia inducer, courtesy of H. S. Teoh (thanks HST) - https://forum.dlang.org/post/mailman.1565.1379620490.1719.digitalmars-d-learn puremagic.comWhoa. Just last week I was trying to look up this exact post, but couldn't, and now you show up with a convenient direct link to it. :-D Thanks!! And yeah, __parameters must be one of the darkest corners of D with the strangest, quirkiest semantics that anybody can imagine. It took me a LOT of trial-and-error and staring at Phobos code before I figured out that arcane black magic. (And even then, I'm still not 100% sure I got it all right...) T -- Life is complex. It consists of real and imaginary parts. -- YHL
Feb 10 2020
On Tuesday, 11 February 2020 at 01:18:08 UTC, H. S. Teoh wrote:It took me a LOT of trial-and-error and staring at Phobos code before I figured out that arcane black magic.Getting individual pieces out of it need some techniques (gotta use the slice technique to get param UDAs too btw). It isn't bad once you know them, but yeah, you aren't going to magically know it without help. But doing it to *forward* like Manu wants is *very* easy. Then you just treat it as a single block and it ALL automatically just works! This isn't impossible, it isn't error-prone, it isn't even particularly verbose. It is just one thing to use.
Feb 10 2020
On Mon, Feb 10, 2020 at 4:45 PM Adam D. Ruppe via Digitalmars-d <digitalmars-d puremagic.com> wrote:On Tuesday, 11 February 2020 at 00:03:01 UTC, aliak wrote:Sorry, I missed that above. Thanks for pointing this out. I did not realise __parameters populated the tuple with all that information... it's not even clear to me how that works! What manner of 'thing' exists in a tuple that can be a type, but also have a name and a default value associated with it? Whatever kind of thing the elements in the tuple are; this seems very useful, and I wanna know how to deploy this kind of thing generally. I don't even know what to call this... it's not a 'type' or a 'value', what 'kind of thing' is this? I guess it's a declaration alias. I wonder how this syntax is useful elsewhere...I do agree that having something like ParametersWithNamesAndDefaultArgs is infeasible.I posted this earlier in this very thread: https://forum.dlang.org/post/cfcgecteoeynumsamjwe forum.dlang.org It is not only feasible... but trivial. ParametersWithNamesAndDefaultArgs is a *built-in language feature* - see 5.6 under here https://dlang.org/spec/expression.html#IsExpression Forwarding this stuff is not difficult at all.
Feb 10 2020
On 2/10/20 2:38 PM, Manu wrote:I do an immense amount of generative meta; generate wrappers, shims, bindings etc, which wrap existing functions. When the parameter names become part of the API, it means any such meta must pay extra attention to properly mirror the parameter names, and it must also carefully mirror the default args from the function it's wrapping. While most of my code takes care to do this anyway, there are cases where it's unnecessary and inconvenient. Some tasks can be completed with a tool like: ReturnType!originalFunction wrapper(alias originalFunction)(Parameters!originalFunction args) { // special sauce... return originalFunction(args); } It is possible to write many forms of glue this way. If we must mirror the argument names and default arguments, you must fall back into string mixin territory, and the code to emit the proper prototype is complex and intensive. In a named-arguments world, shim's like the one I showed above are no longer valid where calling code would use named arguments.This has convinced me (along with reading the subsequent thread) that we shouldn't introduce named parameters until we can solve this problem. Whether it be via Timon's suggestion of having template tuples capture named parameters or some other mechanism. And the is(typeof(fn) P == __parameters) idea isn't the right approach either. It intercepts the parameter names based on what the *target* is, not on how it was *called*. Templates make decisions based on what they are given. -Steve
Feb 11 2020
On Thursday, 6 February 2020 at 06:08:59 UTC, Mike Parker wrote:This is the feedback thread for the first round of Community Review for DIP 1030, "Named Arguments": https://github.com/dlang/DIPs/blob/44b0d4ec0da6a2e797ede748fb1e81cd6db10371/DIPs/DIP1030.md 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... in other words, business as usual. However, if you have any specific feedback for how to improve the the proposal itself, then please post it in the feedback thread. The feedback thread will be the source for the review summary I 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 The review period will end at 11:59 PM ET on February 20, or when I make a post declaring it complete. Discussion in this thread may continue beyond that point. At the end of Round 1, if further review is deemed necessary, the DIP will be scheduled for another round of Community Review. Otherwise, it will be queued for the Final Review and Formal Assessment. Please stay on topic here. I will delete posts that are completely off topic.I'm curious what the current state of druntime/phobos is with parameter name consistency. I took a quick look at std.math in phobos to see what some of the current argument names are: auto conj(Num)(Num z) safe pure nothrow nogc auto abs(Num)(Num x) nogc pure nothrow real cos(real x) safe pure nothrow nogc { pragma(inline, true); return core.math.cos(x); } auto sin(creal z) safe pure nothrow nogc auto sin(ireal y) safe pure nothrow nogc So we have some of this: conj(z:someValue); abs(x:someValue); sin(y:someValue); Now that parameter names are apart of the function's API, this inconsistency starts to matter as changing it breaks the API. Will druntime/phobos try to come up with standard names for these situations? Will we try to fix these names before integrating support for named parameters? If we need to change names later, what will the policy be for druntime/phobos for making parameter name changes when inconsistencies are discovered? Also consider the case when overloads use different parameter names. std.math.sin uses 'z' for creal arguments and 'y' for ireal arguments. This can cause issues during refactor as one needs to re-check all parameter names when changing types of arguments. i.e. sin(z:someValue); If you change the type of someValue from creal to ireal, then this would still call the creal overload, perhaps unexpectedly.
Feb 10 2020
On Monday, 10 February 2020 at 23:20:34 UTC, Jonathan Marler wrote:On Thursday, 6 February 2020 at 06:08:59 UTC, Mike Parker wrote:I took some time to go through the "std.array" module to see how many potential issues it might have. Here's what I saw: ------------------------------------------------------------------------------- different overloads of split use different parameter names -------------------------------------------------------------------------------This is the feedback thread for the first round of Community Review for DIP 1030, "Named Arguments": https://github.com/dlang/DIPs/blob/44b0d4ec0da6a2e797ede748fb1e81cd6db10371/DIPs/DIP1030.md 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... in other words, business as usual. However, if you have any specific feedback for how to improve the the proposal itself, then please post it in the feedback thread. The feedback thread will be the source for the review summary I 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 The review period will end at 11:59 PM ET on February 20, or when I make a post declaring it complete. Discussion in this thread may continue beyond that point. At the end of Round 1, if further review is deemed necessary, the DIP will be scheduled for another round of Community Review. Otherwise, it will be queued for the Final Review and Formal Assessment. Please stay on topic here. I will delete posts that are completely off topic.I'm curious what the current state of druntime/phobos is with parameter name consistency. I took a quick look at std.math in phobos to see what some of the current argument names are: auto conj(Num)(Num z) safe pure nothrow nogc auto abs(Num)(Num x) nogc pure nothrow real cos(real x) safe pure nothrow nogc { pragma(inline, true); return core.math.cos(x); } auto sin(creal z) safe pure nothrow nogc auto sin(ireal y) safe pure nothrow nogc So we have some of this: conj(z:someValue); abs(x:someValue); sin(y:someValue); Now that parameter names are apart of the function's API, this inconsistency starts to matter as changing it breaks the API. Will druntime/phobos try to come up with standard names for these situations? Will we try to fix these names before integrating support for named parameters? If we need to change names later, what will the policy be for druntime/phobos for making parameter name changes when inconsistencies are discovered? Also consider the case when overloads use different parameter names. std.math.sin uses 'z' for creal arguments and 'y' for ireal arguments. This can cause issues during refactor as one needs to re-check all parameter names when changing types of arguments. i.e. sin(z:someValue); If you change the type of someValue from creal to ireal, then this would still call the creal overload, perhaps unexpectedly.S[] split(S)(S s) safe pure auto split(alias isTerminator, Range)(Range range) auto split(Range, Separator)(Range range, Separator sep)split(s: value); split(range: value); ------------------------------------------------------------------------------- different overloads of "array" use different parameter names -------------------------------------------------------------------------------ForeachType!Range[] array(Range)(Range r) ForeachType!(PointerTarget!Range)[] array(Range)(Range r) CopyTypeQualifiers!(ElementType!String,dchar)[] array(String)(scope String str)array(r: value); array(str: value); ------------------------------------------------------------------------------- Generic Range parameters use many different names 'r', 'range', 'ror', 'stuff', 's' -------------------------------------------------------------------------------auto split(alias isTerminator, Range)(Range range) ForeachType!Range[] array(Range)(Range r) ForeachType!(PointerTarget!Range)[] array(Range)(Range r) ElementEncodingType!(ElementType!RoR)[] join(RoR, R)(RoR ror, scope R sep) ElementEncodingType!(ElementType!RoR)[] join(RoR, E)(RoR ror, scope E sep) ElementEncodingType!(ElementType!RoR)[] join(RoR)(RoR ror) T[] replace(T, Range)(T[] subject, size_t from, size_t to, Range stuff) ElementType!S[] replicate(S)(S s, size_t n)split(r: value); array(range: value); join(ror: value); replace(subject: value1, from: value2, to: value3, stuff: value4); replicate(s: value, n: 100); ------------------------------------------------------------------------------- functions that take 2 arguments but have different parameter names -------------------------------------------------------------------------------CommonType!(T[], U[]) overlap(T, U)(T[] a, U[] b) trusted pure nothrow bool sameHead(T)(in T[] lhs, in T[] rhs) pure nothrow bool sameTail(T)(in T[] lhs, in T[] rhs)overlay(a: value1, b: value2); sameHead(lhs: value1, rhs: value2); ------------------------------------------------------------------------------- sometimes an array is passed with 'a', sometimes with 'array', sometimes 'arr' -------------------------------------------------------------------------------void insertInPlace(T, U...)(ref T[] array, size_t pos, U stuff) auto staticArray(size_t n, T)(scope T a) auto staticArray(size_t n, T)(scope T a, out size_t rangeLength) Appender!(E[]) appender(A : E[], E)(auto ref A array) RefAppender!(E[]) appender(P : E[]*, E)(P arrayPtr) struct Appender(A) this(A arr) trusted pure nothrowinsertInPlace(array: value1, pos: value2, stuff: value3); staticArray(a: value); Appender(arr: value); ------------------------------------------------------------------------------- Appender functions use inconsistent parameter names -------------------------------------------------------------------------------struct Appender(A) void reserve(size_t newCapacity) private void ensureAddable(size_t nelems)appender.reserve(newCapacity: value); appender.ensureAddable(nelems: value); ------------------------------------------------------------------------------- Sometimes "length" is spelled out, sometimes it is abbreviated to "len" -------------------------------------------------------------------------------auto staticArray(size_t n, T)(scope T a, out size_t rangeLength) private size_t appenderNewCapacity(size_t TSizeOf)(size_t curLen, size_t reqLen) safe pure nothrowstaticArray(a: value, rangeLength: value2); appenderNewCapacity(curLen: 100, reqLen: 200); ------------------------------------------------------------------------------- appender overloads use different parameter names -------------------------------------------------------------------------------Appender!(E[]) appender(A : E[], E)(auto ref A array) RefAppender!(E[]) appender(P : E[]*, E)(P arrayPtr)appender(array: value); appender(arrayPtr: value);
Feb 10 2020
On Mon, Feb 10, 2020 at 4:05 PM Jonathan Marler via Digitalmars-d <digitalmars-d puremagic.com> wrote:On Monday, 10 February 2020 at 23:20:34 UTC, Jonathan Marler wrote:Mmmm, wow. Yeah, it seems an important pre-req for this DIP to be accepted is that all standard libraries should have a major pass to make sure all parameter names are dignified names that we can confidently stand behind for the rest of time, and also that standard names for common parameters are decided and proliferated. "There are 2 hard problems in computer science..."On Thursday, 6 February 2020 at 06:08:59 UTC, Mike Parker wrote:I took some time to go through the "std.array" module to see how many potential issues it might have. Here's what I saw: ------------------------------------------------------------------------------- different overloads of split use different parameter names -------------------------------------------------------------------------------This is the feedback thread for the first round of Community Review for DIP 1030, "Named Arguments": https://github.com/dlang/DIPs/blob/44b0d4ec0da6a2e797ede748fb1e81cd6db10371/DIPs/DIP1030.md 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... in other words, business as usual. However, if you have any specific feedback for how to improve the the proposal itself, then please post it in the feedback thread. The feedback thread will be the source for the review summary I 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 The review period will end at 11:59 PM ET on February 20, or when I make a post declaring it complete. Discussion in this thread may continue beyond that point. At the end of Round 1, if further review is deemed necessary, the DIP will be scheduled for another round of Community Review. Otherwise, it will be queued for the Final Review and Formal Assessment. Please stay on topic here. I will delete posts that are completely off topic.I'm curious what the current state of druntime/phobos is with parameter name consistency. I took a quick look at std.math in phobos to see what some of the current argument names are: auto conj(Num)(Num z) safe pure nothrow nogc auto abs(Num)(Num x) nogc pure nothrow real cos(real x) safe pure nothrow nogc { pragma(inline, true); return core.math.cos(x); } auto sin(creal z) safe pure nothrow nogc auto sin(ireal y) safe pure nothrow nogc So we have some of this: conj(z:someValue); abs(x:someValue); sin(y:someValue); Now that parameter names are apart of the function's API, this inconsistency starts to matter as changing it breaks the API. Will druntime/phobos try to come up with standard names for these situations? Will we try to fix these names before integrating support for named parameters? If we need to change names later, what will the policy be for druntime/phobos for making parameter name changes when inconsistencies are discovered? Also consider the case when overloads use different parameter names. std.math.sin uses 'z' for creal arguments and 'y' for ireal arguments. This can cause issues during refactor as one needs to re-check all parameter names when changing types of arguments. i.e. sin(z:someValue); If you change the type of someValue from creal to ireal, then this would still call the creal overload, perhaps unexpectedly.S[] split(S)(S s) safe pure auto split(alias isTerminator, Range)(Range range) auto split(Range, Separator)(Range range, Separator sep)split(s: value); split(range: value); ------------------------------------------------------------------------------- different overloads of "array" use different parameter names -------------------------------------------------------------------------------ForeachType!Range[] array(Range)(Range r) ForeachType!(PointerTarget!Range)[] array(Range)(Range r) CopyTypeQualifiers!(ElementType!String,dchar)[] array(String)(scope String str)array(r: value); array(str: value); ------------------------------------------------------------------------------- Generic Range parameters use many different names 'r', 'range', 'ror', 'stuff', 's' -------------------------------------------------------------------------------auto split(alias isTerminator, Range)(Range range) ForeachType!Range[] array(Range)(Range r) ForeachType!(PointerTarget!Range)[] array(Range)(Range r) ElementEncodingType!(ElementType!RoR)[] join(RoR, R)(RoR ror, scope R sep) ElementEncodingType!(ElementType!RoR)[] join(RoR, E)(RoR ror, scope E sep) ElementEncodingType!(ElementType!RoR)[] join(RoR)(RoR ror) T[] replace(T, Range)(T[] subject, size_t from, size_t to, Range stuff) ElementType!S[] replicate(S)(S s, size_t n)split(r: value); array(range: value); join(ror: value); replace(subject: value1, from: value2, to: value3, stuff: value4); replicate(s: value, n: 100); ------------------------------------------------------------------------------- functions that take 2 arguments but have different parameter names -------------------------------------------------------------------------------CommonType!(T[], U[]) overlap(T, U)(T[] a, U[] b) trusted pure nothrow bool sameHead(T)(in T[] lhs, in T[] rhs) pure nothrow bool sameTail(T)(in T[] lhs, in T[] rhs)overlay(a: value1, b: value2); sameHead(lhs: value1, rhs: value2); ------------------------------------------------------------------------------- sometimes an array is passed with 'a', sometimes with 'array', sometimes 'arr' -------------------------------------------------------------------------------void insertInPlace(T, U...)(ref T[] array, size_t pos, U stuff) auto staticArray(size_t n, T)(scope T a) auto staticArray(size_t n, T)(scope T a, out size_t rangeLength) Appender!(E[]) appender(A : E[], E)(auto ref A array) RefAppender!(E[]) appender(P : E[]*, E)(P arrayPtr) struct Appender(A) this(A arr) trusted pure nothrowinsertInPlace(array: value1, pos: value2, stuff: value3); staticArray(a: value); Appender(arr: value); ------------------------------------------------------------------------------- Appender functions use inconsistent parameter names -------------------------------------------------------------------------------struct Appender(A) void reserve(size_t newCapacity) private void ensureAddable(size_t nelems)appender.reserve(newCapacity: value); appender.ensureAddable(nelems: value); ------------------------------------------------------------------------------- Sometimes "length" is spelled out, sometimes it is abbreviated to "len" -------------------------------------------------------------------------------auto staticArray(size_t n, T)(scope T a, out size_t rangeLength) private size_t appenderNewCapacity(size_t TSizeOf)(size_t curLen, size_t reqLen) safe pure nothrowstaticArray(a: value, rangeLength: value2); appenderNewCapacity(curLen: 100, reqLen: 200); ------------------------------------------------------------------------------- appender overloads use different parameter names -------------------------------------------------------------------------------Appender!(E[]) appender(A : E[], E)(auto ref A array) RefAppender!(E[]) appender(P : E[]*, E)(P arrayPtr)appender(array: value); appender(arrayPtr: value);
Feb 10 2020
On Monday, 10 February 2020 at 23:20:34 UTC, Jonathan Marler wrote:Now that parameter names are apart of the function's API,I'm not sure it's correct to say this, considering that parameter names have already been accessible using reflection for a while now. This is what allowed library implementations of named arguments to work. As such, effectively this DIP just adds some syntax sugar.
Feb 10 2020
On 2/10/2020 3:20 PM, Jonathan Marler wrote:I took a quick look at std.math in phobos to see what some of the current argument names are: auto conj(Num)(Num z) safe pure nothrow nogc auto abs(Num)(Num x) nogc pure nothrow real cos(real x) safe pure nothrow nogc { pragma(inline, true); return core.math.cos(x); } auto sin(creal z) safe pure nothrow nogc auto sin(ireal y) safe pure nothrow nogc So we have some of this: conj(z:someValue); abs(x:someValue); sin(y:someValue); Now that parameter names are apart of the function's API, this inconsistency starts to matterIt isn't inconsistent. In math, z=x+iy is normal notation, i.e. x for real numbers, y for imaginary, and z for complex. Besides, I doubt there's much of any point for using named parameters for those functions.
Feb 10 2020
On Tuesday, 11 February 2020 at 07:04:34 UTC, Walter Bright wrote:On 2/10/2020 3:20 PM, Jonathan Marler wrote:conj and abs are using template parameters. So if you're passing an imaginary number to conj you use "z", abs you use "x", and sin you use "y". ireal i; conj(z: i); abs(x: i); sin(y: i);I took a quick look at std.math in phobos to see what some of the current argument names are: auto conj(Num)(Num z) safe pure nothrow nogc auto abs(Num)(Num x) nogc pure nothrow real cos(real x) safe pure nothrow nogc { pragma(inline, true); return core.math.cos(x); } auto sin(creal z) safe pure nothrow nogc auto sin(ireal y) safe pure nothrow nogc So we have some of this: conj(z:someValue); abs(x:someValue); sin(y:someValue); Now that parameter names are apart of the function's API, this inconsistency starts to matterIt isn't inconsistent. In math, z=x+iy is normal notation, i.e. x for real numbers, y for imaginary, and z for complex.Besides, I doubt there's much of any point for using named parameters for those functions.True. I estimate around 75% of functions in general don't benefit from named parameters. So the question becomes, what do we do about parameter name inconsistency in these cases for the standard libraries? If we don't think named parameters are useful for a function, will we leave them be? If so, can we come up with a criteria we can use to determine when named parameters make sense? I think this would help greatly in this transition to named parameters to help avoid alot of the bikeshedding I see coming when this is enabled. I was also hoping to get some answers from the leadership to the other questions:For example, for math functions like the ones I mentioned, are we going to normalize on "x", "y" and "z" depending on the type? And if it's a template that could accept any type, what name would we use in that case? Of course, if the answer to the previous question is that we won't bother with functions that don't make sense with named parameters, then this is a bad example. But the question still stands for functions that do make sense, do you think we should come up with a standard set of names to promote consistency accross the standard libraries, and 3rd party libraries? Also these questions:Will druntime/phobos try to come up with standard names for these situations?Also came up with another question looking through some of the external function declarations in druntime like the ones in https://github.com/dlang/druntime/blob/master/src/core/sys/windows/winbase.d It looks like the parameter names have been stripped out for the windows functions. Do you think we should add parameter names in those functions? If we do want to add names, do you think we should we use the hungarian notation parameter names from windows, or no?Will we try to fix these names before integrating support for named parameters? If we need to change names later, what will the policy be for druntime/phobos for making parameter name changes when inconsistencies are discovered?
Feb 11 2020
On Tuesday, 11 February 2020 at 15:26:42 UTC, Jonathan Marler wrote:On Tuesday, 11 February 2020 at 07:04:34 UTC, Walter Bright wrote:Here's a better example: functions like move and memcpy that take source and destination arguments. Currently, move uses 'source" and "target", but memcpy uses "s2" and "s1".On 2/10/2020 3:20 PM, Jonathan Marler wrote:For example, for math functions like the ones I mentioned, are we going to normalize on "x", "y" and "z" depending on the type? And if it's a template that could accept any type, what name would we use in that case? Of course, if the answer to the previous question is that we won't bother with functions that don't make sense with named parameters, then this is a bad example. But the question still stands for functions that do make sense, do you think we should come up with a standard set of names to promote consistency accross the standard libraries, and 3rd party libraries?Will druntime/phobos try to come up with standard names for these situations?
Feb 11 2020
On 2/11/2020 8:35 AM, Paul Backus wrote:Here's a better example: functions like move and memcpy that take source and destination arguments. Currently, move uses 'source" and "target", but memcpy uses "s2" and "s1".The C99 Standard says: void *memcpy(void * restrict s1, const void * restrict s2, size_t n); which is what we will slavishly use for all Standard C library functions.
Feb 11 2020
On 2/11/2020 7:26 AM, Jonathan Marler wrote:True. I estimate around 75% of functions in general don't benefit from named parameters. So the question becomes, what do we do about parameter name inconsistency in these cases for the standard libraries? If we don't think named parameters are useful for a function, will we leave them be? If so, can we come up with a criteria we can use to determine when named parameters make sense? I think this would help greatly in this transition to named parameters to help avoid alot of the bikeshedding I see coming when this is enabled.Make some PRs to improve the consistency in advance, by all means.For example, for math functions like the ones I mentioned, are we going to normalize on "x", "y" and "z" depending on the type?Sounds reasonable to me. But keep in mind that this will also result in inconsistencies. For example, points will be (x,y,z) triplets.And if it's a template that could accept any type, what name would we use in that case?The most generous of the specializations.question still stands for functions that do make sense, do you think we should come up with a standard set of names to promote consistency accross the standard libraries, and 3rd party libraries?I find standard names for things, like `p` for generic pointer, and `s` for generic string, and `i` for generic integer, to be valuable. But blind adherence to such will cause trouble, because it's not practical to be entirely consistent.I wouldn't go crazy over this, but it would be nice to do it. Also, having good names for parameters is a good idea anyway.Will we try to fix these names before integrating support for named parameters?Initially, we shouldn't worry about fixing it because few will be using N.P. But later, no, we shouldn't be changing them.If we need to change names later, what will the policy be for druntime/phobos for making parameter name changes when inconsistencies are discovered?It looks like the parameter names have been stripped out for the windows functions. Do you think we should add parameter names in those functions? If we do want to add names, do you think we should we use the hungarian notation parameter names from windows, or no?Should use the names from the official Windows documentation. Ditto for all other APIs. Also, there's no rush to add parameter names to APIs that don't currently have them.
Feb 11 2020
On 2/10/2020 1:02 PM, Manu wrote:Just wanted to point out without muddying the feedback thread, that this response completely misses the point. The point is to have a wrapper for origFun which behaves exactly as the original function, but does something special inside. Saying you won't be able to call wrapper with named parameters is the actual point of the post. It would be good to have a response to the fact that it breaks the intention of perfect forwarding. An example: foo(a: 1, b:2); Now I want to replace all calls to foo with a special wrapper that logs all calls. alias foo = logCalls!(.foo); foo(a: 1, b:2); // error, cannot use named parameters with tuples. Is there a plan to mitigate this limitation? -SteveNamed arguments breaks this very important pattern:Named arguments will not match to ... parameters, so it won't break existing code, it just won't compile if you write new code that tries that.
Feb 11 2020
On Tuesday, 11 February 2020 at 13:52:35 UTC, Steven Schveighoffer wrote:Is there a plan to mitigate this limitation?I wrote about this in github comments when the dip pr was first opened: https://github.com/dlang/DIPs/pull/168#discussion_r324481363 lol actually you were the person to push back hardest! __traits(identifier) on the template param is a solid possibility, and the other push back is maybe making it opt-in... but with your __traits(identifier) add on.... no need for my weird struct thingy. So basically the template variadic params would then work identically to the __parameters result we already have (probably including the slice technique lol). There's precedent! That should absolutely work. And could be done right now to solve this in full - with the names being part of the variadic tuple it would forward to calls as well. I like it a lot. But I still think this DIP as-is is an OK addition without it. We can always remove the T... limitation later as well. though wow id really like to have it work.
Feb 11 2020
On 2/11/20 9:07 AM, Adam D. Ruppe wrote:On Tuesday, 11 February 2020 at 13:52:35 UTC, Steven Schveighoffer wrote:ha, I just pushed back on the idea of a custom struct coming in and the template having to deal with that in a special way ;) But my thoughts have evolved on the importance of this. I think it makes the DIP not worth it if we can't capture those calls properly. Note also: if the template parameters names are part of the tuple type, and therefore part of the template instantiation, we have an actual path to deprecations as well: Date makeDate(int year, int month, int day) {...} deprecated("Use better names please") auto makeDate(T...)(T args) if (containsArgName!("a", T) || containsArgName!("b", T) || containsArgName!("c", T)) { auto makeDateImpl(int a, int b, int c) { // remove names return .makeDate(a, b, c); } return makeDateImpl(args); }Is there a plan to mitigate this limitation?I wrote about this in github comments when the dip pr was first opened: https://github.com/dlang/DIPs/pull/168#discussion_r324481363 lol actually you were the person to push back hardest!__traits(identifier) on the template param is a solid possibility, and the other push back is maybe making it opt-in... but with your __traits(identifier) add on.... no need for my weird struct thingy. So basically the template variadic params would then work identically to the __parameters result we already have (probably including the slice technique lol). There's precedent! That should absolutely work. And could be done right now to solve this in full - with the names being part of the variadic tuple it would forward to calls as well. I like it a lot. But I still think this DIP as-is is an OK addition without it. We can always remove the T... limitation later as well.I think while it doesn't break currently existing code, it breaks the *intention* of code. Something that intends to be a perfect forward of an API can no longer EVER claim that. Manu is right, a whole lot of code out there exists solely to massage APIs, adding one nuance here or there. -Steve
Feb 11 2020
On 2/11/2020 5:52 AM, Steven Schveighoffer wrote:An example: foo(a: 1, b:2); Now I want to replace all calls to foo with a special wrapper that logs all calls. alias foo = logCalls!(.foo); foo(a: 1, b:2); // error, cannot use named parameters with tuples. Is there a plan to mitigate this limitation?Currently, no. The current plan is named arguments will not match to ... This leaves the door open to a future enhancement along those lines, which is better than trying to gin up an awkward solution.
Feb 11 2020
On 2/11/20 2:07 PM, Walter Bright wrote:On 2/11/2020 5:52 AM, Steven Schveighoffer wrote:I disagree. If you don't do something about this, the entire realm of wrapping types and functions becomes convoluted and sometimes impossible, because you can't wrap things and have them behave as the original thing as easily as you can today. If we can't figure out a solution, I would say we hold off on named parameters. D's major strength is compile-time introspection and code generation, and this DIP adds a whole new aspect of API that is off-limits to introspection. -SteveAn example: foo(a: 1, b:2); Now I want to replace all calls to foo with a special wrapper that logs all calls. alias foo = logCalls!(.foo); foo(a: 1, b:2); // error, cannot use named parameters with tuples. Is there a plan to mitigate this limitation?Currently, no. The current plan is named arguments will not match to ... This leaves the door open to a future enhancement along those lines, which is better than trying to gin up an awkward solution.
Feb 11 2020
On Tuesday, 11 February 2020 at 19:07:23 UTC, Walter Bright wrote:On 2/11/2020 5:52 AM, Steven Schveighoffer wrote:Sorry but this is another half backed implementation. Sasha.An example: foo(a: 1, b:2); Now I want to replace all calls to foo with a special wrapper that logs all calls. alias foo = logCalls!(.foo); foo(a: 1, b:2); // error, cannot use named parameters with tuples. Is there a plan to mitigate this limitation?Currently, no. The current plan is named arguments will not match to ... This leaves the door open to a future enhancement along those lines, which is better than trying to gin up an awkward solution.
Feb 12 2020