Hacker News new | past | comments | ask | show | jobs | submit login
OCaml mimicry in Java (vena.io)
7 points by PDoyle on May 30, 2016 | hide | past | favorite | 3 comments

I translated the OCamel code to java with derive4j, takes <60 lines, took me ~15 mins: https://gist.github.com/jbgi/2d26c2b30b658ea84b3e458cc8e846a... Do not bother writing a "builder-generator" for algebraic data types: it already exists: https://github.com/derive4j/derive4j ;-)

Don't know much OCaml (understatement...) but the way I understand it an OCaml type-switch like the expr one is essentially enumerating the different ways one can construct an expr. True is an expr, so is False, etc. - these are constructors of expr not functions as I see it. So I'd code that in Java/C++ as a hierarchy that uses dynamic binding to achieve the case-specific computation for the evaluation (since in OO, it's the compiler that should be writing the switch'es) - in C++ [edit - some pointers don't render; all fields are pointers to expr]:

struct expr { virtual bool eval() const = 0; }

struct True : public expr {bool eval() const {return true;}};

class Not : public expr { expr exp; public: Not( const expr & e ) : exp( &e ) {} bool eval() const {return e->eval();} };

class And : public expr { expr exp1, *exp2; public: And( const expr & e1, const expr & e2 ) : exp1( &e1 ), exp2( &e2 ) {} bool eval() const {return exp1->eval() && e2->eval();} };

And so forth. Different type constructors -> different sub-classes of the abstract type. Functions operating on the type -> methods of the parent class, that each sub-class overrides.

If instead of expr and True/False we had Shape and Triangle/Rectangle that we're more used to looking as forming a hierarchy, it might make it easier to see my point. Isn't this the Java/C++ way for doing so? If not, what am I missing here?

You're right, that's the Java/C++ way. I was trying to do it the OCaml way in Java. :-)

Ultimately, what I wanted was a way to declare the variants in one place. I didn't want to repeat myself. The only way I could think of declaring them once, and still being able to both produce and consume values of those types, was with a generic visitor interface.

You've done it with a C++ class hierarchy, which has the following properties that the OCaml solution does not:

First, it needs to repeat the components of each variant type three times: once as field declarations, once as constructor arguments, and once as initialization statements in the constructors. The OCaml one (and my Java one) lets you declare the types, fields, and constructors in one line of code.

Second, your code is arranged into classes, which means that adding a new function (say `toString`) requires adding new code in N places, for N types. In OCaml, you'd just write one new function with N variants. (Of course, your code is better if you want to add a new type.)

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact