The DEFINER library contains an extension to Common Lisp that allows programmer to nicely reuse some common "definition" idioms.
Many CL packages extend the language by adding a slew of
(define-something-else ...)macros. Well, wouldn't it be nice to have a more controlled way to do that? DEFINER is for you. A quick hack where we extend CL to define more complex definition forms.
The idea is to provide a general macro
def and a
specialized generic function for further extensions.
The end result is to make Common Lisp
definitions look like Python.
Of course, with a twist.
def is written completely in
Common Lisp, and in Python you need to hack the
parser to extend the behavior of
Functions, macros, and methods
Basic definition forms for functions, methods and macros.
Now you say:
(def function foo (x) (+ x 42))and
(def macro foo (y) `(list ,y 42))and
(def generic bar (x) (:method ((x string)) ...))and
(def method bar :before ((x symbol)) ...)
Variables, parameters, and constants
The pattern is the same.
(def var *x*)and
(def parameter *foo* 42)and
(def constant +bar+ "bar")
To define classes now you say:
(def class reptilian (animal) ...)
There is a very straighforward rendering of
structures using the
def macro. But it is
much more fun to make the
def form for structures
behave like the
def form for classes.
Now you say:
(def structure foo (a (s 42 :type number)) (:documentation "Foo structure.") (:print-function print-foo))(Of course, nothing forbids us from reverting this to the straightforward rendering; we need to vote on this.)
You know the drill...
(def condition my-error (simple-error) ...)
(def package :foo (:use "CL") (:export "BAR"))
Who says CL does not have types? Check out
(def type forty-two () '(member 42))and
(def type buffer (x) `(vector character ,x))
Any self-respecting CL hackers will never be
satisfied with just defining a few macros. The self-respecting
CL hacker wants to show off. So, the
def macro accepts a special keyword,
definer, that allows you to bend the thing unto
The syntax of this
definer form is
(def definer for-what (&key type-of-naming-form name body-name) forms)
As an example, consider how we could have defined (as we did) the
(def definer type (:name type-name) `(deftype ,type-name ,@definition-forms))An explanation of this definition can be found in the description of the DEF macro.
So, how do you use this?
Suppose you were writing UFFI
code. You would probably make use of the UFFI
uffi:def-foreign-type macro to write things like
(uffi:def-foreign-type char-ptr (* :char))
By using the
definer facility you could now write
(def uffi:foreign-type char-ptr (* :char))It may not look much, but it seems more pleasant to the author and it has some nice side effects, e.g., for editors and IDEs writers.
How does it work?
"DEF" package (
"DEF" is a nickname)
exports two main symbols (plus a few more representing tags and
build-definition-form, a generic function.
def, the main macro.
def is the main macro used in "extended" code, while
build-definition-form is used to extend the
definition capabilities of your environment.
All in all DEFINER is just a cute hack, but it has some niceties of its own. Moreover, it makes it possible to homogeneize a natural programming practice followed by several CL programmers.
Questions? Queries? Suggestions? Comments? Please direct them at me.