[pro] Modularity for subclassing in Common Lisp
Daniel Herring
dherring at tentpost.com
Thu Dec 2 02:29:08 UTC 2010
On Wed, 1 Dec 2010, Daniel Weinreb wrote:
> Smalltalk didn't even try. CLOS, I believe, does not try and there is
> not an idiomatic way to do it. The only language I know that makes a
> good stab in this direction is C++, which has "public", "protected",
> and "private". Whatever else you say about C++, Bjarne understood
> this issue and tried to fix it. The C++ solution isn't perfect
> but it's sure a lot better than anything else.
If you like public, private, and protected, then you really need to study
ADA a bit. CL isn't the only ~DARPA technology to have been abandoned
even though it contained good ideas. All the constraints look like they
could become tedious; but they seem to have good goals for defining
interfaces. [No, I haven't done anything real in ADA.]
Secret on the C++ implementation: these keywords are only enforced at
compile-time, and softly at best. On almost all compilers that matter,
you can change them in the header files, completely violate the intended
contract, and still link just fine with code compiled under the contract.
Java has a similar contractual model, but the JVM does try to enforce such
boundaries at runtime.
All that said, I've started to believe that the approach is fundamentally
wrong. There are always times when someone has to modify the "intrinsics"
of a library. This is often needed to fix bugs, extend functionality in
unanticipated directions, etc.
CL actually does have a decent way to do this, and a standard way to
detect violations. Like C++, put each class in its own namespace
(package). Only export symbols representing the public API. Everything
else is part of the implementation/protected API. Violations of the
public API the same way you find any other use of non-exported symbols.
Private is a good way of saying "are you really sure"; but the
implementation is a misfeature. I suspect scary naming (a la the
_underscore _prefix conventions commonly used in C/C++ and Python) are
quite sufficient.
Later,
Daniel
P.S. Other cute C++ tricks to get "private" data. These are strictly for
debug/experimentation. Any sane coder would shoot you on sight for
leaving them in a codebase.
- Protected data is easily accessed by creating a subclass and casting
other pointers into it.
- LD_PRELOAD can be used to define :around methods on non-inlined
functions, including methods. RTLD_NEXT can be helpful here.
- Calculate the offset of the value of interest, do a little pointer
arithmetic, and cast.
- Reimplement a public member function in the same compilation unit
(source file) as some code that needs to access private data. Simply copy
the definition from the original source file; but add in hooks that
expose private members (e.g. set globals pointing to them).
More information about the pro
mailing list