4. When would you say that one should use polymorphic variants rather
than your open datatypes? (I know how to argue in the other direction:
unique constructors make for better error messages.)

I've wanted such open datatypes several times.  One example is a message bus across an application: some components can yield messages to be dispatched to all registered components.  Messages can hold data, and the set of possible messages (with the type of their associated data) is extensible (say, because components can be loaded dynamically, or just to make the application's architecture more modular).  It makes sense to use an extensible datatype to represent messages.  Components can react to messages with pattern-matching and two components can interact if their share a common constructor definition.  This is simpler than encoding open datatypes with a "universal" type (with injections/projections).  Of course, one can use the existing "exn" type, but then we don't distinguish between exceptions and messages at all.

Isn't this a good use case for polymorphic variants too ? Compared to open datatypes, you could suffer from the weaker type checks though: if two components are supposed to communicate through a constructor, which is mispelled in one of the component, the error would not be noticed by the compiler.

my own 2 cent ...
philippe.