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
"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)