Class-mixins are a great idea but sometimes they lead to a proliferation of subclasses with names like printable-touchable-composing-colored-shape-square-mixin and that's just ugly. Common-Lisp is a dynamic-programming language; Dynamic-Classes brings dynamism to class definition!
You define the mixins and associate them with parameters. Then you
As an example, here is some code from cl-containers iterators that hooks parameters to iterator mixins:
(add-parameter->dynamic-class
:iterator :transform 'transforming-iterator-mixin)
(add-parameter->dynamic-class
:iterator :filter 'filtered-iterator-mixin)
(add-parameter->dynamic-class
:iterator :unique 'unique-value-iterator-mixin)
(add-parameter->dynamic-class
:iterator :circular 'circular-iterator-mixin)
and here it is in action:
> (let ((i (make-iterator '(1 2 3))))
(loop repeat 5 when (move-forward-p i) do
(print (next-element i))))
1
2
3
nil
> (let ((i (make-iterator '(1 2 3) :circular t)))
(loop repeat 5 when (move-forward-p i) do
(print (next-element i))))
1
2
3
1
2
> (let ((i (make-iterator '(1 2 3) :circular t :transform #'sqrt)))
(loop repeat 5 when (move-forward-p i) do
(print (next-element i))))
1.0
1.4142135
1.7320508
1.0
1.4142135
The make-iterator function calls determine-iterator-class to handle the work of figuring how (and possibly creating) the right class given the parameters.
(defmethod make-iterator
(iteratee &rest args &key (iterator-class nil) &allow-other-keys)
(apply #'make-instance
(apply #'determine-iterator-class iteratee iterator-class args)
:container iteratee
args))
Dynamic-Classes can make prototyping a breeze (and it's lots of fun too)!
A darcs repository is available. The commands are listed below:
darcs get http://common-lisp.net/project/dynamic-classes/
Dynamic-Classes is also ASDF installable. Its CLiki home is right where you'd expect.
There's also a handy gzipped tar file.
2008-May-26 - We've split off from metatilities and are living large and on our own! More tests and documentation coming ... soon (we hope).