
Namespacing Variants in ML - halst
http://keleshev.com/namespacing-variants-in-ml
======
gabelevi
I'm also a fan of namespacing variants, and I used it extensively on an OCaml
representation of the SpiderMonkey AST. (Coincidentally, up until writing our
own parser we were using pfff's JavaScript parser! Go pfff!). Anyway, here are
some other useful things I found in OCaml along the way:

Without namespacing, you might be using mutually recursive type definitions
like

    
    
      type statement = ExpressionStatement of expression
      and expression = FunctionExpression of statement list
    

to do this with modules you need to use recursive modules, like

    
    
      module rec Statement : sig
        type t = Expression of Expression.t
      end = struct
        type t = Expression of Expression.t
      end
    
      and Expression : sig
        type t = Function of Statement.t list
      end = struct
        type t = Function of Statement.t list
      end
    

One of the sucky things about recursive modules is that you cannot omit the
signatures, however if your modules only include types then there is a
shortcut that looks like

    
    
      module rec Statement : sig
        type t = Expression of Expression.t
      end = Statement
    
      and Expression : sig
        type t = Function of Statement.t list
      end = Expression
    

Links: Big real world example:
[https://github.com/facebook/flow/blob/3a5b4040b7d2a648f97a06...](https://github.com/facebook/flow/blob/3a5b4040b7d2a648f97a06c93d9dc352c3e2b008/src/parser/spider_monkey_ast.ml#L85)

Recursive module docs: [http://caml.inria.fr/pub/docs/manual-
ocaml-400/manual021.htm...](http://caml.inria.fr/pub/docs/manual-
ocaml-400/manual021.html#toc75)

------
mercurial
Or you can use polymorphic variants in OCaml:

    
    
       type color = `Red | `Green | `Blue | `Black | `Brown
       type hair_color = `Black | `Brown | `Blond

~~~
jallmann
In OCaml 4.01, the compiler is smart enough to distinguish between
constructors with the same name but a different type -- so those variants
wouldn't even need to be polymorphic anymore. This also partially mitigates
the need for 'namespacing' your variants.

~~~
mercurial
Oh, that's pretty nice. OCaml really gets namespacing problems out your way.

------
padator
One thing to consider though is the grepability of a codebase. By relying more
on nested modules, module aliases, opens, local opens, then many constructors
have more than one way to be written and it makes it harder for grep to find
what you look for. Of course people should not use grep and instead rely on
IDE or tools that understand deeply the programming language being edited ...
which makes the problem I mentioned go away. But still it's nice to have the
possibility to use simple tools like grep and that they would simply work.

