OCaml mimicry in Java
engineering.vena.io
engineering.vena.io
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?
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.)