Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proposal: Allow optional names in some places #6115

Closed
alrz opened this issue Oct 17, 2015 · 9 comments
Closed

Proposal: Allow optional names in some places #6115

alrz opened this issue Oct 17, 2015 · 9 comments

Comments

@alrz
Copy link
Member

alrz commented Oct 17, 2015

While C# is fusing records and ADTs together, there is still a need for more concise declarations of "records". Types in in these contexts are expressive enough and there is a chance that one never use them and put them directly in switch or match which doesn't rely on arg names. Also they are more useful in #5718 where you are defining pattern classes and maybe you just don't care about member names, because these classes will directly used in deconstruction syntax and will use positional matching. With #6067 in place, it also would make sense to have optional names in overridden and abstract methods. And in delegates like Action<> or Func<> one simply doesn't care about delegate arg names so having it mandatory seems lame, IMO.

// overridden methods
public override bool Equals(object) => false; // implicitly considered as "case *" in this case
public override bool Equals(object case Foo foo) => Equals(foo);

// abstract methods
protected internal abstract void Apply(Foo);

// record types
public struct ValueTuple<T1, T2>(T1, T2);

// delegates
public delegate void FooEventHandler(object, FooEventArgs);

// interfaces
interface IFoo {
    void Apply(Bar);
}

This syntax is used in method forwarding (#6081) where we just care about method's signature to specify desired overload and having arg names doesn't make sense at all. It also aids #5058 to be effective in declaring tuple types.

@gafter
Copy link
Member

gafter commented Oct 21, 2015

This proposal hypothesizes a lot of things we are unlikely to do.

We don't need the language to help for declaring tuples, as it will be done once in the platform for everyone to use. Any slight savings there will just save me a few keystrokes, and help nobody else. I've already typed more keystrokes here than I would save.

I doubt we'll take on any of the other issues this is suggested to "improve". Even if we did, those improvements belong in the original feature. I rarely hear people complain about having to name method parameters that they do not intend to use.

@gafter gafter closed this as completed Oct 21, 2015
@gafter gafter reopened this Oct 21, 2015
@alrz
Copy link
Member Author

alrz commented Oct 21, 2015

@gafter Not just tuples, per se, I meant all record types in which member names are not that important, such as tuples. This would be useful in interface implementations and method overrides as well, indicating that parameter is not used throughout the method body (as an alternative to case * parameter from #6067).

Even if we did, those improvements belong in the original feature.

This would be a great addition to the record type declaration syntax, because they are meant to be concise and expressive. I can imagine this will be useful in pattern record types such as ones that I mentioned in #5718.

@aluanhaddad
Copy link

And in delegates like Action<> or Func<> one simply doesn't care about delegate arg names so having it mandatory seems lame, IMO.

I disagree. It would actually be nice if one could optionally specify the names for the parameters of a callback so that they could be picked up by tooling. This is useful in languages like TypeScript. Names are important.

@svick
Copy link
Contributor

svick commented Oct 25, 2015

@aluanhaddad

It would actually be nice if one could optionally specify the names for the parameters of a callback so that they could be picked up by tooling.

You can, by using a custom delegate type. And at least ReSharper does use the parameter name from the delegate type in its autocompletion.

@aluanhaddad
Copy link

I don't use ReSharper so I don't take advantage of that, but my point was more that names are a good thing, and your remark about ReSharper speaks to one of the few disadvantages of the Func and Action delegates. I think adopting this proposal would be a bad idea, because it aims to allow less information rich declarations.

@alrz
Copy link
Member Author

alrz commented Oct 26, 2015

@aluanhaddad

it aims to allow less information rich declarations.

Exactly, when types can be expressing enough, names are just additional noise to the code. Take this for example:

abstract sealed class Expr;
sealed class Const(double) : Expr;
sealed class Add(Expr, Expr) : Expr;
sealed class Sub(Expr, Expr) : Expr;
sealed class Mul(Expr, Expr) : Expr;
sealed class Div(Expr, Expr) : Expr;
sealed class Pow(Expr, Expr) : Expr;
sealed class Log(Expr) : Expr;
sealed class Sin(Expr) : Expr;
sealed class Cos(Expr) : Expr;

You can see what I mean.

@aluanhaddad
Copy link

Exactly, when types can be expressing enough, names are just additional noise to the code. Take this for example:

abstract sealed class Expr;
sealed class Const(double) : Expr;
sealed class Add(Expr, Expr) : Expr;
sealed class Sub(Expr, Expr) : Expr;
sealed class Mul(Expr, Expr) : Expr;
sealed class Div(Expr, Expr) : Expr;
sealed class Pow(Expr, Expr) : Expr;
sealed class Log(Expr) : Expr;
sealed class Sin(Expr) : Expr;
sealed class Cos(Expr) : Expr;
You can see what I mean.

Sure, in this case names don't buy you much. However, omitting them is inconsistent with other parts of the language, provides less information for tooling, complicates or makes XML comment syntax inapplicable, and only saves you 1-2 characters (2-4 counting whitespace) per line compared to:

abstract sealed class Expr;
sealed class Const(double x) : Expr;
sealed class Add(Expr x, Expr y) : Expr;
sealed class Sub(Expr x, Expr y) : Expr;
sealed class Mul(Expr x, Expr y) : Expr;
sealed class Div(Expr x, Expr y) : Expr;
sealed class Pow(Expr x, Expr y) : Expr;
sealed class Log(Expr n) : Expr;
sealed class Sin(Expr n) : Expr;
sealed class Cos(Expr n) : Expr;

@alrz
Copy link
Member Author

alrz commented Oct 26, 2015

@aluanhaddad Names you have chosen not only don't make any sense but also make it even more confusing. They should be left and right for binary operators, value for Const and arg (not sure about this) for functions. If you are saying that names are important and provide "more information" you should think about them not just use placeholders like x, y, n, etc to satisfy the compiler. And that's the point: when types are expressive enough names just add unnecessary additional noise and having them mandatory force developer to use x, y like you did, or at best, some thoughtful names, if you care enough.

@alrz
Copy link
Member Author

alrz commented Feb 12, 2016

Discussion on this matter probably belongs to #6739. Closing accourding to the comment above.

@alrz alrz closed this as completed Feb 12, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants