<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><br class=""><div><br class=""><blockquote type="cite" class=""><div class="">On 22 Aug 2018, at 00:36, Daniel Pezely <<a href="mailto:daniel@pezely.com" class="">daniel@pezely.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class="">
  

    <meta http-equiv="content-type" content="text/html; charset=utf-8" class="">
  
  <div text="#000000" bgcolor="#FFFFFF" class=""><p class="">I posted this to Stack Overflow but was hoping for more input.<br class="">
    </p><p class=""><a class="moz-txt-link-freetext" href="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</a></p><p class=""><br class="">
    </p>
    <div class="post-text" itemprop="text"><p class="">May I get recommendations or links to representative code
        repositories with good style for multiple related Common Lisp
        packages, please?</p><p class="">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.</p><p class="">Each system (<code class="">*.asd</code> file) isolates tests and may be
        invoked using:</p><p class=""><code class="">(asdf:test-system foo :force t)</code></p><p class="">Separate systems may be built via <code class="">make</code>, which
        definitely helps isolate SBCL code-coverage reports.</p><p class="">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.</p><p class="">I currently have a single directory tree with a subdirectory
        for each CL package. There's a top-level <code class="">Makefile</code>
        plus one in each subdirectory that the library maintain would
        use. The top-level also contains symbolic links for <code class="">.asd</code>
        files pointing into relevant subdirectories. (It's a library
        deeply dependent upon POSIX calls via <code class="">uiop-posix</code>,
        so it's only applicable on an OS with sym-links.)</p><p class="">This seems to be an issue at large considering issue #1 for
        Quicklisp-docs [0].</p><p class="">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.</p>
      <ul class="">
        <li class="">[0] <a href="https://github.com/rudolfochrist/quicklisp-docs/issues/1" rel="nofollow noreferrer" class="">https://github.com/rudolfochrist/quicklisp-docs/issues/1</a></li>
        <li class="">[1] <a href="https://google.github.io/styleguide/lispguide.xml" rel="nofollow noreferrer" class="">https://google.github.io/styleguide/lispguide.xml</a></li>
        <li class="">[2] <a href="https://web.archive.org/web/20160305061250/http://eudoxia.me/article/common-lisp-sotu-2015/" rel="nofollow noreferrer" class="">https://web.archive.org/web/20160305061250/http://eudoxia.me/article/common-lisp-sotu-2015/</a></li>
        <li class="">[3] <a href="http://weitz.de/cl-recipes/" rel="nofollow
            noreferrer" class="">http://weitz.de/cl-recipes/</a></li>
        <li class="">[4] <a href="http://lisp-lang.org/learn/writing-libraries" rel="nofollow noreferrer" class="">http://lisp-lang.org/learn/writing-libraries</a>
          but see also their section on Continuous Integration</li>
      </ul><p class="">Repo to be fixed: <a href="https://gitlab.com/dpezely/cl-mmap" rel="nofollow noreferrer" class="">https://gitlab.com/dpezely/cl-mmap</a><br class="">
        (commit a23bd88d of 2018-07-14; release will be tagged when
        fixed)</p><p class="">Thanks,<br class="">
          -Daniel</p></div></div></div></blockquote></div><div class=""><br class=""></div>You’re asking about different things.<div class=""><br class=""></div><div class="">- 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. <a href="http://github.com/informatimago/lisp" class="">http://github.com/informatimago/lisp</a></div><div class=""><br class=""></div><div class="">- 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.</div><div class="">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.</div><div class=""><br class=""></div><div class="">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.</div><div class=""><br class=""></div><div class="">- 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.</div><div class="">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.</div><div class=""><br class=""></div><div class="">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!</div><div class=""><br class=""></div><div class="">In short: it depends!</div><div class=""><br class=""><div class="">
<div style="color: rgb(0, 0, 0); letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><div style="color: rgb(0, 0, 0); letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><div style="color: rgb(0, 0, 0); letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class="">-- <br class="">__Pascal J. Bourguignon__</div><div style="color: rgb(0, 0, 0); letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><br class=""><br class=""><br class=""></div></div></div>
</div>
<br class=""></div></body></html>