From: Onay
Subject: package question
Date: 
Message-ID: <42869970$0$25689$9b4e6d93@newsread2.arcor-online.net>
(defpackage original-p1
  (:use common-lisp)
  (:export gen))
  
(in-package original-p1)
;; define first ability
(defmethod gen ((x number))
   (format t "gen[number]: ~a~%" x))

;; my original-p1 package contains the original lib
(defpackage p2
  (:use common-lisp)
  (:export gen))
  
(in-package p2)
;; define second ability
(defmethod gen ((x string))
   (format t "gen[string]: ~a~%" x))

(defpackage client
   (:use common-lisp original-p1 p2))
(in-package client)

(gen 1)

gives me an error complaining name collision ("gen"). Is it somehow possible
to write autonomous libraries in different packages which
implement !different! versions of gen without knowing from each other?
I mean i would like to be able to write a generic lib and add additional
abilities to my lib WITHOUT having to change the source code of the
original lib? 
Need merging the 'function table' of gen from different packages in the
client package...
-- 
(+::+) oni (+::+)
(I already try to be as amusing as possible, my master!)

From: Barry Margolin
Subject: Re: package question
Date: 
Message-ID: <barmar-8AEF55.22420614052005@comcast.dca.giganews.com>
In article <·························@newsread2.arcor-online.net>,
 Onay  <·····@gmx.net> wrote:

> (defpackage original-p1
>   (:use common-lisp)
>   (:export gen))
>   
> (in-package original-p1)
> ;; define first ability
> (defmethod gen ((x number))
>    (format t "gen[number]: ~a~%" x))
> 
> ;; my original-p1 package contains the original lib
> (defpackage p2
>   (:use common-lisp)
>   (:export gen))
>   
> (in-package p2)
> ;; define second ability
> (defmethod gen ((x string))
>    (format t "gen[string]: ~a~%" x))
> 
> (defpackage client
>    (:use common-lisp original-p1 p2))
> (in-package client)
> 
> (gen 1)
> 
> gives me an error complaining name collision ("gen"). Is it somehow possible
> to write autonomous libraries in different packages which
> implement !different! versions of gen without knowing from each other?
> I mean i would like to be able to write a generic lib and add additional
> abilities to my lib WITHOUT having to change the source code of the
> original lib? 
> Need merging the 'function table' of gen from different packages in the
> client package...

But if they don't know about each other, they could just as easily 
conflict with each other.  What if both packages have a GEN function 
that's specialized on NUMBER?  Which one should be used?

Anyway, the thing you have to remember about packages is that they deal 
with symbols, not functions and variables.  The symbols ORIGINAL-P1:GEN 
and P2:GEN are different symbols, and CLIENT can only import one or the 
other.

If two packages export symbols with the same name, client packages 
either have to avoid using both, or make use of SHADOWING-IMPORT to 
select which one they want to get.  You can still refer to the other one 
using an explicit package prefix.

-- 
Barry Margolin, ······@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
From: Wade Humeniuk
Subject: Re: package question
Date: 
Message-ID: <vexhe.65764$tg1.64301@edtnps84>
Onay wrote:
> (defpackage original-p1
>   (:use common-lisp)
>   (:export gen))
>   
> (in-package original-p1)
> ;; define first ability
> (defmethod gen ((x number))
>    (format t "gen[number]: ~a~%" x))
> 
> ;; my original-p1 package contains the original lib
> (defpackage p2
>   (:use common-lisp)
>   (:export gen))
>   
> (in-package p2)
> ;; define second ability
> (defmethod gen ((x string))
>    (format t "gen[string]: ~a~%" x))
> 
> (defpackage client
>    (:use common-lisp original-p1 p2))
> (in-package client)
> 
> (gen 1)

Do this---

P2 7 > (defpackage client
    (:use common-lisp original-p1 p2)
    (:shadow gen))
#<PACKAGE CLIENT>

P2 8 > (in-package client)
#<PACKAGE CLIENT>

CLIENT 9 > (gen 1)

