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

What language proposals would benefit from CLR changes? #420

Closed
gafter opened this issue Feb 12, 2015 · 45 comments
Closed

What language proposals would benefit from CLR changes? #420

gafter opened this issue Feb 12, 2015 · 45 comments

Comments

@gafter
Copy link
Member

gafter commented Feb 12, 2015

If we were to plan for one language feature that requires a revision of the CLR, then we might as well do as many of them at the same time as make sense. What changes would we consider for C# 7 and VB 15 that would benefit from CLR support? See #166 for related discussion. This is a pared-down list for us to select from.

  1. Virtual extension methods (see Java-like virtual extension methods/default interface implementations, aka traits or (ruby-like) mixins #73, Proposal: Virtual extension methods #258)
  2. Generic constraints about static methods or constructors (see also (Proposal) Concepts/Traits (enhanced generic constraints) #129, #154).
  3. Array slicing (see Proposal: Slicing #120)
  4. Language support for tuples (see Proposal: Language support for Tuples #347) and function types (no issue yet) might benefit from CLR unification across assemblies.
  5. Traits (see [Proposal] Add support for traits and/or mixins #60) aka structural interfaces (see #154) or mixins (no issue yet)

Those that we would likely not do in this timeframe include

  1. Make void a first-class type with one value; see Suggestion: void as a first-class citizen #234 (Suggested by @ashmind) (Given how long the CLR has been around, it is probably too late for APIs to benefit, as those that would benefit most have already been written)
  2. Covariance and contravariance for classes (see Allow type parameters to be declared co/contra variant on classes. #171)
  3. Allow |, &, and ~ operators on a type parameter with the enum constraint (see Proposal: support an enum constraint on generic type parameters #262)
  4. Intersection types (Proposal: Implicit Interfaces #2146, though likely not that syntax) and/or union types.
  5. Support generic indexers (see [Proposal] Generic indexers #523)
  6. Higher-kinded polymorphism (see Higher Kinded Polymorphism / Generics on Generics #2212)
@sharwell
Copy link
Member

I noticed you omitted the generic indexers request. Was that intentional, or perhaps it is missing because I didn't submit a complete proposal?

@ashmind
Copy link
Contributor

ashmind commented Feb 12, 2015

Language support for tuples might benefit from CLR unification across assemblies; see #347.

Just to add, other uses are function types and ASP.NET's [AssemblyNeutral].
Would it be useful for you if I outlined a design suggestion? And if I do, should it go here or to https://github.com/dotnet/coreclr ?

@AdamSpeight2008
Copy link
Contributor

A de-facto Option(Of T).

@gafter
Copy link
Member Author

gafter commented Feb 12, 2015

@sharwell Can you please point me to the indexers issue you're talking about?

@ashmind Language suggestions belong here. CLR suggestions belong there. I'll add function types to the list of language features that would benefit from unification.

@AdamSpeight2008 I don't know what you're suggesting that would benefit from CLR support.

@mikedn
Copy link

mikedn commented Feb 12, 2015

#262 might also need runtime support. Enum constraints are supported in CLR but to be really useful it would be nice to also support bitwise operations for flags. & and | work but ~ sometimes requires a conversion that cannot be expressed in IL.

@gafter
Copy link
Member Author

gafter commented Feb 12, 2015

@mikedn Added to the list (as something we probably would not do).

@sharwell
Copy link
Member

@gafter It's the first comment in #166. The motivating example is currently in one of my Stack Overflow answers, but if you feel it merits further discussion I can write the proposal separately here.

@MgSam
Copy link

MgSam commented Feb 12, 2015

Rather than do #161, which seems like a big change to the language for minimal benefit, I'd like to see the C# and CLR teams work together to come up with a non-garbage collected option for .NET development. This is probably outside the C# 7.0 timeframe though.

@gafter
Copy link
Member Author

gafter commented Feb 12, 2015

@sharwell If you could collect the most relevant bits into an issue/proposal that would be great.

@orthoxerox
Copy link
Contributor

Structural typing and intersection/union types. Right now structural typing is de facto supported in the compiler (foreach and await), but it could be elevated into either anonymous checks or into capabilities (implicitly implemented interfaces).

Intersection types would be useful for those cases when you need to work with objects that implement more than one interface. Of course, if you had capabilities, you could use them instead.

Union types are less useful at this stage, since existing libraries don't use them.

@gafter
Copy link
Member Author

gafter commented Feb 14, 2015

@orthoxerox Structural typing is already number 6 on the list.

@biqas
Copy link

biqas commented Feb 15, 2015

Hi,

Serialization/Deserialization to express on IL level would have huge benefits in through-puts, and interop between IL/None-IL-Languages.

There is already a project from Microsoft: https://github.com/Microsoft/bond which is dealing with it, but it is just on language level.

@gafter
Copy link
Member Author

gafter commented Feb 15, 2015

@biqas I don't know enough about what you're suggesting to add it to the list. Can you please create a new issue describing what you're suggesting in more detail, and link to it in this thread?

@biqas
Copy link

biqas commented Feb 15, 2015

@gafter

hope it is little bit more info's
Binary layout schemas and transformations on IL-Level
#526

@gafter
Copy link
Member Author

gafter commented Feb 16, 2015

@biqas #526 doesn't propose anything for C# of VB. It is a CLR/IL change proposal. This is a list of language changes.

@biqas
Copy link

biqas commented Feb 22, 2015

@gafter yes you are right it was not proposing anything for C#, so you can remove it from here (sorry got the topic wrong:-) ). Maybe there will be or is already a something similiar for only CLR/IL, if so it would be fit there.

@grokys
Copy link

grokys commented Feb 24, 2015

Generic indexers would be incredibly useful for Perspex. We use indexers to allow binding in initialization lists which means at the moment we have to forego compile-time checking. See https://github.com/grokys/Perspex/blob/master/Docs/intro.md#attached-properties-and-binding-pt-2 for an example.

@qwertie
Copy link

qwertie commented Apr 26, 2015

"Closed" union types? Isn't that a synonym for Algebraic Data Types? I prefer the strictly more powerful concept of open union types, as in Ceylon. Anyway, yes, pattern matching and ADTs don't need CLR changes.

P.S. I do wonder where one is supposed to propose CLR changes. Under Roslyn doesn't seem right.

@gafter
Copy link
Member Author

gafter commented Apr 26, 2015

@qwertie closed union types enable the compiler to prove a set of options (cases) is complete. Having said that, the existing "records" proposal is open union types.

@qwertie
Copy link

qwertie commented Apr 26, 2015

@gafter I take it you aren't familiar with Ceylon's union & intersection types. If you were, you'd know that the compiler knows what cases are possible in any given situation and can check whether all cases have been handled. AFAICT, Ceylon's union type system is strictly more flexible than (closed) ADTs and doesn't sacrifice anything (except possibly type inference, which is not relevant when we're talking about CLR features, not compiler features. In the interest of full honesty, Ceylon-style union types are sort-of incompatible with Rust-style closed-union value types, but that's not really an issue since the CLR does doesn't support the latter anyway.)

@dsaf
Copy link

dsaf commented Aug 13, 2015

Shouldn't there be a CLR-change label? #4505

@alrz
Copy link
Contributor

alrz commented Nov 15, 2015

I dig "function types", isn't it under consideration, @gafter?

@gafter
Copy link
Member Author

gafter commented Nov 15, 2015

Nobody on the language design team is championing function types.

@CyrusNajmabadi
Copy link
Member

  1. Is covariance/contravariance for methods included in this list? Is that subsumed by Covariance and contravariance for classes (see #171)?
  2. Are structural delegates (as opposed to Nominal delegates) subsumed by any of those items?
  3. Variadic generics? (i.e. so you don't need Func<>... Func<,,,,,,,,,,> etc.

If not, i'd like to see those on the list. Thanks!

Note: i'm only interested in these features if they can be backfilled over what existing stuff we have, and not if they require totally new APIs to be build. i.e. if we added variadic generics, but couldn't replace the existing Func/Action goop with it, then I don't see it actually being that useful. Same with structural delegates. I don't want to have to rewrite APIs or produce a new set of delegate types. I want a way for our existing delegates to gain structural semantics in the runtime, and to able to use that and work with that from C#.

Thanks!

@gafter
Copy link
Member Author

gafter commented Nov 16, 2015

@CyrusNajmabadi Covariance for method return types (#357) would use bridge methods and does not require CLR changes. There is no proposal for contravariance of methods.

There is no proposal for structural function types (which I find somewhat surprising). I gather you mean a shorthand notation for the platform types named Func and Action. I think it would be nice to be able to write int=>int as a shorthand for Func<int, int>, though there are likely to be interesting issues finding an unambiguous syntax. If that is what do, no CLR changes are required.

The two proposals possibly related to varadic generics (#5058 and #2212) aren't detailed enough to be evaluated as proposed language features. Both probably require CLR changes. I believe F# is hoping to get CLR support for higher-kinded generics.

@CyrusNajmabadi
Copy link
Member

@gafter

  1. As long as we have some solution for Covariant Return Types, i'm happy. CLR support seems the cleanest. But using bridge methods is fine with me (and I guess means they'll work downlevel) :)
  2. I'm not referring to a shorthand for delegates, but to have structural delegates. i.e. I want Predicate<string> and Func<string,bool> to be the same. I don't want to have to write ConditionalWeakTable<Blah, Fooby>.CreateValueCallback when I could just say Func<Blah,Fooby>. I find it so annoying that there are nominal semantics here and that I can't interchange any of these guys.
  3. I'll let F# to the advanced work with generics. Though do you think that the CLR would make changes here with just F# asking for it? Seems like we'd want C# to possibly go along as well to make it more likely.

@gafter
Copy link
Member Author

gafter commented Nov 16, 2015

@CyrusNajmabadi

  1. Removing the return type from the CLR's view of a method's signature would be a breaking change. How else would we get CLR support?
  2. Making Predicate<string> and Func<string, bool> be the same type would be a breaking change.
  3. Apparently the CLR changes for higher-kinded generics aren't that large. There are many other things worth doing before that for C#.

@alrz
Copy link
Contributor

alrz commented Nov 16, 2015

Making Predicate<string> and Func<string, bool> be the same type would be a breaking change.

Wouldn't this possibly make function types more likely to happen? I think having a T => bool implicitly convertible to both would address the compatibility issue.

@CyrusNajmabadi
Copy link
Member

I don't see why something being a breaking change matters. I'm all for breaking changes if the value is high enough. Not doing so leads to stagnation. TS, for example, was will to take on breaking changes with the latest release because the value was felt to be high enough.

  1. "How else would we get CLR support?" I'm not sure what you mean. We'd get CLR support by having them allow overriding of methods with other methods that have a covariant return type (and possibly contravariant parameter types... though I care less about this use case.)
  2. It would be a breaking change. I don't care**. I think the value is high enough to warrant it. Especially if we do the work to make it easy and seamless to move your code forward. I think there is remarkably little value in the current system, and there is high cost across all of the .Net ecosystem because of this decision. Much could be simplified and made far clearer if we did this. Regardless, this wasn't the thread of "What language proposals would benefit from CLR changes and wouldn't be breaking changes". It's "What language proposals would benefit from CLR changes. To me, the proposal of having structural delegates would benefit from CLR changes :)
  3. "There are many other things worth doing before that for C#." Sure. That doesn't mean it shouldn't be listed though.

Effectively, all of our features we do at any version were simply "not worth doing" the version before. And yet we still got around to them. That's what backlogs are for :)

*: Heck, we changed how "foreach variable capture" worked. That was a breaking change, but the value was there. And, indeed, I would say that we *reallllllly should have made "comparing value to null is an error" even though it was a breaking change.

Breaking changes are a consideration with language changes. But they are not, in and of themselves, a blocker of them.

@HaloFour
Copy link

Would be nice if the CLR could at least make it very inexpensive to convert between structurally-equivalent delegate types rather than having to incur the double-invoke penalty. Then C# could potentially permit implicit conversion between them. I think that would largely satisfy these requests.

@gafter
Copy link
Member Author

gafter commented Nov 16, 2015

@CyrusNajmabadi TS has never taken a binary incompatible change. That would be like changing the semantics of the existing JS language (TS's equivalent to our "CLR support") in a way that changes the behavior of existing code. Making an incompatible CLR change is unlikely to be considered beyond this discussion.

@orthoxerox
Copy link
Contributor

@HaloFour I think the current implementation of CLR can already invoke structurally compatible delegates if you tell it to in CIL, since the function pointers are the same in the end. However, it's an unsupported feature of this specific implementation. Would be nice to obtain a guarantee that this will continue to work.

@HaloFour
Copy link

@orthoxerox Yes, but you'll still get an exception if you attempt to combine them with another delegate instance.

@gafter gafter modified the milestone: C# 7 and VB 15 Nov 21, 2015
@nietras
Copy link

nietras commented Dec 21, 2015

I would add "Unmanaged generic type constraint + generic pointers" to this list, as per https://github.com/dotnet/coreclr/issues/2322

@qwertie
Copy link

qwertie commented Dec 6, 2016

In what sense are structural delegates a breaking change at the CLR level? It seems to me like all you have to do is let the verifier succeed in doing assignments and calls where otherwise it would fail.

Here's another item for my wish list: the ceq opcode should be allowed to bitwise compare two arbitrary value types (and create an mscorlib function for invoking this opcode from C#). The fact that I can't do this decreases the efficiency of my VList's SmartSelect method and I'm sure other people must be affected by this too.

@gafter
Copy link
Member Author

gafter commented Mar 22, 2017

Now being tracked at dotnet/csharplang#317

@gafter gafter closed this as completed Mar 22, 2017
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