覆盖/重载+运算符以对常见的lisp向量进行操作

Cod*_*lus 2 overriding operator-overloading common-lisp

我希望重载+运算符来处理常见的lisp向量 - 正如它对线性代数中的向量一样.是否有可能与+操作员一起超载?

这是我的预期定义:

 (defmethod + ((v1 vector) (v2 vector))
Run Code Online (Sandbox Code Playgroud)

在此先感谢您的帮助!

Vat*_*ine 5

如果我这样做,我会先从一个单独的包中开始.然后我会编写一个使用二元运算符的通用函数:

(defun + (&rest addends)
  (reduce #'binary+ (cdr addends) :initial-value (car addends)))

(defgeneric binary+ (addend1 addend2))
Run Code Online (Sandbox Code Playgroud)

然后你可以在泛型函数上定义方法binary+,允许你添加两个向量,一个向量和一个标量,...

这将是一个合适的包装器生成宏:

(defmacro define-operator (op &key (binary-signifier :binary) (package *package*)
  "Defines a generic operator OP, being essentially a reduce operation using
   a generic function composed of BINARY-SIGNIFIER and the operator."
  (let ((op op)
        (binary (intern (concatenate 'string
                                          (string  binary-signifier)
                                          (string op))
                        package)))
    `(progn
       (defun ,op (&rest args)
          (reduce (function ,binary) (cdr args) :initial-vale (car args)))
       (defgeneric ,binary (arg1 arg2)))))
Run Code Online (Sandbox Code Playgroud)

然后你可以根据Joshua Taylor的答案定义方法:

(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))
Run Code Online (Sandbox Code Playgroud)


Jos*_*lor 5

这是Vatine 答案的扩展,但有一些更多细节以使实现更清晰:

(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))
Run Code Online (Sandbox Code Playgroud)

(+ 1 1)
;=> 2

(+ #(1 2) #(0 -1))
;=> #(1 1)

(+ '(1 3) '(3 1))
;=> (4 4)
Run Code Online (Sandbox Code Playgroud)