: Alessio Stalla <alessiostalla@gmail.com> : Jean-Claude Beaudoin <jean.claude.beaudoin@gmail.com>
The stance on packages found in the mentioned Quora post is based on the old misconception about packages being modules, or "software packages" in the Linux distribution sense. They're not. They are really just namespaces, containers of symbols. So it does not make any sense, to me, that they have versions. Software has versions, not names.
Excellently summarized.
Well, "packages" seem to me to be the only system structuring device offered by the CL spec. So you have to work from there toward something more appropriate, I'd say. In a somewhat upward compatible manner I'd hope.
When your only hammer is CL packages, expect a lot of hurt fingers. You may also be confusing many different issues: Q1: What are the current best practices when programming in CL on top of the existing package infrastructure? A1: Avoid sharing packages between several sytems. Use one or multiple packages per system, maybe even one or more packages per file, but to avoid modifying other systems' packages, except through well-defined APIs. But in practice such APIs do exist, or are defined post-hoc, and the build system mostly doesn't and cannot know about them. Q2: How do I replace packages with something better, and implement it on top of CL? A2: Look at what languages with advanced module systems are doing, e.g. Racket. But don't expect interoperation between such code and regular CL code to be seamless; your new language can easily FFI into CL, but you'll need tricks akin to extern "C" { ... } to specify entry points for CL code to call into your extended language. But is vanilla CL the correct starting point to develop such a new language? Q3: How do I replace packages with something better, and implement CL on top of that? A3: As with A2, look at a clueful language such as Racket; and again, interoperation will not be seamless. And then if what you implement is bug-compatible with packages and the rest of CL, you'll be able to run CL code on top of your language. But is that what you want? In all these cases, the idea of loading multiple versions of a package unmodified in a same image makes no sense whatsoever. Just not possible as a general mechanism. Sure, by manually editing the code, you can fork a system and rename some packages. Do it, if that's what you need to do. That is NOT AT ALL the same thing as "loading multiple versions of a package in a same image". Now if you have a virtualized implementation of CL (e.g. use multiple CL processes), then yes, it's trivial to have these many images each load its own package. Do it, too, if that's what you need.
I think it *is* already possible, even if no convenient machinery for it exists, to load the same symbols under different packages (i.e. to use different names for different versions of the same concepts).
(defpackage p ...) (load (compile-file "p-1.0.lisp")) (rename-package "P" "P-1.0") (defpackage p ...) (load (compile-file "p-1.1.lisp")) (rename-package "P" "P" "P-1.1")
p-*.lisp start with (in-package :p)
Then you can compile code against p (latest version), p-1.0 and/or p-1.1. Of course each p-*.lisp must be "nice" - only define things in package p.
This is an interesting line of argument you've got here...
If the p-*.lisp are _actually_ nice, you don't need any such brain damage. So keep your code nice, so that no one needs to such stupid evil things doomed to fail. —♯ƒ • François-René ÐVB Rideau •Reflection&Cybernethics• http://fare.tunes.org Foolishness is rarely a matter of lack of intelligence or even lack of information. — John McCarthy