:description "A CLOS-style object system based on Janet tables"
:author "Z. D. Smith <firstname.lastname@example.org>"
An object system for Janet, inspired by CLOS.
The Janet language provides a simple form of object orientation using
tables and prototypes:
Janet tables can have *methods* by storing functions at a keyword on
the table. When called with method syntax `(:method-name object)`,
the call is translated into a function call to that function with the
object itself as the first argument.
Janet provides prototypal inheritance. Any table may have a prototype
set, whereupon any value access at that table that returns `nil` will
recurse upwards to the table's prototype.
`fugue` provides a more powerful set of commands that extend the
existing OO dynamics of Janet with a more elaborate interface and set
`defproto` is the main entrypoint to fugue, allowing users to define
*Prototypes*. These are Janet tables with some additional metadata
included, as well as a constructor method added at `:new`. `defproto`
takes arguments that govern how new instances are created, as well as
allocation rules, ie, the configuration determining which object
fields should be populated at the instance level and which at the
## `fugue/defgeneric` / `fugue/defmethod`
`defgeneric` provides the interface for creating and managing *Generic
Functions*---functions which can be extended for additional
Prototypes. Generic functions may have a default behaviour, which is
then specialized for Prototypes via `defmethod`. Methods can be
specialized for a single argument---the first argument---and child
prototypes can inherit methods from their ancestors. They can also
call ancestor methods by invoking `(prototype-method)` within their
own method bodies.
`defmulti` allows the creation of *Multimethods*. Unlike Generic
Functions/Single Methods, Multimethods can be defined for the types of
all of their arguments, not just the first one. They are also not
limited to fugue Prototypes, being definable over any Janet type or a
fugue Prototype. Also unlike Single Methods, they are *not*
inheritable; a multimethod defined for an ancestor Prototype will not
be selected for any descendent prototype instances.```)