Named multiple-values
Named-multiple-values is a piece of macrology that enables one to deal with Common Lisp's multiple-values somewhat abstractly. That is, you may refer to a set of values by name, and also particular values by name.

named-multiple-values.lisp might be considered to be a convenience library. It defines a single macro, called named-multiple-values:define-named-multiple-values. This macro generates two macros, whose names it returns. See the example.

Example

Here is an example of what it can look like:

  (define-named-multiple-values foo-values (bar zot zut)
    (:all &all))
=> FOO-VALUES, FOO-VALUES-BIND

  (foo-values () :bar 'barney :zut 'zutteklut)
=> BARNEY, NIL, ZUTTEKLUT

  (foo-values-bind (&zut my-zut &bar local-bar)
      (values 1 2 3)
    (list my-zut local-bar))
=> (3 1)

  (foo-values-bind (&all default-foos)
      (values 1 2 3)
    (foo-values (:defaults default-foos)
      :zot 'special-zot))
=> 1, SPECIAL-ZOT, 3

However, named-multiple-values is not expected to be particularly useful for interactive work, see the "background" section.

Description

I will offer two analogies to the concept of named-multiple-values:

  • Multiple-values are similar to functions' argument-lists, where the latter is "down-stream", and the former is "up-stream" flow of information. Much like Common Lisp---by use of &key---allow you to pass arguments (down-stream) to functions by name rather than position, you can now generate up-stream multiple-values by name.
  • Common Lisp's defstruct offers the possibility of defining abstract types whose concrete type is (for example) a list. So while the type abstractly consits only of members a, b, and c, in reality there will be a list of length three, whose first element is a, second element is b, and third is c. Named multiple-values are very much the same thing, except the set of values only exists as an abstract entity: No list or anything else is ever consed up, since the value-sets as such never exist as lisp objects. Consequently, they cannot be passed around between functions.

Background

What is named-multiple-values useful for? I'm not quite sure. This code is factored out from a project where I had many tens of functions that followed the same protocol, both down-stream and up-stream. That is, the functions accepted the same parameters, and returned the same values. Being the lisper that I am, I took advantage of this regularity in the code by having macros that dealt with both directions of the protocol. This added greatly to the clarity of the code, and saved me a lot of editing.

While the down-stream part of my original project's macrology was rather trivial, and didn't really provide that much beyond what &key already does, the up-stream part I thought might be more interesting for more general-purpose use. So here it is, available as finished code, or just as and idea you might find usable in your own code.

Because this code is factored out and modified quite a bit from my original project with well-tested code, and abstracted into what I suppose might be called a higher-order-macro (a macro-writing macro, that is), I fully expect there to be bugs and quirks. So this code should perhaps be considered more as a description of an idea than a ready-to-use library.

Comments are welcome.

I (Gary King) am not sure that I follow but are named-multiple-values similar to returning property lists but without the consing?

Yes, I think that would describe it reasonably. If you want to return numerous values and would prefer to refer to each value by name rather than ordering, you can use ``Named multiple-values''.


macro example