Version 0.2.0. of the Concatenative DSL has been released.
Here are some highlights from the changelog:
- Implemented new combinators:
- binrec
- split
- twodip
- threedip
- Performance improvements:
- Stack is never copied.
- No symbol/string conversion when processing words.
- Pseudo-namespace support (e.g. :kernel/:while and :math/:factorial)
- ~ and <= operators to unquote and define words, respectively.
- No more uppercase words!
Oddly enough, I realized that it is possible to defined methods named after reserved words like “while”
or “if”, so now all the concatenative words (combinators) in kernel.rb
are now defined
without a leading undersore. Similarly, there's no real need to use UPPERCASE
symbols, so as a result, method lookup is significantly faster and will use less resources.
Here's how the lookup works. Say you have the following program:
[[1,2,3], [4.5.6], :concat]
If :concat
has been defined by the user (:concat <= [...]
), that definition will be
used, otherwise the Concatenative::Kernel
combinator concat
will be called. If you want to
use the corresponding Ruby method, all you have to do is specifying the arity explicitly using the |
operator.
To remove any ambiguity, it is now possible to specify the namespace of a word explicitly, e.g.
:kernel/:concat or :ruby/concat. The /
operator simply concatenates the two symbols together
(:"kernel/concat"
) and sets the namespace (:kernel
) and name (:concat
) of the
new symbol. :kernel
and :ruby
are not meant to be used when defining new words, but you
can use anything else you like, for example :math/:factorial or :local/:a, etc.
As I pointed out in the first article about concatenative, even with the new performance improvement a concatenative program still runs slower than a standard Ruby program, but at least now you won't run out of stack space (the Ruby stack, in this case) too soon.
If you have any issues to report, feature requests, etc., feel free to use GitHub to do so.