Error: Undefined function GEN called with arguments (1).
   1 (continue) Try invoking GEN again.
   2 Return some values from the call to GEN.
   3 Try invoking something other than GEN with the same arguments.
   4 Set the symbol-function of GEN to another function.
   5 (abort) Return to level 0.
   6 Return to top loop level 0.

Type :b for backtrace, :c <option number> to proceed,  or :? for other options

CLIENT 10 : 1 > :a

CLIENT 11 > (p2:gen "hello")
gen[string]: hello
NIL

CLIENT 12 > (original-p1:gen 100)
gen[number]: 100
NIL

CLIENT 13 >
From: Sam Steingold
Subject: Re: package question
Date: 
Message-ID: <uu0l4wr5t.fsf@gnu.org>
> * Onay <·····@tzk.arg> [2005-05-15 02:36:00 +0200]:
>
> (defpackage original-p1
>   (:use common-lisp)
>   (:export gen))

you now created 2 symbols: original-p1:gen as you requested and
cl-user::gen because the form was read in package cl-user.
I suggest that you replace the last line with

  (:export #:gen))

> (in-package original-p1)
> ;; define first ability
> (defmethod gen ((x number))
>    (format t "gen[number]: ~a~%" x))

where is (defgeneric gen) ?

> ;; my original-p1 package contains the original lib
> (defpackage p2
>   (:use common-lisp)
>   (:export gen))

same as above - two symbols are created.
note that if this p2:gen is supposed to be the same as original-p1:gen,
you need to write

(defpackage p2
  (:use common-lisp)
  (:import-from #:original-p1 #:gen)
  (:export #:gen))

now you have just original-p1:gen which is exported from both p2 and
original-p1.

> (defpackage client
>    (:use common-lisp original-p1 p2))

now this is overkill: (:use #:common-lisp #:original-p1) is enough.

> gives me an error complaining name collision ("gen").

of course: you tried to use original-p1, which made original-p1:gen
available and p2, which made p2:gen available.
so, when you write gen now, what symbol do you mean original-p1:gen or
p2:gen?

the symbols must be the same (as accomplished above using :import-from),
but the methods may be different.

> Is it somehow possible to write autonomous libraries in different
> packages which implement !different! versions of gen without knowing
> from each other?

different versions of _function_ - yes.
but your new packages must import the _function names_, as above.


-- 
Sam Steingold (http://www.podval.org/~sds) running w2k
<http://www.openvotingconsortium.org/> <http://www.jihadwatch.org/>
<http://www.iris.org.il> <http://www.palestinefacts.org/>
A man paints with his brains and not with his hands.
From: ·······@gmail.com
Subject: Re: package question
Date: 
Message-ID: <1116353863.479468.10340@g14g2000cwa.googlegroups.com>
Try using :shadowing-import-from like this.

1. set up a base package with the (defgeneric) form.
2. make two (or more) packages that inherit from the base package. each
can use (defmethod) to add methods to the generic function.
3. all packages export the symbol, and because of the shadowing, you
can use the symbol from any package and it will work the same way. the
methods from the packages you've loaded will be available.

Here's an example:

(defpackage :p (:use common-lisp) (:export gen-func-1))
(in-package :p)
(defgeneric gen-func-1 (x))

(defpackage :p1
   (:use common-lisp p)
   (:shadowing-import-from :p gen-func-1)
   (:export gen-func-1))
(in-package :p1)
(defmethod gen-func-1 ((x number))
  (+ x 1))

(defpackage :p2
   (:use common-lisp p)
   (:shadowing-import-from :p gen-func-1)
   (:export gen-func-1))
(in-package :p2)
(defmethod gen-func-1 ((x string))
  (concatenate 'string x "!"))

(in-package :cl-user)


Now you can call any of these and they will work:

(p:gen-func-1 5) => 6
(p:gen-func-1 "hello") => "hello!"

(p1:gen-func-1 5) => 6
(p1:gen-func-1 "hello") => "hello!"

(p2:gen-func-1 5) => 6
(p2:gen-func-1 "hello") => "hello!"

If only :p is loaded, no methods will be available. If only :p1 or :p2
is loaded, then only the method from that package will be available.

Harold

harold at hotelling dot net