-
Notifications
You must be signed in to change notification settings - Fork 22
Description
I propose to lift byref generics restrictions for inline functions.
Since all the new byref things have landed in 4.5 I've been playing quite a bit with Span. It's awesome it all works so well already and correctly prevents you from going off the rails.
It is definitely restrictive and it complicates generic programming a lot. It might especially shock people where they normally don't realize this applies, like piping |> or functions like id. The reason for this is purely a limitation of the CLR and its implementation of generics, it cannot accept a byref type argument, however F# could.
F# already has ways to deal with other generics limitations by marking functions as inline. This effectively removes this function from the runtime's view which allows the language to relax restrictions around generic constraints or limitations.
For instance lifting restrictions on byref for generic functions should allow the following contrived example to pass compilation:
Span<int>.Empty |> idBoth |> and id are generic, but both are also already marked inline today.
Making this change is neatly in line ;) with previous choices for inline to lift generics limitations and it greatly increases ergonomics working with byreflike types and byref arguments.
@TIHan has also quickly checked the feasibility of this and found a place to implement this inside PostInferenceChecks.fs where it can be, in theory, implemented in a way to guarantee correctness.
Pros and Cons
The advantages of making this adjustment to F# are increased language ergonomics and consistency as not being able to use byref in generics is purely a CLR restriction. This is opens up a lot of possibilities to add some sugar on interactions with Span and friends. And it might also help in performance scenarios where passing structs byref is preferred but where generic code is important too or used a lot. In the face of F# dissuading people from doing method overloading it is a good option to have.
The disadvantages of making this adjustment to F# are extra complexity in the compiler. A function marked as inline should, for byref call sites, not contain any calls to other generic functions that aren't marked inline as well.
Extra information
Estimated cost (XS, S, M, L, XL, XXL): S (or M?)
Related suggestions: (put links to related suggestions here)
Affidavit (please submit!)
Please tick this by placing a cross in the box:
- This is not a question (e.g. like one you might ask on stackoverflow) and I have searched stackoverflow for discussions of this issue
- I have searched both open and closed suggestions on this site and believe this is not a duplicate
- This is not something which has obviously "already been decided" in previous versions of F#. If you're questioning a fundamental design decision that has obviously already been taken (e.g. "Make F# untyped") then please don't submit it.
Please tick all that apply:
- This is not a breaking change to the F# language design
- I or my company would be willing to help implement and/or test this