I wish to overload the + operator to work on common lisp vectors -- just as it would for vectors in linear algebra. Is it possible to overload with the +
operator?
Here is my intended definition:
(defmethod + ((v1 vector) (v2 vector))
Thanks in advance for all the help!
If I were to do this, I would start by doing it in a separate package. I would then write a general function that uses binary operators:
(defun + (&rest addends)
(reduce #'binary+ (cdr addends) :initial-value (car addends)))
(defgeneric binary+ (addend1 addend2))
Then you can define methods on the generic function binary+
that would allow you to add two vectors, a vector and a scalar, ...
Something that would be a suitable wrapper-generating macro:
(defmacro define-operator (op &key (binary-signifier :binary) (package *package*)
"Defines a generic operator OP, being essentially a reduce operation using
a generic function whose name is a concatenation of BINARY-SIGNIFIER and OP."
(let ((op op)
(binary (intern (concatenate 'string
(string binary-signifier)
(string op))
package)))
`(progn
(defun ,op (&rest args)
(reduce (function ,binary) (cdr args) :initial-value (car args)))
(defgeneric ,binary (arg1 arg2)))))
Then you can define methods, as per Joshua Taylor's answer:
(defmethod binary+ ((x number) (y number))
(cl:+ x y))
(defmethod binary+ ((x vector) (y vector))
(map 'vector 'cl:+ x y))
(defmethod binary+ ((x list) (y list))
(map 'list 'cl:+ x y))
This is an extension of Vatine's answer, but with some more detail to make the implementaiton clearer:
(defpackage #:generic-arithmetic
(:use "COMMON-LISP")
(:shadow "+"))
(in-package #:generic-arithmetic)
(defun + (&rest addends)
(reduce 'binary+ (cdr addends) :initial-value (car addends)))
(defgeneric binary+ (addend1 addend2))
(defmethod binary+ ((x number) (y number))
(cl:+ x y))
(defmethod binary+ ((x vector) (y vector))
(map 'vector 'cl:+ x y))
(defmethod binary+ ((x list) (y list))
(map 'list 'cl:+ x y))
(+ 1 1)
;=> 2
(+ #(1 2) #(0 -1))
;=> #(1 1)
(+ '(1 3) '(3 1))
;=> (4 4)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With