Algebrick - Bumping to v0.2 with new better type-defining-DSL

Finely I've got an idea how to improve the old-not-so-good-DSL for Algebraic type definition.

With old DSL you would define Tree type as follows.

include Algebrick::DSL
type_def do
  tree === tip | node(value: Object, left: tree, right: tree)
end

Although this looks quite nice and it's concise, it magically defines constants Tree, Tip and Node. Later when you come back to the code it's hard to find where the constants are being defined. There is no Tree = #something in the source code. IDEs like RubyMine won't find the definition either.

I've tried to improve the situation with manually setting the constants (this was never released).

Tree, Tip, Node = type_def do
  tree === tip | node(value: Object, left: tree, right: tree)
end

But this has several other flaws:

  1. If order of tip and node is changed in the definition, newly created types will end up in wrong constants since they are being returned by #type_def in order of first mention.
  2. When more types are being defined in #type_def's block it will get messy very soon.

Then I've finally realized that because #instance_eval and #instance_exec does not change the Module.nesting of the blocks, the block can be evaluated inside a scope with DSL methods keeping the constants defined in original place. This behavior allows the following definition of Algebraic types.

Tree = Algebrick.type do |tree|
  Tip  = type
  Node = type { fields value: Object, left: tree, right: tree }

  variants Tip, Node
end

It's been released in version 0.2.0.

Version 0.2.2

Version 0.2.1 just fixes release date of the gem. Version 0.2.2 adds minor improvement to the DSL. Field readers on products can be defined in DSL with methods #readers *names or #all_readers for all of them.

Node = type do
  fields value: Object, left: tree, right: tree
  all_readers
end

I hope you like the new DSL.