fslang-suggestions icon indicating copy to clipboard operation
fslang-suggestions copied to clipboard

Extend fixed expressions to support more types

Open jwosty opened this issue 6 years ago • 18 comments

Extend fixed expressions to Span, Memory, refs, and GetPinnableReference

There should be some way to pin instances of Span<T>, Memory<T>, and certain kinds of types to take their native addresses for native interop purposes. In C# you can just use the fixed statement, but F# only supports a limited set of constructs, none of which you can get to work with Spans.

This can all be accomplished in F# by making fixed expressions work with anything that implements GetPinnableReference() just like C#.

Pros and Cons

Advantages:

  • You can use spans in native interop situations without being forced to copy it to an array first
  • Feature parity with C#

Disadvantages:

  • It's work
  • More special language rules

Extra information

Estimated cost (XS, S, M, L, XL, XXL): M? Just a guess.

Related suggestions: (put links to related suggestions here)

Affidavit (please submit!)

Please tick this by placing a cross in the box:

  • [x] This is not a question (e.g. like one you might ask on stackoverflow) and I have searched stackoverflow for discussions of this issue
  • [x] I have searched both open and closed suggestions on this site and believe this is not a duplicate
  • [x] 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:

  • [x] This is not a breaking change to the F# language design
  • [x] I or my company would be willing to help implement and/or test this

jwosty avatar Jun 25 '19 05:06 jwosty

I think this should definitely be allowed.

cartermp avatar Jun 25 '19 13:06 cartermp

Come to think of it, fixed should probably also support Memory<'t> directly too.

@cartermp do you think this addition should only concern itself with Span/Memory, or should it be a more general expansion to things that have GetPinnableReference?

jwosty avatar Jun 25 '19 16:06 jwosty

FSharp.Core currently doesn't depend on System.Memory. Using statically resolved type parameters with member constraints would be the way to go. Therefore, this should be a more general expansion to things that have GetPinnableReference.

Happypig375 avatar Jun 26 '19 03:06 Happypig375

@jwosty We should match what C# does here and lookfor the GetPinnableReference member. @tihan can be of help in figuring out how to determine that.

cartermp avatar Jun 26 '19 12:06 cartermp

I support this. This is a very reasonable request.

TIHan avatar Jun 26 '19 16:06 TIHan

I say we should also support arbitrary pinning of refs. For example, C# lets you do the following (shamelessly copied from the C# docs):

class Point 
{ 
    public int x;
    public int y; 
}

unsafe private static void ModifyFixedStorage()
{
    // Variable pt is a managed variable, subject to garbage collection.
    Point pt = new Point();

    // Using fixed allows the address of pt members to be taken,
    // and "pins" pt so that it is not relocated.

    fixed (int* p = &pt.x)
    {
        *p = 1;
    }
}

That way, it's a more general construct that you can use to workaround anything that's not supported directly by fixed, like in that stackoverflow answser I linked to in the OP.

jwosty avatar Jun 27 '19 15:06 jwosty

Yup, approved as far as I'm concerned.

dsyme avatar Jul 01 '19 15:07 dsyme

@dsyme what do you think about supporting GetPinnableReference vs supporting any ref? Would an RFC be approved if it contained both?

jwosty avatar Jul 01 '19 16:07 jwosty

@dsyme what do you think about supporting GetPinnableReference vs supporting any ref? Would an RFC be approved if it contained both?

I don't see why not - @TIHan do you agree?

dsyme avatar Jul 02 '19 11:07 dsyme

Here is the csharp pattern based fixed proposal that discusses GetPinnableReference

davidglassborow avatar Jul 09 '19 08:07 davidglassborow

Based on what I know right now, supporting both sounds very reasonable to me.

TIHan avatar Jul 09 '19 18:07 TIHan

Would someone mind drafting up an RFC? I could certainly try but I don't think I have enough knowledge about Span<'T> and the likes (and their inner workings in the C#/F# compilers) to do a good job.

jwosty avatar Nov 10 '19 21:11 jwosty

@jwosty, if you want to draft a RFC, we can help you fill in any gaps.

TIHan avatar Nov 10 '19 23:11 TIHan

@TIHan great, I will be more than happy to do this once I'm on Christmas break from classes... Can't wait to work on stuff other than school!

jwosty avatar Dec 10 '19 17:12 jwosty

PR submitted with a basic, incomplete RFC drafted. Help is now greatly appreciated

jwosty avatar Jan 06 '20 05:01 jwosty

Hey @jwosty , awesome that you submitted a draft! When I get some time, I will go over it.

TIHan avatar Jan 24 '20 00:01 TIHan

@TIHan not a draft anymore 🙂 https://github.com/fsharp/fslang-design/blob/master/RFCs/FS-1081-extend-fixed-expressions.md

Design discussion here: https://github.com/fsharp/fslang-design/issues/421

cartermp avatar Jan 24 '20 08:01 cartermp

would be really nice to see it implemented on par with C# fixed behaviour. ref pinning is heavily used in Silk.NET and it is currently quite tricky to port their samples to F# without this feature.

sergey-tihon avatar Sep 27 '21 13:09 sergey-tihon