> On 22 Aug 2018, at 00:36, Daniel Pezely <dan...@pezely.com> wrote:
> 
> I posted this to Stack Overflow but was hoping for more input.
> https://stackoverflow.com/questions/51638864/common-lisp-style-multiple-packages-in-same-repo
>  
> <https://stackoverflow.com/questions/51638864/common-lisp-style-multiple-packages-in-same-repo>
> 
> May I get recommendations or links to representative code repositories with 
> good style for multiple related Common Lisp packages, please?
> 
> For instance, consider a high-level workflow library with accompanying 
> lower-level API, each in its own CL package but same git repo due to 
> synchronized releases.
> 
> Each system (*.asd file) isolates tests and may be invoked using:
> 
> (asdf:test-system foo :force t)
> 
> Separate systems may be built via make, which definitely helps isolate SBCL 
> code-coverage reports.
> 
> Some users of the library may only want to load the lower-level API. For 
> simplifying dependencies for those using higher-level API, it seems best to 
> keep everything bundled in one repo. Any revision to one library would likely 
> require updating all for the same release.
> 
> I currently have a single directory tree with a subdirectory for each CL 
> package. There's a top-level Makefile plus one in each subdirectory that the 
> library maintain would use. The top-level also contains symbolic links for 
> .asd files pointing into relevant subdirectories. (It's a library deeply 
> dependent upon POSIX calls via uiop-posix, so it's only applicable on an OS 
> with sym-links.)
> 
> This seems to be an issue at large considering issue #1 for Quicklisp-docs 
> [0].
> 
> Found nothing relevant in Google's CL style guide [1], State of the Common 
> Lisp Ecosystem, 2015 [2], Edi's CL Recipes [3] or Lisp-lang [4]. Browsing 
> repos seem to have quite a mix of styles.
> 
> [0] https://github.com/rudolfochrist/quicklisp-docs/issues/1 
> <https://github.com/rudolfochrist/quicklisp-docs/issues/1>
> [1] https://google.github.io/styleguide/lispguide.xml 
> <https://google.github.io/styleguide/lispguide.xml>
> [2] 
> https://web.archive.org/web/20160305061250/http://eudoxia.me/article/common-lisp-sotu-2015/
>  
> <https://web.archive.org/web/20160305061250/http://eudoxia.me/article/common-lisp-sotu-2015/>
> [3] http://weitz.de/cl-recipes/ <http://weitz.de/cl-recipes/>
> [4] http://lisp-lang.org/learn/writing-libraries 
> <http://lisp-lang.org/learn/writing-libraries> but see also their section on 
> Continuous Integration
> Repo to be fixed: https://gitlab.com/dpezely/cl-mmap 
> <https://gitlab.com/dpezely/cl-mmap>
> (commit a23bd88d of 2018-07-14; release will be tagged when fixed)
> 
> Thanks,
>   -Daniel
> 


You’re asking about different things.

- git repositories. It’s more a question of ownership and administration than 
anything else.  Technically, as you noted, it is better to keep in the same 
repository things that will evolve in sync. eg. client & server module 
implementing the same protocol.  But if for some reason those two modules had 
to be developed by different teams, it would still be preferable to have two 
separate repositories, and synchronize thru the protocol specification, and not 
thru the code.  Otherwise, as a small team of 1 I tend to prefer big git 
repositories holding everything eg. http://github.com/informatimago/lisp

- asdf systems are entirely orthogonal and agnostic to packages.  It will let 
you do as you wish. Whether what you do is good or not will depend on the use 
case.
It may be the less surprising option to map 1 package to 1 system, and to avoid 
defining (or overriding/redefining) things in other packages.  But it may be 
needed, useful or easier to ignore this rule.

For example, you can define a package X loaded with a system X. Then a package 
X.TEST loaded with a system X.TEST.  But in order to test some internal feature 
of X, you may have to define or redefine things in the package X, from the code 
loaded by the system X.TEST; or you may want to avoid the package X.TEST 
altogether, and just load tests in the package X, from the system named X.TEST! 
 All the other use cases are possible, and might be justified by a given 
situation.

- files. Mapping lisp definitions (and other top-level forms) to files is 
rather arbitrary.   The only technical constraint is that the definitions that 
are used by macros (at macroexpansion-time ∈ compilation-time), must be 
compiled before, and loaded into the compilation environment before those 
macros can be used (and even, better before they’re defined). This can be done 
by wrapping those definitions in an eval-when form, but it’s often easier to 
put them in a separate file, to be compiled and loaded before the file defining 
the macro and the files using it.  For the rest, do as you wish.  I try to 
follow the logic of the program, or the “explanatory order” (think about the 
human reader).  But it doesn’t matter at all.  Instead of worrying about that, 
you’d better spend your time writing an emacs mode that would store lisp forms 
into files automatically.  You’d just have a browser (like a smalltalk 
browser), and add definitions, or browse and select definitions to be edited. 
emacs would fetch them from the file IT had decided where to store them, and 
would present them in an ephemeral buffer for your edit.  Of course, instead of 
text-based commands such as search and replace, you’d have symbolic editing 
commands such as rename-symbol-in-definition or rename-symbol-everywhere or 
substitute-sexp-everywhere etc.  This includes directories.
That said, nothing prevents you to define some conventions for your current 
project. See again the above github repo for an example. I’m not saying you 
should follow it, it’s just a random example that suits me for this case, an 
aggregation of libraries. For application programs, I’d use a totally different 
way to structure code in packages, and spread code in files and directories, 
and how to load it with what systems.

Basically, what I’m saying is that it’s a software engineering question and it 
must be answered based on software engineering design and decisions.  In UML 
you have the concepts of module and components, and with stereotypes, different 
kinds of components, you can represent packages, asdf system and components, 
and even if you want to modelize it, asdf files, since asdf uses files as unit 
of compilation and loading.  How you structure your software cannot be 
PRE-designed! You have to do the work yourself, as a software engineer!

In short: it depends!

-- 
__Pascal J. Bourguignon__




Reply via email to