cross-package defgeneric/defmethod in Common Lisp?
Asked Answered
L

1

5

What is the right way to define a generic in package A and to provide a method for this generic in package B in CLOS?

Thank you in advance!

Example:

(defpackage :common (:use :cl))  
(in-package :common)  
(defgeneric compare (a b))

(defmethod compare ((a number) (b number))  
  (cond ((< a b) -1)
        ((= a b) 0)
        (T 1)))

(defpackage :a (:use :cl))  
(in-package :a)  

(defclass foo (a b))

(defmethod compare ((x foo) (y foo)) ...)   
; SBCL isn't able to access this method via the common package
Lawmaker answered 28/1, 2010 at 17:31 Comment(0)
Z
10

Methods and functions don't belong to packages. Symbols belong to packages.

(defpackage :common (:use :cl))  
(in-package :common)  
(defgeneric compare (a b))

(defmethod compare ((a number) (b number))  
  (cond ((< a b) -1) ((= a b) 0) (T 1)))

(defpackage :a (:use :cl))  
(in-package :a)  

(defclass foo (a b))

If A is the current package, then you need to write common::compare to access the non-exported symbol COMPARE of package COMMON.

(defmethod common::compare ((x foo) (y foo)) ...)   

If COMPARE has been exported from package COMMON, then you could write:

(defmethod common:compare ((x foo) (y foo)) ...)   

If COMPARE has been exported from package COMMON and package A would 'use' package COMMON, then you could write:

(defmethod compare ((x foo) (y foo)) ...)   
Zwick answered 28/1, 2010 at 17:40 Comment(2)
Thank you very much! Exactly what I've expected.Lawmaker
Yes, this is old but - you're a legend man! Here's an addition to the solution (mind the accessor vis:: syntax) (defclass test-node () ((visited :initform nil :accessor vis::visited) (children :initform nil :accessor children) (data :initarg :data :accessor data)))Spriggs

© 2022 - 2024 — McMap. All rights reserved.