From: Sam Griffith Jr.
Subject: Operator overloading in CL
Date: 
Message-ID: <66o1tk$c63$1@gte2.gte.net>
Hello anyone,

Is there any way to overload operators in CL?  I want to create a '+'
msg. and a few others for some of the objects I have.  Please reply to
email as well if you can.

Thanks ahead of time,

Sam Griffith Jr.
·········@aol.com
········@gte.net

From: Kent M Pitman
Subject: Re: Operator overloading in CL
Date: 
Message-ID: <sfw1zzknyjb.fsf@world.std.com>
"Sam Griffith Jr." <········@gte.net> writes:

> Hello anyone,
> 
> Is there any way to overload operators in CL?  I want to create a '+'
> msg. and a few others for some of the objects I have.  Please reply to
> email as well if you can.
> 
> Thanks ahead of time,
> 
> Sam Griffith Jr.
> ·········@aol.com
> ········@gte.net

There is a distinction between making '+' generic and overloading.

In overloading, there is no requirement of using the same protocol.
For example, the arguments for the "open" that opens a window might
not be those for the "open" that opens a file, but one might want to
use the word "open" in both cases.  That's overloading.  In making
something generic, you describe a single abstract operation and the
data it requires, and then various objects implement that control/data
request by methods.

Lisp implements generic functions but not overloading per se.
See DEFGENERIC and DEFMETHOD in the Common Lisp HyperSpec(TM)
at http://www.harlequin.com/education/books/HyperSpec/

However, the spec says you can't redefine system functions like '+'.
To get around this, of course, you can make a new package (see
DEFPACKAGE in CLHS) in which the symbol named "+" is shadowed and
then you can use "+" the new package.

Probably you'd do something like:

 (DEFPACKAGE MATH-STUFF
   (:USE)
   (:EXPORT "+" "-" "/" "*"))

 (DEFMETHOD MATH-STUFF:+ (X Y) (+ X Y))
 (DEFMETHOD MATH-STUFF:- (X &OPTIONAL Y)
   (IF Y (- X Y) (- X)))
 ...etc.

 (DEFPACKAGE MATH-USER
   (:USE COMMON-LISP MATH-STUFF)
   (:SHADOWING-IMPORT-FROM "MATH-STUFF" "+" "-" "/" "*"))

Hmmm. This may be a little more vague than you need, but maybe someone
else can help with more ideas...
From: Peter Schotman
Subject: Re: Operator overloading in CL
Date: 
Message-ID: <348FA529.7D07E72B@tip.nl>
Kent M Pitman wrote:

> "Sam Griffith Jr." <········@gte.net> writes:
>
> > Hello anyone,
> >
> > Is there any way to overload operators in CL?  I want to create a
> '+'
> > msg. and a few others for some of the objects I have.  Please reply
> to
> > email as well if you can.
> >Probably you'd do something like:
>
>  (DEFPACKAGE MATH-STUFF
>    (:USE)
>    (:EXPORT "+" "-" "/" "*"))
> snip...
>
>  (DEFPACKAGE MATH-USER
>    (:USE COMMON-LISP MATH-STUFF)
>    (:SHADOWING-IMPORT-FROM "MATH-STUFF" "+" "-" "/" "*"))
>
> Hmmm. This may be a little more vague than you need, but maybe someone
>
> else can help with more ideas...

Below an example of what you might want (combine with the package
instructions of above).Mind you, the following can be quite inefficient!
I wouldn't mind having someone suggest
how to improve its efficiency though :-)


(in-package :math-stuff)

;;; standard function
(defun + (arg1 arg2 &rest arg3)
   (adding arg1 arg2 arg3))

(defgeneric adding (arg1 arg2 other-numbers)
  (:documentation "Adding different types of arguments."))
(defmethod adding (arg1 arg2  other-numbers)
  (declare (ignore arg1 arg2 other-numbers))
  (error "Arguments given to ADD are not applicable."))

(defmethod adding ((arg1 number) (arg2 number) other-numbers)
   (if (null other-numbers)
      (cl:+ arg1 arg2)
      (adding (cl:+ arg1 arg2) (pop other-numbers) other-numbers)))

;;; here I use a list to perform interval computation in my case a list
always looks like '(a b) where a and b are numbers
(defmethod adding ((arg1 list) (arg2 number) other-numbers)
   (if (not (= (length arg1) 2))
      (error "lijst argument 1 aan add heeft geen lengte 2.")
      (if (null other-numbers)
         (list (cl:+ (first arg1) arg2)(cl:+ (second arg1) arg2))
         (adding (list (cl:+ (first arg1) arg2) (cl:+ (second arg1)
arg2)) (pop other-numbers) other-numbers))))

(defmethod adding ((arg1 number) (arg2 list) other-numbers)
   (if (not (= (length arg2) 2))
      (error "lijst argument 2 aan add heeft geen lengte 2.")
      (if (null other-numbers)
         (list (cl:+ (first arg2) arg1)(cl:+ (second arg2) arg1))
         (adding (list (cl:+ (first arg2) arg1) (cl:+ (second arg2)
arg1)) (pop other-numbers) other-numbers))))

(defmethod adding ((arg1 list) (arg2 list) other-numbers)
   (if (and (not (= (length arg1) 2)) (not (= (length arg2) 2)))
      (error "lijst argumenten aan (add <list> <list>) hebben geen
lengte 2.")
      (if (null other-numbers)
         (list (cl:+ (first arg1) (first arg2)) (cl:+ (second arg1)
(second arg2)))
         (adding (list (cl:+ (first arg1) (first arg2)) (cl:+ (second
arg1) (second arg2)))
            (pop other-numbers) other-numbers))))

;;; continue for other math operations (devision is more complicated see
for instance: "Global optimization
;;; using interval analysis", Hansen, 1992)