dotnet / fsharp

The F# compiler, F# core library, F# language service, and F# tooling integration for Visual Studio
https://dotnet.microsoft.com/languages/fsharp
MIT License
3.89k stars 782 forks source link

State of generative type providers for Core CLR #1088

Closed panesofglass closed 7 years ago

panesofglass commented 8 years ago

@dsyme, @KevinRansom, @NumberByColors, @dmitry-a-morozov, Tachyus has been prevented from moving to Core CLR because we currently use the SqlEnumProvider, which is a generative type provider. We use this to generate CLI enumerations, modules of constant string literals, and (soon) units of measure in our public-facing web application and services. As I understand, generative type providers use System.Reflection.Emit, which is not supported on Core CLR, and no similar API is available to replace it. Therefore, we are stuck on .NET Framework for the foreseeable future.

Is there a planned replacement for Reflection.Emit that will allow generative type providers to be ported to Core CLR?

dsyme commented 8 years ago

As I understand, generative type providers use System.Reflection.Emit, which is not supported on Core CLR, and no similar API is available to replace it. Therefore, we are stuck on .NET Framework for the foreseeable future

Just to mention that architecturally generative type providers can use any technique you like to generate a DLL - they do not intrinsically require Reflection.Emit. However the current ProvidedTypes API implementation is set up to convert F# quotations to IL using Reflection.Emit. In principle you could change that implementation to use Cecil, ILASM, fsc.exe, csc.exe or some other code generator.

forki commented 8 years ago

@eiriktsarpalis @terrajobst are there any public plans about Reflection APIs on coreclr?

smoothdeveloper commented 8 years ago

@dsyme it would be super valuable to have Microsoft provided SDK samples (they provide so much on MSDN accross the spectrum of products) showcasing generative type providers relying on simple code generation.

With generative type providers, in workplace where adoption of F# is not agreed upon, it is still possible to leverage amazing libraries to generate types for other language consumptions.

It is in Microsoft interest to make this use case of F# shine so that C# and VB.NET users can leverage the work the F# TP library implementers are doing.

I would have no obstacle implementing such TP for internal use but I have to admit that the documentation and attempts I've made about implementing generative TP didn't get me there, while robust SDK documentation and more extensive samples (using various type generation approaches) would be helpful.

7sharp9 commented 8 years ago

Maybe a semi-transparent spike could be using the ikvm reflection /cc @panesofglass @dsyme

terrajobst commented 8 years ago

@forki

are there any public plans about Reflection APIs on coreclr?

Yes! https://github.com/dotnet/apireviews/tree/master/2016-01-19-reflection#stakes-in-the-ground

To answer the original question: Ref Emit is supported on CoreCLR. What isn't supported is using Ref Emit to generate a PE file on disk. For that, we recommend either using Roslyn or the upcoming metadata writer APIs.

panesofglass commented 8 years ago

Thank you for the clarification, @terrajobst!

7sharp9 commented 8 years ago

So:

We don't want to allow developers to extend the reflection object model by inheritance, so we don't need to expose any of the protected *Impl methods.

Does that mean anything for type providers and the derived methodinfo etc that they use, or is this strictly runtime by which time the desktop model has built the type etc.

I guess it would effect type providers that were running/generating/designtime under a .Netcore system infrastructure.

enricosada commented 8 years ago

i dont know if it's useful at all because i dont know enough of gen providers, but i see aspnet team has some issue with view precompilation (that's similiar right?).

so i can add discussion about code generating in roslyn and @jaredpar [generator comment)(https://github.com/dotnet/cli/issues/1812#issuecomment-213028113)

terrajobst commented 8 years ago

Does that mean anything for type providers and the derived methodinfo etc that they use, or is this strictly runtime by which time the desktop model has built the type etc.

I don't know enough about F# type providers to answer that question. In general, the reflection OM was made extensible so that one is able to also represent non-runtime type information, i.e. for inspecting a different set of .NET assemblies that don't match the ones used by the running code. However, due to the design of the reflection APIs certain concepts (such as unresolved types) can't easily be represented. Since we didn't know at the time how we want to move this forward in .NET Core, we decided to disallow extensions so that we've more flexibility in the future.

terrajobst commented 8 years ago

i dont know if it's useful at all because i dont know enough of gen providers, but i see aspnet team has some issue with view precompilation (that's similiar right?).

@jaredpar is the best person to answer this, but I'd say they are related by quite different. Generators are for adding SyntaxTrees during compilation. In other words, a generator is a piece of code that is able to add additional source files without having to write them to disk. This is useful for all areas that today use the .Desginer.cs extension. It's less overhead for the build system and thus is less prone to weird errors.

However, generators will not necessarily allow you to modify existing code or extend the language. My understanding of type providers is that they allow a piece of code to lazily construct types as the developers "dots" into the type, allowing the provider to make, for instance, network requests to download schema information. A generator might be able to do the same thing, however, it has to provide all the type information up-front (AFAIK).

jaredpar commented 8 years ago

The code generator features proposed for Roslyn is essentially two features:

  1. The ability to augment a Compilation with SyntaxTree values. The plugin point for adding them has a similar interface as analyzers. Hence it can do deep inspection on values (trees, symbols, etc ...) as a part of deciding what code to dump.
  2. The ability to replace methods / properties defined in source with new versions defined in a partial class. This means types can opt into having their behavior extended / modified by generators. Allows for scenarios like making INotifyPropertyChanged automatic.
dsyme commented 7 years ago

I think we should close this. Type providers in general are for "vNext" of the F# .NET Core support so tracking the specific case of generative type providers doesn't seem necessary.