Custom equals, hashCode, toString, Comparable, etc - JamesIry/jADT GitHub Wiki

track this issue

Out of the box jADT generates equals, hashCode, and toString methods. For many purposes they're adequate, but not for all purposes. Further, other common Java standards such as Comparable are shut off from jADT.

Allowing users to put Java in a jADT file sounds like a bad idea. So I'm not going there.

Here's the sketch of a plan.

Stop automatically generating equals, hashCode, and toString unless specifically requested. Rough thought is something like Haskell's "deriving", e.g. Foo = Bar | Baz deriving toString, equals. Details to be ironed out.

After that there are a couple of options for allowing custom implementations.

Plan A

Allow a jADT data type to extend another class, something like Foo extends BaseFoo = Bar | Baz

The idea is that a user could write BaseFoo as a package private class in the same package as Foo. He or she could make BaseFoo implement Comparable, do a custom toString, equals, and/or hashCode, etc. How would the methods be implemented? Using the standard Foo visitor interfaces, of course.

That does mean that BaseFoo depends on Foo and Foo depends on BaseFoo, which is ugly. But as long as BaseFoo is package private it becomes an implementation detail.

Plan B

That's a good plan but I'm not overly fond of implementation inheritance if it can be avoided.

Rather than extending a base class users could make Foo implement an interface and then delegate custom method calls to a second class that the user writes.

Foo implements Comparable = Bar | Baz delegates FooImpl { int compareTo(Foo other) String toString() int hashCode() boolean equals() }

Then FooImpl would look like

class FooImpl { public void FooImpl() {}

public int comparTo(Foo self, Foo other) {
  //...
}

public String toString(Foo self) {
  //...
}
// etc

}

In other words, every method mentioned as a delegate in Foo must be implemented in FooImpl with an extra "self" param.

⚠️ **GitHub.com Fallback** ⚠️