For rapid prototyping purposes, I would like to start building a library of generalized versions of some basic functions provided in Common Lisp, rather than only collect (or import) special purpose functions for the task at hand. For example, the map
function is moderately generalized to operate on sequences of any kind, but does not handle adjustable vectors. Writing the special purpose extension below seems sufficient for present use, but remains limited:
(defun map-adjustable-vector (function adjustable-vector)
"Provides mapping across items in an adjustable vector."
(let ((new-adj-vec
(make-array (array-total-size adjustable-vector)
:element-type (array-element-type adjustable-vector)
:adjustable t
:fill-pointer (fill-pointer adjustable-vector))))
(dotimes (i (array-total-size adjustable-vector))
(setf (aref new-adj-vec i) (funcall function (aref adjustable-vector i))))
new-adj-vec))
What I would like to see is how to go about writing a function like this that additionally takes an output type spec (including a new 'adjustable-vector type) and allows multiple kinds of lists and vectors as input--in other words, patterned after map
.
More broadly, it would be useful to understand if there are basic principles or ideas relevant to writing such generalized functions. For example, would generic methods specializing on the output type specs be a viable approach for the above function? Or, perhaps, could leveraging map
itself figure in the generalization, as coredump illustrated in a previous post at Mapping into a tree of nested sequences? I don't know if there are any limits to generalization (excepting a certain inefficiency), but I would like to see how far it can go.