home

Protocols and libraries

2012-05-12

I am thinking about building a protocol for finance libraries; this protocol needs to wrap some other libraries and provide a consistent interface for the common results from these libraries. Ideally, each library doesn’t know about this hypothetical protocol; they can be developed independently.

Suppose we have cl-finance-queries, a generic protocol.

cl-finance-queries provide a method to gain information from an arbitrary endpoint library. The library doesn’t really know anything about cl-finance-queries. The last requirement really messes things up; it requires adaptor code to be created to transform the endpoint code into a final normalized form.

Suppose I require that a finance library supply a number of functions with certain names: cl-finance-queries digs around the namespace and all functions meeting the name are used. This lays an obligation on the namespace library and would almost certainly require creating adaptor code on the library’s side.

Suppose that I supply a number of defgenerics and require that a finance library supply a defclass with defmethods that meet the defgenerics. This almost requires an idea of a Connector object who doesn’t really store data, but only truly serves as a mechanism for type specialization on generic functions.

Still thinking about this. The specification for an endpoint library to not know about the protocol is probably sane.

My ideal code looks like this:

` (ql:quickload :cl-yahoo-finance) (ql:quickload :cl-finance-queries)

(cl-finance-queries:current-stock-data :cl-yahoo-finance "IBM"). `

Note that this imposes no knowledge from cl-yahoo-finance of what cl-finance-queries is or does. I could as easily swap in some :cl-google-finance and theoretically, magic would happen and the same answers would come back.

However, perhaps Google requires a login token, so really what it will be is:

(let ((session-token (make-instance 'cl-google-finance :usename user :password password))) (cl-finance-queries:current-stock-data session-token "IBM"))

This seems very reasonable as well: why should the protocol expect only a namespace, and not an object denoting a session?

Maybe configuring an adaptor class is the proper way to go about it, using this modality.:

  • cl-finance-queries has a session class
  • cl-finance-queries has a list of generic functions
  • cl-yahoo-finance gets an extension cl-yahoo-finance-queries which implements the generic functions and defines a session class which inherits from the cl-finance-queries class.