Skip to content

Tooling :: Interop story for .NET libraries using C# source generators for high performance #14300

Open
@T-Gro

Description

@T-Gro

I want to open the discussion on consumption of .NET libraries built using C# source gen support https://learn.microsoft.com/en-us/dotnet/csharp/roslyn-sdk/source-generators-overview .

With every .NET version, more APIs use it and is part of the reason of the unprecedented performance boosts of .NET platform for various computing tasks. A few examples include:

And I think it is only about time before database libraries or structured loggers (incl. telemetry) will have it as well.

I do not believe that F# needs it's own clone of source generators, there are concepts like type providers or Myriad which allow accomplishing similar goals. Therefore I did not continue this as a comment on fsharp/fslang-suggestions#864 , which I believe has different aspirations.

I do want to reopen the discussion from the .NET library consumption perspective, especially around libraries/frameworks that are massively backed and invested in (like aspnetcore), and are expensive to replicate and part of the big performance wins.
F# is " | Succinct, robust and performant language for .NET" and the ability to consume the fastest of .NET's libraries IMO comes with this motto.

The latest resolution I could find on the topic is "use C# project" fsharp/fslang-suggestions#864 (comment) , which makes sense in the short term (< 3 years) perspective.

However, the broader the usage of C# code gen in well established libraries, the more slices would have to be done in a project to separate the F# pieces (where F# programmers wants to write) and C# parts (simply due to libraries needing that). Important to note that it might spread multiple layers of the application, and therefore isn't just "1 F# and 1C# project", but rather an interleaved sandwich depending on the level of the stack a library is targeting. The cognitive complexity of seeing a project (which turned into a solution by now) like this is objectively bigger and the typical display by Solution Explorer does not make the dependency order visible at a first glance.

Which brings me to the tooling topic - what can we do better in order to support a smooth workflow using such libraries in a project that would want to be F#-only otherwise.

There is an older suggestion about mixed projects fsharp/fslang-suggestions#117 , which was correctly resolved as being a tooling issue and not a change to F# language itself.

My current view is that the user-facing side of this feature could look like embedding a single standalone C# file into middle of a F# project.
That C# file would have access to all project/package dependencies (this is where the source gen stuff is), F# files before it, NOT the files after it ;; and would be only accessible by F# files coming after it.
If this eliminates any worries, I think this would be handy even if always restricted to 1-C#-file scenarios only.

From the IDE side, I could imagine this being a "lightweight project within project", as well as a .cs file being within .fsproj and the F# compiler knowing to split the project into multiple compilation units, invoke Roslyn underneath and putting the results together in the right order.

I will wait for someone more knowledgeable to assess if merging the produced C# & F# ILs together is even a theoretical thought, or it if this would have to be independent .dlls on the output.

This is an XXL item

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions