I can't understand doc to save my life. Here is a simple problem.
While duking it out with C, at one point I wanted to migrate
incrementally a working Lispworks win32 app shell from LW's FLI to UFFI.
I wanted to go incrementally so I could see where it stopped working,
if anywhere.
So I had:
(defpackage cgl-window-manager
(:nicknames :cwm)
(:use CL CL-USER FLI UFFI)
(:export #:CREATE-TOPLEVEL-WINDOW #:CLOSE-WINDOW #:TEXTOUT
#:HDC #:cgl-window-init))
Well LW screamed like a stuck pig, because UFFI had a few names the same
as FLI. Now we're just talking about a few, so I could have typed up a
nice little defpackage option (shadow?) listing them if for the life of
me I could have figured out what to do.
Mind you it finally dawned on me that I could just use uffi and then
leave un-migrated code as was, since the author had used the fli: prefix
throughout. (doh!) but I am still curious as to how to resolve conflicts
when two packages overlap.
tia.
--
kenny tilton
clinisys, inc
http://www.tilton-technology.com/
---------------------------------------------------------------
"Cells let us walk, talk, think, make love and realize
the bath water is cold." -- Lorraine Lee Cudmore
Kenny Tilton <·······@nyc.rr.com> writes:
> I can't understand doc to save my life. Here is a simple problem.
>
> While duking it out with C, at one point I wanted to migrate
> incrementally a working Lispworks win32 app shell from LW's FLI to UFFI.
> I wanted to go incrementally so I could see where it stopped working,
> if anywhere.
>
> So I had:
>
> (defpackage cgl-window-manager
> (:nicknames :cwm)
> (:use CL CL-USER FLI UFFI)
> (:export #:CREATE-TOPLEVEL-WINDOW #:CLOSE-WINDOW #:TEXTOUT
> #:HDC #:cgl-window-init))
>
> Well LW screamed like a stuck pig, because UFFI had a few names the same
> as FLI. Now we're just talking about a few, so I could have typed up a
> nice little defpackage option (shadow?) listing them if for the life of
> me I could have figured out what to do.
>
> Mind you it finally dawned on me that I could just use uffi and then
> leave un-migrated code as was, since the author had used the fli: prefix
> throughout. (doh!) but I am still curious as to how to resolve conflicts
> when two packages overlap.
I'm not sure if you can do it automagically with DEFPACKAGE, but
here's how I do it:
foo-package.lisp:
(defpackage :foo (:export #:alpha #:beta))
bar-package.lisp:
(defpackage :bar (:export #:beta #:gamma))
baz-package.lisp:
(defpackage :baz
(:use :foo))
(in-package :baz)
;; for any symbols that overlap in FOO and BAR, use the symbol from BAR
(loop for sym being the external-symbols of :bar
collecting sym into symbols
finally (shadowing-import symbols))
(export '(alpha beta gamma))
At the repl after loading these files:
* 'baz:alpha
FOO:ALPHA
* 'baz:beta
BAR:BETA
* 'baz:gamma
BAR:GAMMA
--
/|_ .-----------------------.
,' .\ / | No to Imperialist war |
,--' _,' | Wage class war! |
/ / `-----------------------'
( -. |
| ) |
(`-. '--.)
`. )----'
Kenny Tilton <·······@nyc.rr.com> wrote:
+---------------
| (defpackage cgl-window-manager
| (:nicknames :cwm)
| (:use CL CL-USER FLI UFFI)
| (:export #:CREATE-TOPLEVEL-WINDOW #:CLOSE-WINDOW #:TEXTOUT
| #:HDC #:cgl-window-init))
|
| Well LW screamed like a stuck pig, because UFFI had a few names the same
| as FLI. Now we're just talking about a few, so I could have typed up a
| nice little defpackage option (shadow?) listing them if for the life of
| me I could have figured out what to do.
+---------------
Here's what I did (had to do) when using Tim Bradshaw's HTOUT macros
in CLISP:
(defpackage :cgi-user
(:use :cl :ext :htout :cgi :cgi-sql #+cmu :pg)
#+clisp ; conflicts with CLISP's inspector in "EXT"
(:shadowing-import-from :htout #:with-html-output))
From the CLHS page on DEFPACKAGE, note especially the marked[*] lines:
The order in which the options appear in a defpackage form is
irrelevant. The order in which they are executed is as follows:
1. :shadow and :shadowing-import-from.
2. :use.
3. :import-from and :intern.
4. :export.
[*]==> Shadows are established first, since they might be necessary to
[*]==> block spurious name conflicts when the :use option is processed.
The :use option is executed next so that :intern and :export
options can refer to normally inherited symbols. The :export
option is executed last so that it can refer to symbols created
by any of the other options; in particular, shadowing symbols
and imported symbols can be made external.
-Rob
-----
Rob Warnock, PP-ASEL-IA <····@rpw3.org>
627 26th Avenue <URL:http://rpw3.org/>
San Mateo, CA 94403 (650)572-2607
Kenny Tilton <·······@nyc.rr.com> writes:
> (defpackage cgl-window-manager
> (:nicknames :cwm)
> (:use CL CL-USER FLI UFFI)
>[..]
> Well LW screamed like a stuck pig, because UFFI had a few names the
> same as FLI. Now we're just talking about a few, so I could have typed
> up a nice little defpackage option (shadow?) listing them if for the
> life of me I could have figured out what to do.
Well, you don't have to :use a package to use it. You can access the
symbols using the package prefix.
I suppose you might be :use using some packages without conflicts,
and as packages evolve, you install a new version and get conflicts.
A this point it might be a lot of work to change from :use to package
prefixes.
It seems some caution is in order when deciding to :use a package. Is
it a stable package? Will its exported symbols change? To be on the
safe side you could use :import-from and only import the symbols you
actually use from the package.
//Lennart
* Kenny Tilton wrote:
> Well LW screamed like a stuck pig, because UFFI had a few names the
> same as FLI. Now we're just talking about a few, so I could have typed
> up a nice little defpackage option (shadow?) listing them if for the
> life of me I could have figured out what to do.
You can use my conduits system to deal with these kinds of issues
fairly elegantly. It lets you define packages which are `like' other
packages but don't, say, export all the same symbols. This is called
`extending', and you do it via, say:
(defpackage :foo/missing-some-symbols
(:use)
(:extends/excluding :foo #:sym1 #:sym2 ...))
This says: make a package "FOO/MISSING-SOME-SYMBOLS" which is just
like "FOO" except it does not export (or contain) FOO:SYM1 &c. There
are also :EXTENDS, and :EXTENDS/INCLUDING, as well azs some other
things. Conduit packages (packages which extend other packages) can
extend several packages, and I use them commonly for things like
defining a single interface package to a large system:
(defpackage :com.cley.weld.low
(:use)
(:extends
:com.cley.weld.low.sessions
:com.cley.weld.low.impdep
...))
There is some rudimentary documentation
(http://www.tfeb.org/lisp/hax.html#CONDUITS), and I said a while ago
that I would write something for the CL cookbook on packages, which I
really will try and do sometime and which will describe things like
conduits.
There is nothing magic about conduit packages - it's just a macro
which expands to CL:DEFPACKAGE having massaged its arguments. At
least Kent Pitman has a, probably better, version of the same thing.
--tim