Out of curiosity, did you try using dialyzer? I understand ADTs are strictly better, but was there a particular problem that dialyzer couldn't pragmatically solve for you?
I never took the time to figure out what Dialyzer could and couldn't catch. This was a few years ago, so I don't really have any particular examples in mind anymore, but IIRC it may have had to do with being mostly unable to validate the structure of tuples as parameters to functions.
> validate the structure of tuples as parameters to
> functions.
Dialyzer can definitely do that, you just need to specify a type that is a tuple: -type something() :: {Thing :: thingtype(),
Thing2 :: thing2type()}.
%% ...
-spec foo(something()) -> thingtype().
But I agree that Dialyzer can feel incomplete. It's been a little while now but I recall having to use `term()' in specs (basically, untyped) to suppress false positives in some cases. It was also quite slow.Still, a much better situation than Ruby.