Closed endeavour closed 4 years ago
Ignoring the discriminated union issue, what's to stop you from referencing a C# assembly from F#? That is -- why not just use C# to define your contracts and serializers, then invoke them from your F# code? I don't have any experience with F#, but my understanding is that these types of scenarios are supported.
You're right, that is absolutely supported and it's what I'm using currently. The FlatBufferUnion thing just kind of bugs me :)
Ah, okay. Makes more sense now. I played with unions for a few minutes. This F#:
type Shape =
| Rectangle of width : float * length : float
| Circle of radius : float
| Prism of width : float * float * height : float
Decompiles into this pile of c#. It's almost 800 lines long!
That's not something that I'm eager to try and codegen. I have a few questions for you:
TryGetItem1
, the method would be more along the lines of TryGetRectangle
. Certainly possible, but I'm not sure how helpful it is.I was more thinking of writing an alternative Flatsharp.Compiler project that generates .fs files instead of .cs, but it looks like it uses some Roslyn stuff so I guess this isn't (easily) possible?
Another option might be to generate a .fs file containing a bunch of Active Patterns so that the C# type can be used with pattern matching in F#. I guess this wouldn't be quite as good as native DUs because the syntax would be a bit different it would lack exhaustiveness checking but it could be a quick win. If I get some time over the next few days I'll try and knock a prototype up.
Feel free to give it a try :) I don't know enough F# to undertake anything like that at this time. However, it looks like the F# compiler is open source, so you may be able to do something analogous to what I'm doing with Roslyn. The flow right now for CodeGening FBS files is a two-pass process:
Pass 1: Use Antlr to parse the .fbs file and generate C# contracts with FlatSharp attributes. This just creates class definitions for tables and structs, but no serializers or rpc definitions.
Pass 2 (necessary when fbs file calls for a precompiled serializer or gRPC stuff): Take the C# from pass 1 (data contracts), and compile an in-memory assembly with it. Then pipe that through FlatSharp to generate serializers just like you would as if you defined your contracts in C#. Take the resulting C# serializer code, merge it with the C# contracts we just generated, and dump it to the output file.
While it's a little convoluted, the advantage is I only have to write each part of the CodeGen once. The only thing the .FBS files really do is generate contracts. The serializer code still comes from the same place.
Closing due to inactivity
Would be fantastic to be able to generate F# code as well as C#. In particular, F# supports discriminated unions natively so the clunky FlatBufferUnion could be removed.