[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