Allow using discards as ignored optional parameters #1897
Replies: 33 comments
-
Naming the arguments brings clarity and I often do it without being forced to. If C# was going to adopt this alternative approach which VB uses, would we want discards or just extra commas? |
Beta Was this translation helpful? Give feedback.
-
Extra commas in Vb.Net are difficilt to distinguish by human eye, especially when there are serveral blanck commas. "Disgards" is a good C# feature and it will be consistent to use rhem in all places where a variable or a parameter needs to be discarded.
|
Beta Was this translation helpful? Give feedback.
-
I think it is a sensible idea, and consistent with the language. On the other hand, using named parameters is already possible, and better code style. As such, we would be adding a feature which doesn't allow us to do anything we couldn't before, and encourages use of bad style. Hence this gets a 👎 from me. |
Beta Was this translation helpful? Give feedback.
-
@MohammadHamdyGhanem Do you have a reason to downvote @YairHalberstadt’s point? It makes sense to me and your downvote makes it look like you aren't happy with Yair's point but can't argue with it. |
Beta Was this translation helpful? Give feedback.
-
This would be a breaking change: int Factorial(int count = 2, int othervar = 0){
int result = 1;
for (int i = 1; i <= count; i++){
result *= i;
}
return result;
}
// elsewhere:
int _ = 5;
Console.WriteLine(Factorial(_, 1)); // 2 or 120? |
Beta Was this translation helpful? Give feedback.
-
@TheUnlocked |
Beta Was this translation helpful? Give feedback.
-
@TheUnlocked
We should propose that C# considers _ as a keyword and prevents using it as a name for variables, properties, methods, parameters.... etc. |
Beta Was this translation helpful? Give feedback.
-
Not necessarily. {
int _;
_ = 42; // assignment to variable called _
}
{
_ = 42; // discard
} This means that in your example, Maybe that would make it too confusing, but it wouldn't be a breaking change. |
Beta Was this translation helpful? Give feedback.
-
With this code, the author's intent is quite clear:
The alternative proposed here is quite opaque:
Only the original author of the code would know what this means without digging into the original definitions. |
Beta Was this translation helpful? Give feedback.
-
@theunrepentantgeek |
Beta Was this translation helpful? Give feedback.
-
No, I did not. I'm saying that the existing syntax we already have not only works perfectly well but is decidedly superior to this proosal.
Not every C# developer uses Visual Studio. Some don't use any IDE at all (not even Visual Studio Code) - they use simple text editors, either by choice or because they don't have the option. Any suggested syntax change for C# needs to stand on it's own without requiring scaffolding provided by tool support. |
Beta Was this translation helpful? Give feedback.
-
@theunrepentantgeek |
Beta Was this translation helpful? Give feedback.
-
Um, what? You can't just say, "Let's take out the already existing feature that makes this feature pointless out of discussion." No, this feature already exists, and it makes yours pointless, so it's staying in discussion.
No, three ways is actually a mess. I mean, how many ways are there to write properties? There's that many ways, not because the C# devs think writing code is a beautiful form of self expression, but because people kept getting tired of writing the longer boilerplate code. Python has their motto of there being one way, and only obvious way of doing something, and that's a good motto to follow to keep things simple. It would be very confusing to have all three ways. Besides, which code is more clear in meaning: AddAccount(_, _, _, _, _, _, _, 42);
AddAccount(, , , , , , , 42);
AddAccount(age: 42); You can see, the
so, why not "Why not" is a very weak argument and shows you don't know what you're talking about. But if you really wanna know, I'll keep going. C# features start off in the hole, by 100 points, and they have to earn 100 points to get out of it and to be taken seriously. That means that it has to be overwhelming positive to make it in.
Last time I checked... CreateAccount("Jane", 42); // Way #1
CreateAccount(age: 42); // Way #2 Soo, since there are already 2 ways, we don't need your feature right?
Not really. So far, the examples have shown it to be shorter, and even if it's longer, it's much quicker to type, because it's 1., less awkward, and 2., has IDE support to add them.
Not true. Just because something is superior to something else, doesn't mean it's superior to all other things in the field. For example, a day old glass of milk smells better than a 7 day old glass of milk, that's pretty apparent. That does not mean that a day old glass of milk smells so good that everyone keeps one in their room and smells it every chance they can. No, it still smells bad, just not as bad. He never said that optional parameters are the best way to program, and they are the most superior form and there's nothing bad that could ever exist. It's just very helpful with the
They're not.
Not true. The majority of the code is named methods, variables, members, etc. Besides that, if it was really full of unreadable symbols, wouldn't it be important to add more readabilty, hence making optional parameters more important, not worsen the issue, by adding more unreadable symbols?
The developers make the syntax, and if their nice, they'll add in the features we want to make it easier. That idea, is a complete privilege, not a right. |
Beta Was this translation helpful? Give feedback.
-
@willard720 Thanks |
Beta Was this translation helpful? Give feedback.
-
@MohammadHamdyGhanem
That's not how it works. If you use discarded arguments and then I view your code on GitHub or in Vim, I don't get a choice to use named arguments. |
Beta Was this translation helpful? Give feedback.
-
@DavidArno I'm sorry, I don't find that example plausible. Assuming a non-terrible parameter name, how can argument position tell you more than naming the argument? |
Beta Was this translation helpful? Give feedback.
-
@jnm2, Foo(1, 2, false, "a"); I have no named parameters; just positional ones. This is a common way to write code. I'm used to looking at positional parameters. When I then see, Foo(1, _, _, "a"); I'm seeing the same positional parameters. Now two of them are using default values. I don't know what those default values are, but I know they are there; I know optional parameters are in play. But when I see, Foo(1, s:"a"); I've lost that positional parameter information. Without looking at the method signature, I can't tell that But as previously stated, I don't find optional parameters compelling in almost any circumstances. This feature doesn't offer enough benefit to overcome my objections to using optional parameters, so I still do not support it. |
Beta Was this translation helpful? Give feedback.
-
But Sometimes I'll even specify the default value of an optional parameter just so I can specify the parameter name. |
Beta Was this translation helpful? Give feedback.
-
@DavidArno Named arguments need a few more keystrokes to select the argument name from members list. But the worst case is when the argument name is too long, so the resulted code is not pleasant. |
Beta Was this translation helpful? Give feedback.
-
@MohammadHamdyGhanem,
Indeed. And that to me waves a big red flag that something is wrong with the code. What's the use case for needing those default values? I've rarely come across examples of either overloads or optional parameters that I find convincingly solve a user need.
Wanting to supply default values to a method just feels wrong to me in most cases. |
Beta Was this translation helpful? Give feedback.
-
You want to provide all five parameters to Directory.Delete is the same way, only less pronounced. Parameterizing options that are not commonly used is a great thing to do. |
Beta Was this translation helpful? Give feedback.
-
You can use named params with any non-optional param.
By the way, there is an irritating behavior in the editor: When I select the named param name from the auto complete list (like |
Beta Was this translation helpful? Give feedback.
-
public StreamReader (System.IO.Stream stream);
public StreamReader (System.IO.Stream stream,
System.Text.Encoding encoding,
bool detectEncodingFromByteOrderMarks,
int bufferSize,
bool leaveOpen); And if even more parameters were needed, or folk often only wanted to override the default for one of those parameters, I'd use the builder pattern to handle those options. |
Beta Was this translation helpful? Give feedback.
-
@MohammadHamdyGhanem
Yes, that's what I do with many non-optional params. I even do it with optional params sometimes, which requires me to specify their default value.
No way! I so frequently need to specify And besides, you'd be happy with two? That's still "wanting to supply default values to a method," and I don't think it ever feels wrong. |
Beta Was this translation helpful? Give feedback.
-
I can imagine domains that have well specified paremeter order and using
public class Point
{
public Point(int x, int y, int z) { ... }
...
public Point WithCoordinates(int? x = null, int? y = null, int? z = null) { ... }
}
...
Point p = new Point(0,0,0);
p.WithCoordinates(5,_,_);
p.WithCoordinates(_,1,_);
p.WithCoordinates(7,_,7);
// lines above read better than lines bellow
p.WithCoordinates(x:5);
p.WithCoordinates(y:1);
p.WithCoordinates(x:7,z:7);
public class ContextAndScope
{
public ItemInScope(Context ctx = Context.Default, Scope scp = Scope.Default) { ... }
}
...
new ContextAndScope(_, myScope);
// reads better than
new ContextAndScope(scope: myScope); This could indeed be preferable in minority of cases compared to named parameters, but I don't see why that should harm this proposal. |
Beta Was this translation helpful? Give feedback.
-
This behavior is intentional and by design. |
Beta Was this translation helpful? Give feedback.
-
It annoys me and the people I've worked with. Can you help this behavior make sense to me, or can I ask for a change? |
Beta Was this translation helpful? Give feedback.
-
As with most things with suffixes in completion, the suffix is there for information purposes, but is not intended to be inserted so as not to screw with what you are typing. i.e. we put things like |
Beta Was this translation helpful? Give feedback.
-
Finally, behavior like this is very difficult to change given that you will likely break the muscle memory built up by many users for how completion works. I'd prefer to not derail this convo. If you'd like to discuss more, we can do gitter, or we can do it in a new bug that is opened :) |
Beta Was this translation helpful? Give feedback.
-
I added a relevant proposal: |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
Suppose we have this function:
If we want to ignore y and z optional params, we have to use named arguments like this:
Foo(1, s: "something");
I slao suggest to allow us to use discards as placeholders of the messing arguments like this
Foo(1, _, _, "something");
Beta Was this translation helpful? Give feedback.
All reactions