RSS Feed

Lisp Project of the Day

defclass-std

You can support this project by donating at:

Donate using PatreonDonate using Liberapay

Or see the list of project sponsors.

defclass-stdmacroclos

Documentation😀
Docstrings😀
Tests 😀
Examples😀
RepositoryActivity🥺
CI 😀

This library provides a shortcut macro to define CLOS classes. Today I needed to define a class which will store stock candles data. It will keep data in the columns.

With defclass-std we can define such class like this:

POFTHEDAY> (defclass-std:defclass/std candles ()
             ((timestamps
               lows highs
               opens closes
               volumes)))

It will be expand into the defclass full of accessors, init forms, etc:

(defclass candles nil
  ((timestamps :accessor timestamps
               :initarg :timestamps
               :initform nil)
   (lows :accessor lows
         :initarg :lows
         :initform nil)
   (highs :accessor highs
          :initarg :highs
          :initform nil)
   (opens :accessor opens
          :initarg :opens
          :initform nil)
   (closes :accessor closes
           :initarg :closes
           :initform nil)
   (volumes :accessor volumes
            :initarg :volumes
            :initform nil)))

But what I really want is a class with custom initforms and readers, prefixed by class name.

Here is the class definition I had before discovered the defclass-std.

(defclass candles ()
  ((timestamps :reader candles-timestamps
               :initform (make-time-vector)
               :initarg :timestamps)
   (lows :reader candles-lows
         :initform (make-price-vector)
         :initarg :lows)
   (highs :reader candles-highs
          :initform (make-price-vector)
          :initarg :highs)
   (opens :reader candles-opens
          :initform (make-price-vector)
          :initarg :opens)
   (closes :reader candles-closes
           :initform (make-price-vector)
           :initarg :closes)
   (volumes :reader candles-volumes
            :initform (make-volume-vector)
            :initarg :volumes))
  (:documentation
   "This is stock candles candles."))

Here is how defclass-std can make this definition shorter and DRY:

(defclass-std:defclass/std candles ()
  ((timestamps
    :ri :with-prefix
    :std (make-time-vector))
   (volumes
    :ri :with-prefix
    :std (make-volume-vector))
   ;; Columns, having common options
   ;; can be grouped together!
   (lows highs opens closes
    :ri :with-prefix
    :std (make-price-vector)))
  (:documentation
   "This is stock candles storage."))

It will write :initarg and :reader for each slot. Also, slot's :initform will have the value, provided after the :std keyword.

The syntax can be made even shorter, but such format is not supported yet:

(defclass-std:defclass/std candles ()
  ((timestamps
    :std (make-time-vector))
   (volumes
    :std (make-volume-vector))
   (lows highs opens closes
    :std (make-price-vector)))
  (:default-slot-opts :ri :with-prefix)
  (:documentation
   "This is stock candles storage."))

This can make class definitions as concise as defstruct.


Brought to you by 40Ants under Creative Commons License