Method Versions — Retracted May 19th, 2011
Patrick Stein

When I wrote the method-versions library, I had read about ContextL and decided that I only wanted a very small subset of it and wanted it to be very easy to use. It turns out that I didn’t quite understand the complexity-level of ContextL. It is actually very similar to what I had wanted.

With my library, you set up some versions and a variable to track the current version:

(method-versions:define-method-version :v1.0)
(method-versions:define-method-version :v1.1 :v1.0)

(declaim (special *protocol-version*))
(defparameter *protocol-version* :v1.0)

In ContextL, you just set up some layers:

(contextl:deflayer :v1.0)
(contextl:deflayer :v1.1 (:v1.0))

In my library, you then set up a generic function that uses a special method combination that keys off of the special variable:

(defgeneric send-cmd (cmd)
  (:method-combination method-versions:method-versions-method-combination
                       *protocol-version*))

In ContextL, you declare a layered function:

(contextl:define-layered-function (cmd))

In my library, you then declare different methods using the version as a method qualifier.

(defmethod send-cmd ((cmd login-cmd))
  (send-string (login-name cmd))
  (send-string (login-password cmd)))

(defmethod send-cmd :v1.0 ((cmd login-cmd))
  (send-string (login-name cmd))
  (send-string (login-password cmd))
  (send-string (login-location cmd)))

In ContextL, you declare layered methods specifying which layer the functions belong to:

(contextl:define-layered-method send-cmd ((cmd login-cmd))
  (send-string (login-name cmd))
  (send-string (login-password cmd)))

(contextl:define-layered-method send-cmd :in :v1.0 ((cmd login-cmd))
  (send-string (login-name cmd))
  (send-string (login-password cmd))
  (send-string (login-location cmd)))

In my library, you set your special variable appropriately and invoke the method:

(let ((*protocol-version* :v1.1))
  (send-cmd cmd))

In ContextL, you declare which layer you want to be active when you go to invoke the method:

(contextl:with-active-layers (:v1.1)
  (send-cmd cmd))

My library does not let you specify other method qualifiers like :around or :after. ContextL does.

I am going to leave my library published because I think it is a reasonably understandable, yet non-trivial, use of non-standard method combinations. However, I am going to end up using ContextL for the projects that I had intended for my library.

Method Versions — v0.1.2011.05.18 May 18th, 2011
Patrick Stein

Edit: After re-reading some of the ContextL papers, I believe that I am actually just going to use ContextL as it’s a much more flexible superset of this library. I will probably still keep this library published as an example of a non-trivial, but glarkable, method combination.

I am releasing a new library that allows one to dispatch generic methods based on the value of a global parameter.

There are situations where one might like to dispatch a method on some information other than the required parameters of the method. For many situations, it is sufficient to switch between those methods based on some external parameter. The method-versions library allows one to do just that.

Obtaining

Internationalization Example

In this example, we do a silly form of internationalization. To that end, we will use English as the default language and define some other languages.

 (method-versions:define-method-version latin)
 (method-versions:define-method-version pig-latin)
 (method-versions:define-method-version french latin)
 (method-versions:define-method-version spanish latin)

We will prepare a language parameter and a welcome method that is versioned on the language.

 (declaim (special *language*))
 (defparameter *language* nil)
 
 (defgeneric welcome ()
   (:method-combination method-versions:method-version-method-combination
                        *language*))

And, we define welcome methods for the various languages (accidentally forgetting spanish).

 (defmethod welcome () :welcome)
 (defmethod welcome :latin     () :velkominum)
 (defmethod welcome :pig-latin () :elcomeway)
 (defmethod welcome :french    () :bonjour)

Then, we will try each of the languages in turn.

 (mapcar #'(lambda (ll)
             (let ((*language* ll))
               (welcome)))
         '(nil :latin :pig-latin :french :spanish))
 => (:welcome :velkominum :elcomeway :bonjour :velkominum)

USerial — v0.6.2011.05.12 May 12th, 2011
Patrick Stein

The latest release of my USerial library provides a way to make a simple serialize/unserialize pair for a list where every item can be serialized using the same key.

(make-list-serializer :list-of-integers :uint32)

(with-buffer (make-buffer)
  (serialize :list-of-integers '(1 2 3 4 5 6 7))
  (buffer-rewind)
  (reduce #'+ (unserialize :list-of-integers))) => 28

Here is the latest:

USerial — v0.5.2011.04.21 released April 21st, 2011
Patrick Stein

I am releasing a new version of my USerial library.

This release extends the (make-slot-serializer ...) and (make-accessor-serializer ...) so that you can pass an existing instance into the unserializers with the :object parameter rather than having the factory form allocate a new instance.

This release also provides ways to serialize and unserialize from slots and accessors in other code to allow even greater flexibility:

(serialize-accessors* (:string person-name
                       :uint8  person-age
                       :string person-hair-color)
     *person-instance* :buffer buffer)

(unserialize-slots* (:string name
                     :uint8  age
                     :string hair-color)
     *person-instance* :buffer buffer)

The serialize-slots* and unserialize-accessors* macros are also available.

Here is the latest:

Edit: Special thanks to Elliott Slaughter. The above improvements came out of recommendations from him.

USerial — v0.4.2011.04.11 April 12th, 2011
Patrick Stein

Made an addition to the USerial library to support logging of binary messages (so far only cl-log supported).

(serialize-log :log-category :uint32 uint-to-log :string "string to log" ...)

Here is the latest tarball: userial_0.4.2011.04.11.tar.gz and its signature: userial_0.4.2011.04.11.tar.gz.asc.

l