Skip to content

MiguelPires/Lisp-Class-System

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

31 Commits
 
 
 
 
 
 
 
 

Repository files navigation

Lisp Class System

This project implements a class system for Lisp through a set of macros. The implemented features are:

  • Classes
  • Default Slot Initializers
  • Multiple Inheritance
  • Generics
  • Multiple-Dispatch Methods
  • Auxiliary Methods

Classes

The def-class macro allows you to create a class complete with default constructor, getters, setters, recognizers. For instance, to create a class person with slots name and age and respective default methods do:

 
> (def-class person name age)
(...)
> (setf p (make-person :age 50 :name John))
#S(...) 
> (person-age p)
50
> (set-person-name p "Bill")
"Bill"
> (person-name p)
"Bill"
> (person? p)
t
 

Default Slot Initializers

It's possible to provide default initializer forms to determine the value of a form if none is provided:

 
> (def-class person name age :initform (+ 10 1))
t
> (setf p (make-person :name "John"))
#S(...)
> (person-age p)
11
> (person-name p)
"John"
 

Multiple Inheritance

The def-class macro also allows you to inherit from multiple classes:

 
> (def-class thing)
t
> (def-class being age)
t 
> (def-class (person being thing) name)
t
> (setf p (make-person :name "John" :age "22"))
#S(...)
> (person-age p)
11
> (being-age p)
11
> (person-name p)
"John"
> (person? p)
t
> (being? p)
t

Generic Functions

The def-generic macro allows you to specify a function's name and parameters, omitting the implementation. This functionality is complemented by multiple-dispatch methods, described in the next section.


> (def-generic sum (p1 p2))
SUM

Multiple-dispatch Methods

The def-method macro allows you to specify a generic function's implementation for a specific set of parameter specializers:


> (def-method sum ((person p1) (person p2)
        (format t "Adding two people's ages~%")
        (+ (person-age p1) (person-age p2))) 
SUM
> (def-method sum ((person p1) (being b2))
        (format t "Adding a person and a being's age~%")
        (+ (person-age p1) (being-age b2)))
SUM
> (sum (make-person :age 1) (make-person :age 2)) 
"Adding two people's ages"
3
> (sum (make-person :age 1) (make-being :age 2)) 
"Adding a person and a being's age"
3

Note that in the first example, both methods would be applicable since person is a subclass of being. However, the class system invokes the most specific of all the applicable methods. This is the coherent with the standard method combination of the Common Lisp Object System.

Auxiliary Methods

The def-method macro also allows you to specify auxiliary methods that are to be called either before or after the primary method. Like its counterpart in Common Lisp, this feature calls every applicable auxiliary method, not just the most specific:


> (def-method sum :before ((person p1) (person p2))
        (format t "Before adding~%"))
SUM
> (def-method sum :after ((person p1) (person p2))
        (format t "After adding~%"))
SUM
> (sum (make-person :age 1) (make-person :age 2))
"Before adding"
"After adding"

Full Method Usage

The returned value of the effective method composed of auxiliary and primary methods is the returned value of the primary method. This example showcases one possible usage of the method combination:


> (def-generic sum (p1 p2))
SUM
> (def-method sum ((person p1) (person p2))
        (format t "Adding people's ages~%")
        (+ (person-age p1) (person-age p2)))
SUM
> (def-method sum :before ((person p1) (person p2))
        (format t "Before adding~%"))
SUM
> (def-method sum :after ((person p1) (person p2))
        (format t "After adding~%"))
SUM

> (def-method sum :after ((person p1) (person p2))
        (format t "Again after adding~%"))
SUM
> (sum (make-person :age 1) (make-person :age 2)) 
"Before adding"
"Adding people's ages"
"After adding"
"Again after adding"
3

About

Implementation of a Class System for Common Lisp

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published