[Gardeners] Monthly progress report: Lisp FAQ

Nikodemus Siivola nikodemus at random-state.net
Thu Jun 1 17:05:11 CDT 2006


Jeremy Smith <jeremy at xanadu.net> writes:

>>    What about overloading operators like #'+?
>>    Maybe also some reference to generic functions?
>
> Personally, I'd use optional parameters for this. Here's a piece of
> (probably awful) Lisp code to demonstrate:
>
> (defun my+(num1 num2 &optional (num3 0))
> 	(+ num1 num2 num3))

Ikes, no! This is how it is done:

;;; Step 1: shadow
(defpackage "MY+" (:use :cl) (:shadow "+"))

(in-package :my+)

;;; Step 2: define a variant with fixed number of arguments
(defgeneric +/2 (a b))

(defvar *swap* nil)

;;; Step 3: default method delegates to CL:+, and deals with alternative
;;; order or arguments, so that specializing on the first argument will
;;; be enough
(defmethod +/2 (a b)
  (if *swap*
      (cl:+ a b)
      (let ((*swap* t))
        (+/2 b a))))

;;; Step 4: oddball perlish method to show-off
(defmethod +/2 ((string string) x)
  (+/2 (read-from-string string) x))

;;; Step 5: delegate from + to +/2
(defun + (&rest arguments)
  (reduce #'+/2 arguments :initial-value 0))

;;; Done
(+ "1" 1 "1") ; => 4

Cheers,

  -- Nikodemus              Schemer: "Buddha is small, clean, and serious."
                   Lispnik: "Buddha is big, has hairy armpits, and laughs."



More information about the Gardeners mailing list