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:
- If order of
tip
andnode
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. - 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.