Question

I am looking into using System.ComponentModel.Composition in Fsharp and was wondering if it is possible to dynamically generate a Discriminated Union in memory? I would like to have DU that is built off elements of the types that are imported. The main reason is that I have code that works of a DU and I thought it most simple to use that with Composition. I am fully prepared to accept that this is the wrong thing to do.

I have used FSharpType and FSharpValue for various things in the past, but it seems that these are about manipulating existing DUs not creating new ones.

I am sorry to say I don't even yet have an 'I tried this' code sample because I don't know where to start.

  • Is it possible?
  • Is it advisable?
  • Should I actually not be using a DU to represent what comes from Composition?
  • I am happy to use reflection even though it is a bit slow.

edit

  • Is it possible/advisable to dynamically add to a DU? (If a DU has to exist)
Was it helpful?

Solution

One of the big advantages of discriminated unions is that the set of possible cases is known at compile-time, so the compiler can tell you when your code doesn't handle a possible case. This helps a lot with refactoring as you can add a new case to an existing union and the compiler will tell you what places in the code need to be changed.

Another benefit is that pattern-matching on discriminated unions is syntactically elegant - you can write very clear code.

In theory you can probably dynamically generate a DU with Reflection.emit, or perhaps even add new cases to an existing one. However neither of the advantages above will apply so I don't really see much point in using them at all.

A standard inheritance model is also the right way to deal with dynamically loaded plugins, IMO. Define an interface or common base class in a DLL that each plugin depends on, have the plugin define a class that implements it, and then use methods on that interface/base class on the plugin once loaded.

DUs are designed to fix the set of possible /values/ in advance but make it easy for anyone to write a new function over the DU, whereas object-oriented inheritance is designed to fix the set of possible basic /functions/ in advance but make it easy for anyone to add new values. Since loading code dynamically is all about adding new values, I think it's a very natural fit.

It's worth mentioning in passing that DUs are actually implemented using .NET inheritance by the F# compiler - there's a base class for the entire union type, and then individual derived classes for each union case (though I think argument-less cases get treated specially).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top