Exporting the symbol foo:bar makes (foo:bar) and
(setf (foo:bar) new-value) available for a user of the package. What
are the good ways of not making the latter available?
I have thought of creating a separate package just for the purpose of
exporting, and creating a compiler-macro foo-interface:bar there. (This
makes it possible to use the same name and not to have to suffer from
either a call indirection (not guaranteed) or un-funcallability.) There
are other advantages of separate interface packages. Are there any
caveats? Is there something better? Is there a convention for
documenting the allowed uses of an exported symbol (e.g., method
dispatch on class is OK, instantiation isn't)?
Thanks,
Robert
Robert Monfera <·······@fisec.com> writes:
> Exporting the symbol foo:bar makes (foo:bar) and
> (setf (foo:bar) new-value) available for a user of the package. What
> are the good ways of not making the latter available?
Don't make FOO:BAR setf-able in any package you want to export.
That means not making it SETF-able at all, or else using an intermediate
package, as in:
(DEFPACKAGE "P1"
(:EXPORT "FOO"))
(IN-PACKAGE "P1")
(DEFUN FOO ...)
(DEFUN (SETF FOO) ...)
(DEFPACKAGE "P2"
(:EXPORT "FOO"))
(SETF #'FOO #'P1:FOO)
;or, depending on your taste:
;
; (DECLAIM (INLINE FOO))
; (DEFUN FOO (&REST ARGS) (P1:FOO ARGS))
> I have thought of creating a separate package just for the purpose of
> exporting, and creating a compiler-macro foo-interface:bar there. (This
> makes it possible to use the same name and not to have to suffer from
> either a call indirection (not guaranteed) or un-funcallability.) There
> are other advantages of separate interface packages. Are there any
> caveats?
Possible loss of compiler hints depending on how you do it. The SETF above
may lose some stuff. That's why the inline declaration or a compiler
macro might be better.
Also, exporting variables is harder.
(On the Lisp Machine, two variables in different packages can share a
value cell, but CL doesn't have that capability generally.)
But if you name them with *...* it
shouldn't be too bad, since you can probably import them straight through.
Most functions (and certainly most SETF's, partly as a consequence) don't
have names with *...* around them.
> Is there something better? Is there a convention for
> documenting the allowed uses of an exported symbol (e.g., method
> dispatch on class is OK, instantiation isn't)?
Not that I know of. Pity we didn't create abstract classes and a bunch of
other declarational verbiage that has arisen in some latter day systems
like Dylan and Java.
Kent M Pitman <······@world.std.com> writes:
> Robert Monfera <·······@fisec.com> writes:
>
> > Exporting the symbol foo:bar makes (foo:bar) and
> > (setf (foo:bar) new-value) available for a user of the package. What
> > are the good ways of not making the latter available?
>
> Don't make FOO:BAR setf-able in any package you want to export.
>
> That means not making it SETF-able at all, or else using an intermediate
> package, as in:
>
> (DEFPACKAGE "P1"
> (:EXPORT "FOO"))
>
> (IN-PACKAGE "P1")
>
> (DEFUN FOO ...)
> (DEFUN (SETF FOO) ...)
>
> (DEFPACKAGE "P2"
> (:EXPORT "FOO"))
>
> (SETF #'FOO #'P1:FOO)
This will not work in ACL 6.0 Trial, unless you manually produce an
ANSI image or you use the hacks posted here by Erik Naggum.
> > Is there something better? Is there a convention for
> > documenting the allowed uses of an exported symbol (e.g., method
> > dispatch on class is OK, instantiation isn't)?
>
> Not that I know of. Pity we didn't create abstract classes and a bunch of
> other declarational verbiage that has arisen in some latter day systems
> like Dylan and Java.
Back to the drawing table?
Cheers
--
Marco Antoniotti =============================================================
NYU Bioinformatics Group tel. +1 - 212 - 998 3488
719 Broadway 12th Floor fax +1 - 212 - 995 4122
New York, NY 10003, USA http://galt.mrl.nyu.edu/valis
Like DNA, such a language [Lisp] does not go out of style.
Paul Graham, ANSI Common Lisp