Monthly Archives: March 2014

The less-familiar parts of Lisp for beginners — multiple-value-list

Another variation for working with multiple values is multiple-value-list.  A newcomer to Lisp is likely to have encountered multiple-value-bind, which allows the individual returned values to be assigned to new variables, but may not have seen multiple-value-list.  This macro retrieves the values from a form and inserts them, in order, in a new list, which is then returned.

The less-familiar parts of Lisp for beginners — multiple-value-call

Continuing the series of less commonly-encountered Lisp features, multiple-value-call.  This function is much like funcall, but over multiple values.  If functions returning multiple values is unfamiliar to you, check the brief digression on the topic of values in this earlier post.

When funcall is invoked, if any of the arguments are forms, those forms are evaluated and the primary value is used in the function invocation.  Any additional values are discarded.  The multiple-value-call special operator captures all values returned by those forms and inserts them, in order, in the argument list before calling the function.  This is best illustrated with a simple example:
 

CL-USER> (funcall '+ (values 1 10) (values 1 20))
2
CL-USER> (funcall 'list (values 1 10) (values 1 20))
(1 1)
CL-USER> (multiple-value-call '+ (values 1 10) (values 1 20))
32
CL-USER> (multiple-value-call 'list (values 1 10) (values 1 20))
(1 10 1 20)

The less-familiar parts of Lisp for beginners — muffle-warning

Continuing onward, we arrive at muffle-warning.  This might not seem like a particularly interesting or subtle function, but its behaviour is a bit different from what a newcomer from C++ might expect.

To begin with, you should probably review the articles on exception handling in Lisp.

While we haven’t discussed the warn function yet, we’ll go over it a bit here.  This function generates a Lisp condition (think exception).  Recall that Lisp conditions, if not caught, need not lead to termination.  If a condition is signaled with error, and there is no handler for it, the execution will enter the debugger.  If, instead, signal is used, then an uncaught condition causes execution to continue as if signal had not been invoked.  The warn function is similar to signal, but when it falls through unhandled, or returns from a restart, it prints a diagnostic text on the error stream.  That is, an unhandled warning doesn’t behave as if it had not been invoked at all, but instead produces some diagnostic in an implementation-defined manner.

So, what does muffle-warning do?  It is a function that can be invoked only inside a restart for a warning condition while such a condition is active.  The muffle-warning function suppresses the output from the warning before allowing execution to proceed after the warn invocation.  After the restart exits, execution continues after the warn, but with the normal error stream output suppressed for that one invocation.

The less-familiar parts of Lisp for beginners — method-qualifiers

Now we move to the method-qualifiers function.  This is another example of a function useful in the implementation of Lisp, specifically in the dispatching of methods.  It allows the programmer to distinguish between primary methods, :after methods, :before methods, and :around methods.  While there is likely to be a programmer who has a use for this, I cannot think of a situation where manually dispatching methods is necessary.  The Lisp generic function system, augmented by define-method-combination, seems suitable for any case I can imagine at the moment, so I believe you’re unlikely to find yourself needing to make use of method-qualifiers.