1. 3

    Realforce 104U. The variable-weighting has ruined me – trying to use a normal keyboard now means either the main keys are too light or the pinky keys are too heavy.

    1. 1

      Related to anaphoric macros.

      I like the improved style vs. Graham’s implicit bindings, but for whatever reason binding conditionals in Lisp never gained traction. Perhaps they are just harder to read.

      1. 1

        These are(were?) super common in Clojure, fwiw. I can’t fathom a reason they ‘d be popular in Clojure, but not in Common Lisp, other than one having a Lisp-1 and a community that hates typing more characters than necessary…but in that case, the implied ‘it Would be better….

        1. 1

          I can’t fathom a reason they ‘d be popular in Clojure, but not in Common Lisp

          They’re included in the Clojure standard library, but you have to write them yourself in CL (or use a library). That’s probably why.

          1. 1

            Right. The barrier to entry is far less in Clojure, but the idea of binding conditionals was not new in Clojure. So there was lots of opportunity for CL users to adopt it, and for it to end up in SBCL’s standard library, or be a quicklisp library away. That seems to have not happened.

      1. 1

        How hard would it be to make these without the Alexandria dependency? (I’d try it myself but just don’t have the time and energy currently.)

        1. 1

          with-gensyms is trivial to replace. parse-body would be tougher, but still isn’t too bad.

        1. 1

          Most of this went over my head (I’m not a lisp person), but I want to say I love your “give code a grey background” CSS. Mind if I steal it?

          1. 3

            Feel free. I did it like that because it clearly shows where the actual snippets of code begin and end, including leading/trailing punctuation/whitespace.

            1. 1

              I do a a similar thing only the left border uses the colors that Github uses to mark languages.

            1. 15

              Always good to see more folks getting into Common Lisp!

              As far as I can tell, new Quicklisp projects have to be located inside ${HOME}/quicklisp/local-projects. I am not particularly happy with it, but it is not really important.

              If you want to put your projects elsewhere on your disk, you can put symlinks into local-projects that point to them. I even have a llp shell alias (“Link in Local Projects”) to run something like ln -s "$(pwd)" "$HOME/.quicklisp/local-projects" to make it easy to add the symlink (note that I keep quicklisp in ~/.quicklisp so it doesn’t clutter the file listing), since I do it so often.

              I had already installed clisp, and it took me quite some times to understand my mistake.

              I will always be annoyed at clisp for choosing such a confusing name.

              Quicklisp packages (systems?) are defined through asd files.

              Common Lisp’s terminology is confusing because it’s old and uses a lot of words that we use now (like “package”) to mean different things than people mean today. Things get easier once you internalize what Common Lisp means by the terms.

              A package in Common Lisp is a container for symbols. They’re a way to group related names (symbols) together so you don’t have to do the miserable prefixing of every name with mylibrary-... like you do in Emacs Lisp or C to avoid name clashes.

              Unlike other languages like Python/Clojure/etc, packages and files on the hard disk are not tied strongly together in Common Lisp. You can have several files that all work with the same package, a single file that switches back and forth between packages, or even write code that creates/mutates packages at runtime. Files and packages are orthogonal in Common Lisp, which gives you maximum flexibility to work however you want.

              A system in Common Lisp is a collection of code (mostly) and a description of how to load that code (and some metadata like author, license, version, etc). For example: my directed graph library cl-digraph contains a system called cl-digraph. That system has a description of how to load the code, and that description lives in the cl-digraph.asd file. It creates a Common Lisp package (called digraph).

              The Common Lisp language itself has no knowledge of systems. ASDF is a Common Lisp library bundled with most (all?) modern implementations that handles defining/loading systems. (The name stands for Another System Definition Facility, so as you might guess there have been several other such libraries. ASDF is the one everyone uses today.)

              Systems and packages are orthogonal in Common Lisp. Some systems (like small libraries) will define exactly one package. Some systems will define multiple packages. Rarely a system might not define any new packages, but will use or add to an existing one.

              A project in Common Lisp is not an official term defined anywhere that I know of, but is generally used to mean something like a library, a framework, an application, etc. It will usually define at least one system, because systems are where you define how to load the code, and if it didn’t define a system how would you know how to load the code? My cl-digraph library mentioned above is a project that defines three systems:

              • cl-digraph which contains the actual data structure and interface.
              • cl-digraph.test which contains the unit tests. This is a separate system because it lets users load the main code without also having to load the unit test framework if they’re not going to be running the tests.
              • cl-digraph.dot which contains code for drawing the directed graphs with Graphviz. This is a separate system because it lets users load the main code without also having to load the cl-dot system (the graphviz bindings) if they don’t care about drawing.

              If I were writing this today I’d use ASDF’s foo/bar system naming notation instead of separating the names with a dot, because there’s some nice extra support for that. I just didn’t know about it at the time, and don’t want to break backwards compatibility now.

              We saw how Common Lisp has no concept of a system — that comes from ASDF. Similarly, ASDF has no concept of the internet, or reaching out to somewhere to download things. It assumes you have somehow acquired the systems you want to load, maybe by sending a check to an address and receiving a copy of the code on floppy disk, as many of my old Lisp books offer in the back pages.

              Quicklisp is another library that works on top of ASDF to provide the “download projects from the internet automatically if necessary” functionality that people want in our modern world. So when you say (ql:quickload :cl-digraph) you’re asking Quicklisp to download cl-digraph (and any dependencies) if necessary, and then hand it off to ASDF to actually load the code of the cl-digraph system. Unlike ASDF, Quicklisp is relatively new in the Common Lisp world (it’s only about eight years old) bundled with any modern Lisp implementations (that I know of) (yet?), which is why you need to install it separately.

              So to summarize:

              • Files are files on your hard drive.
              • Packages are containers of symbols. They are orthogonal to files.
              • Systems are collections of code, plus instructions on how to load this code. They are orthogonal to packages.
              • Projects are high-level collections of… “stuff” (code, documentation, maybe some image assets, etc). They are (mostly) orthogonal to systems (seeing a trend here?).
              • Common Lisp knows about files and packages. ASDF adds systems. Quicklisp adds the internet.

              This is a pretty high-level view that glosses over a lot, but maybe it’ll clear things up and help you dive into the details later.

              1. 3

                Thanks a lot for taking the time to write this. I learnt a lot by reading it. Common Lisp is definitely interesting, and I am glad I finally started my journey to learn it :).

                1. 2

                  Like sjl said, I never put my own projects in ~quicklisp/local-projects but always put a symlink in there. I think that was the intent of that directory.

              1. 5

                This fun macro has been in Arc Lisp from the start under the name accum, and I find it extremely useful. For example, I recently added support for list comprehensions using it: http://akkartik.name/post/list-comprehensions-in-anarki

                One difference between the two: gathering uses a hardcoded function name gather, whereas accum takes a first arg that’s the function you call to ‘accumulate’ new item. Often we use acc, so calls begin (accum acc ...).

                1. 2

                  Interesting posr about list comprehensions!

                  It is commonly use collect or with-collector in Lisp. The named variant is also common.

                  https://github.com/jscl-project/jscl/blob/master/src/utils.lisp

                  There is even a variant to collect into multiple queues, in which case one has to provide a name for each collector.

                  1. 3

                    Serapeum has a version called collect too. I didn’t call it collect because that conflicts with iterate’s collect clause, and I tend to use iterate pretty heavily in my personal stuff..

                    1. 2

                      Thanks for that pointer! I wasn’t aware, but in my toy lisp I called the pair collect and yield. Glad I was on the right track!