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

Emit Discriminated Unions #306

Open
JaggerJo opened this issue Apr 27, 2019 · 7 comments
Open

Emit Discriminated Unions #306

JaggerJo opened this issue Apr 27, 2019 · 7 comments

Comments

@JaggerJo
Copy link
Member

JaggerJo commented Apr 27, 2019

I'm currently playing around with building a DSL for Avalonia UI. I looked at how Fabulous generates types one time.

It would be interesting to create the DSL dynamically using a (generative) type provider. In my case I would like to generate DU's for all implementations of IControl.

type ButtonAttr =
| Name of string
| Width of float

This would make it extremely simple to use 3rd party controls, because bindings are generated at compile/ design time.

Currently it is (as far as I know) not possible to emit F# specific types like Records or Discriminated Unions from a Type Provider.

  1. Why isn't it possible to generate F# specific types (aren't they just nested classes with custom attributes/metadata after all) ?
  2. Is there a general interest in making this possible (or is it just me wanting this) ?

EDIT:
just found out there is a discussion about using a TP in Fabulous

@smoothdeveloper
Copy link
Contributor

There is a language suggestion regarding provided DU & records: fsharp/fslang-suggestions#154

And another one to be able to pass types to type providers: fsharp/fslang-suggestions#212

@dsyme
Copy link
Contributor

dsyme commented May 7, 2019

  1. Why isn't it possible to generate F# specific types (aren't they just nested classes with custom attributes/metadata after all) ?

The main thing is that it's just a lot of work. The way TPs are architected (providing .NET System.Type/MethodInfo etc. and the compiler converts them to F# TAST nodes) effectively means we have to fully invert the compilation process from .NET IL types --> F# TAST types. This is implemented in tast.fs and infos.fs in the F# compiler for methods, types, properties, events but there is no corresponding inversion for F#-defined union/record types.

The inversion would be similar to that implemented in FSharp.Reflection.FSharpType/FSharpValue based on the attributes etc. But it's painful to implement and fully test accurately.

  1. Is there a general interest in making this possible (or is it just me wanting this) ?

Yes, people are interested in this

@JaggerJo
Copy link
Member Author

JaggerJo commented May 8, 2019

@dsyme Thank you for the explanation (If you don't mind I have on further question).

If generating TAST in F# would be simple enough, the TAST could be given straight to the Compiler, then compilation could happen as usual. Why is it the other way around (Type/MethodInfo -> TAST) ?

@dsyme
Copy link
Contributor

dsyme commented May 13, 2019

If generating TAST in F# would be simple enough, the TAST could be given straight to the Compiler, then compilation could happen as usual. Why is it the other way around (Type/MethodInfo -> TAST) ?

The TAST is an internal compiler representation and not deemed to be sufficiently stable nor simple enough to allow direct generation.

@JaggerJo
Copy link
Member Author

Thanks for the explanation, should I close this now ?

@dsyme
Copy link
Contributor

dsyme commented Jul 19, 2019

@JaggerJo It's ok to leave it open I think

@Luiz-Monad
Copy link

Luiz-Monad commented Feb 5, 2020

What about providing the FSharp compiler services interface to a TypeProvider, so it can get better metadata?
And with ProvidedDU and ProvidedRecords, that would increase the flexibility.
Perhaps we could have a DSL for creating the relevant part of the TypeProvider output that will become the TAST. (of course you wouldn't expose the real TAST)
I don't mind it being internally represented by Type/MethodInfo, but wouldn't it be simpler having a specific AST/DSL for TypeProviders ? (nothing impedes someone doing that and it creating the Quotation expressions needed, that's precisely how I'm thinking to tackle my TypeProvider )
[edit: after reading other topics, I guess I have my historical reasons answer]

But FSharpCompilerServiceTypeProvider, that would be a fun thing !

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

4 participants