Open lostmsu opened 5 years ago
However, there are many scenarios, when having operators to be static methods fail. Main one being inability to represent generic algebras, which is hindering efforts to make C# suitable for scientific computing.
Can you add this scenario to your proposal please?
@YairHalberstadt , sure, no problem. I just assumed, that everyone tried this hundreds of times, and know what I am talking about.
UPD. Moved the code sample into the initial post.
Never assume đ
There are various proposals around type classes that aim to address this problem from the opposite angle. Namely, allow interfaces to declare static members.
One disadvantage is they will only work in generic contexts.
@YairHalberstadt type classes require CLR changes, or type erasure. This needs neither.
@lostmsu No they don't. See the shapes proposal.
@YairHalberstadt the shapes proposal seems to cover what I am looking for, but the implementation cost would be much higher, and would introduce generic parameter bloat. Since CLR has (or at least used to have) very tight restrictions on the number of generic parameters, it might not be viable.
The shapes proposal was proposed by Mads Torgerson, the program manager for C#. They are likely going to look very very hard into implementing it.
It could be it isn't actually manageable, but I would hold on for now...
@YairHalberstadt well, I've done that for F# back in university ~10 years ago: https://archive.codeplex.com/?p=ntypeclasses From my experience, it is not elegant enough.
Elegant, as in elegant to use, or elegant as in elegant CodeGen?
Shapes/TypeClasses/etc. has a lot of interest at the LDM level. There are many reasons for this. However, one of hte primary ones is that it's felt that there are so many issues/proposals/things-people-want that wuold just fall under such an umbrella. So, instead of having to define 50 different features to do everythin in a one-off fashion, you just define the one large and flexible feature that subsumes all the rest at an acceptable-enough level.
@YairHalberstadt elegant as in design and semantics, and also codegen.
New type declaration keywords, the need for implicit TypeClass
type parameter, a whole new set of rules to find an appropriate implicit instance.
For codegen, as I mentioned - generics bloat, which might require CLR upgrade.
@CyrusNajmabadi , as far as I can see, having type classes would not make the code in the example as elegant as it could be, because you'd still have to call T.Add(T other)
instead of simply doing T + T
unless what I request is implemented.
You should be able to define operators in type classes, and by constraining a type parameter to a type class you would be able to write T + T
as desired.
@YairHalberstadt , as under the hood the type classes are represented as interfaces, that would imply you can define operators on interfaces.
I believe F# makes heavy use of generics, and it seems to run fine. Func and Action are both defined for up to 16 type parameters. I do not know for sure, but I think it likely the CLR will cope fine.
There are other potential performance issues, such as jitted code bloat, possibly leading to cache misses, but I think that it's important to run tests on large, real life codebases to get an idea if there are any performance issues in practice.
@lostmsu
They are interfaces under the hood, and all static members (including operators) would be instance members on that interface, but that is all implementation details. The developer would declare those members as static members on the "shape" type and they would call them like normal operators or static members. The compiler will handle converting that to instance member calls to the "shape" interface and the witness struct will handle proxying those calls to the actual static members and operators.
as under the hood the type classes are represented as interfaces, that would imply you can define operators on interfaces.
Nope. You could define an unspeakable method for the witness struct, and use an attribute to indicate it should be used as an operator.
@lostmsu
I believe this is where the conversation (publicly) left off: #1711
The section under "Static interface members" explicitly discusses static members and operators.
All of this is up in the air, but anytime I've seen it discussed this is the general example, a type with a static property and static operators.
Basically what I'm trying to say here is:
Shapes are almost definitely going to be looked at. They may be implemented, or they may not, but these type of features are unlikely to be considered till shapes are decided on.
It's still great to bring up these issues as they help guide the LDM as to what shapes should be capable of doing. I.e. shapes have to be powerful enough to solve these 30 issues.
If shapes don't end up happening, then all those issues might be looked at again.
@HaloFour I can perfectly understand how that would work.
Problem is this spec is extremely large, and proposal is not even finished (for example, it lacks exact rules to resolve default instances). I can hardly see it getting through all the necessary stages and approvals in the next 5+ years.
Whereas what I suggest here can be hacked in a day, and implemented and well-tested in 2-4 weeks. And would be immediately useful for the concepts proposal too.
Whereas what I suggest here can be hacked in a day, and implemented and well-tested in 2-4 weeks. And would be immediately useful for the concepts proposal too.
@lostmsu As i mentioned, the LDM would like to avoid N 'smaller' one-off proposals like this.
@lostmsu
Problem is this spec is extremely large, and proposal is not even finished (for example, it lacks exact rules to resolve default instances). I can hardly see it getting through all the necessary stages and approvals in the next 5+ years.
And it solves a lot of problems, including your own. If history is any indication the team prefers to solve the big problems rather than trying to piecemeal a dozen disparate ways of doing things. This concept has the attention of the program manager of the C# team so it's likely to get a lot of attention after C# 8.0 ships.
Whereas what I suggest here can be hacked in a day, and implemented and well-tested in 2-4 weeks. And would be immediately useful for the concepts proposal too.
You could have the entire team jumping up and down about this specific proposal and it would never happen in the next 2-4 weeks, or the next 2-4 months, or likely within the next year. This repo doesn't move that way.
Yes, big projects take time. Many features slated for C# 8.0 were being discussed on CodePlex 3 years ago. The team is conservative and very deliberate. They're very unlikely to consider a small one-off solution that fits under a bigger umbrella unless it can be demonstrated that the bigger umbrella can't solve the problem or is itself not going to happen.
@CyrusNajmabadi I don't see why we can't have both. How many "one-off" proposals with no new concepts or keywords in them, that address parts of what shapes proposal is trying to get at?
Let's not run around in circles.
This concept has the attention of the program manager of the C# team so it's likely to get a lot of attention after C# 8.0 ships.
@MadsTorgersen
@lostmsu
New grammar, changes to the spec, development, testing, and support until the heat death of the Universe.
@CyrusNajmabadi I don't see why we can't have both
Because it's redundant. Why solve the problem two ways instead of just solving it one way? It's a better use of resources, and it makes things less confusing and cheaper to maintain over the life of the language.
New grammar, changes to the spec, development, testing, and support until the heat death of the Universe.
Yeah, which I estimated for this feature to be 2-4 weeks tops for a single person. Do you disagree with that estimate?
@lostmsu
Yeah, which I estimated for this feature to be 2-4 weeks tops for a single person. Do you disagree with that estimate?
Yes, because this will involve the team, not a single person, and team is mindful as to the state of the language 5 years from now. They don't hack stuff together that quickly.
@lostmsu Cyrus worked on the Roslyn team for many many years, was a member of the LDM, and is one of the most frequent contributors to Roslyn, despite no longer working at Microsoft.
If he says it'll take that long, you better believe it.
Oh wait, that was HaloFour
@CyrusNajmabadi
Because it's redundant. Why solve the problem two ways instead of just solving it one way? It's a better use of resources, and it makes things less confusing and cheaper to maintain over the life of the language.
You are making a really huge assumption here, that shapes or type classes will ever be implemented in C#.
F#, which derived from ML, and had very hand-wavy design process, never got to implementing it in years even in an experimental setting. That is even though ML had it in the first place. And trust me, there was no lack of desire for it.
@HaloFour
5 years from now
5 years from now the market of scientific computing will be dominated by everything but C#, and there will be no way in.
Not meaning in any way to say we should believe you less @HaloFour đ
You are making a really huge assumption here, that shapes or type classes will ever be implemented in C#.
And? The goal of the LDM is to assess and make reasonable decisions based on many potential futures. There is enough of beliefe that shapes/type-classes/etc. will be done to warrant not doing the 30 feature requests out there that fall under that umbrella. Even if it was only a few weeks worth for each (and it's not, it's sooo much higher), the LDM does not want to spend that to add 30 sub features, instead of one feature that would solve all of them (even if it takes longer to design and implement).
If, at some point, it becomes highly unlikely that shapes/etc. get done, then the views on these individual features will change.
I get that you don't like that's the current place where things land. But that's life. :-/
The issue with 30 sub features is not just that all 30 have to be implemented.
It's that any new feature I add after that, has to consider how it interacts with all those 30 features. When I write a tests for a new feature, I've now got to consider 30 extra cases and decide whether they need a test.
And this is not theoretical. I literally right now am writing a test case to see how my new Roslyn API interacts with using declarations, which I would not have to do if they were not being added to the language.
The issue with delaying these "30 sub features" for me is that the shapes/type classes feature is not, apparently, time boxed. E.g. I'd be fine if LDM would say "we will not ship C# 9 until shapes is implemented", or "if shapes is not past proposal stage by some moment in C# 9 timeline, we will take a look at simpler alternatives".
Otherwise after C# 9 release this Go joke will become relevant for C#:
@lostmsu
A delayed feature is potentially good; a bad feature is bad forever.
for me is that the shapes/type classes feature is not, apparently, time boxed.
Sorry. Things are not time boxed in the language.
E.g. I'd be fine if LDM would say "we will not ship C# 9 until shapes is implemented",
The LDM will not do that. It never has done that. Features come and go as things are learned. For example,if efforts start on shapes, and it turns out to be non-feasible, they will be scrapped. This has happened numerous times in the lifetime of C# and it will likely happen again.
or "if shapes is not past proposal stage by some moment in C# 9 timeline, we will take a look at simpler alternatives".
The team publishes what they are working toward. There is no guarantee either htat if shapes do not make it in 9 that these others will be worked on.
Otherwise after C# 9 release this Go joke will become relevant for C#:
So what? No one working on C# cares if someone makes a joke about it because some feature is delayed. Responsible language development involved careful and thoughtful consideration about the future and where you want the language to be then. It means often not looking at cheap shortcut possibilities in the nearterm in spite of better approaches that can come later.
Note: these lessons have been hard learned by many language designers working on many different languages over decades. And, even knowing this stuff, we still screwed up some verssions of C# and are stuck with language features we wish we could get rid of.
Your feedback has been noted, and your desire to have this is well understood. But the language willl proceed at the pace it feels is appropriate, even if that means missing out on short-term wins in some arenas.
So what? No one working on C# cares if someone makes a joke about it because some feature is delayed.
They should. Developers are generally clever enough folks to start making jokes for a good reason.
They should. Developers are generally clever enough folks to start making jokes for a good reason.
This is not a constructive avenue for dialog. The team are very used to criticism regarding their decisions. If they were afraid of doing or not doing something based on whether or not someone would disagree the language would quite literally never have been designed in the first place.
They should
No, they should not. Someone will always think your language is a joke. Driving to make that group of people happy is an inappropriate focus.
Let me make it totally clear: at every single step of C#, there have been people who consider it a joke to use the language (for any number of reasons). No one cares. The language isn't going to shift how it does development to make that group happy.
--
Note: bringing up 'Go' is rather strange in and of itself, given that 'go' is more loved than C# based on the most recent StackOverflow survey:
So, even i people are making fun of 'go' so what? Why is that at all something important to care about?
This is not a constructive avenue for dialog.
Neither is the whole talk about why this should be superseded by a feature, that has no apparent horizon.
Neither is the whole talk about why this should be superseded by a feature, that has no apparent horizon.
Yes it is. You're asking for a feature in the short term. I'm explaining why that's not felt ot be appropriate. It's entirely on topic and appropriate. I'm not sure why you're rejecting this explanation. It's accurate and important to understnd.
At this point i'm not sure what else to say. We're at am impasse.
I'm not sure what of the above is under contention. It's a factual statement about the current state of affairs. Nothing is likely to change about any of the above. If, in teh future, the LDM finds that the umbrella features are just unlikely to happen, your feature request may be reprioritized accordingly. Until there, there's little that will change here in the foreseeable future.
@CyrusNajmabadi IMHO, "Love" here is quite skewed. I am sure F# for the long time had more of it, than C#, being niche. Look at this one, depicting Go hype train, and its fall after the Jul-Aug 2018 announcement, that 2.0 won't have generics: https://www.tiobe.com/tiobe-index/go/
C# isn't a popularity contest. Proposals aren't considered on the basis that they'll increase the TiOBE index for the language.
@HaloFour what is the basis then?
@lostmsu
Whether the feature solves problems and fits within long-term vision of the language.
IMHO, "Love" here is quite skewed.
As are "jokes". You're the one who opened up that part of the discussion. I'm just pointing out that that it's not an the objective of hte C# language to minimize people making jokes about it.
Yes, we've read https://blogs.msdn.microsoft.com/ericlippert/2007/05/14/why-are-overloaded-operators-always-static-in-c/
However, there are many scenarios, when having operators to be static methods fail. Main one being inability to represent generic algebras, which is hindering efforts to make C# suitable for scientific computing.
My proposal is simple: allow defining operators without
static
keyword, and permit them on interfaces. When performing operator overloading, always choosestatic
operators defined in 7.0 way, if present, and issue a warning, if there is also a matching instance operator.E.g.
P.S. IMHO, the fact, that users of the feature can shoot themselves in the feet by making asymmetric addition that way should not prevent legitimate use. There are users, who would be able to do that with inheritance, but nobody is arguing for it to be deprecated.