I’ve made an image to describe Common Lisp method composition (or CLOS method composition if you want):
SCons is a program designed to replace make and autotools. SCons being a new tool is built with all the knowledge of what problem really this kind of tool should be solving, while make and autotools were built while discovering the real problem. It is natural to expect SCons to have a better design that covers the big picture. Continue reading
I recently stated what I believe is the biggest problem with Lisp, you can’t make programs with it. In my quest, my first solution is a very simplistic Makefile that does the job using cl-launch, a very interesting program that can turn a Common Lisp program into a Bash script. Other solutions are likely to use cl-launch as well.
So, we’ll play with this little program:
(defun main () (format t "Hello world!~%")) (main)
Very trivial indeed. And to “compile it”, we’d use this trivial Makefile:
%: %.lisp cl-launch --output $@ --file $&< hello-world: hello-world.lisp
All we have to do now is run make:
$ make cl-launch --output hello-world --file hello-world.lisp
And we now have a runable hello-world:
$ ./hello-world Hello world!
It run! it worked! it’s portable! Isn’t it great?
Obviously all the logic is hidden inside cl-launch (thank you Fare Rideau). The problems with this simple solution is that using only make makes programs harder to port and package for different distributions and operating systems. That’s why the autotools where invented. Remember those days when to compile something we had to open a Makefile and set up variables? well, this simplistic solution is going back to those days. We can do better, I hope I can do better.
Now, for the curious, this is how the hello-world script looks like (I’d say its quite remarkable):
#!/bin/sh #| CL-LAUNCH 2.03 CONFIGURATION SOFTWARE_FILE=. SOFTWARE_SYSTEM= SOFTWARE_INIT_FORMS= SYSTEMS_PATHS= INCLUDE_PATH=/usr/share/common-lisp/source/cl-launch LISPS="cmucl sbcl clisp ecl openmcl gclcvs allegro lisp gcl" WRAPPER_CODE= DUMP= RESTART= IMAGE_BASE= IMAGE_DIR= IMAGE= # END OF CL-LAUNCH CONFIGURATION # This file was generated by CL-Launch 2.03 # This file was automatically generated and contains parts of CL-Launch # PROG="" . /usr/share/common-lisp/source/cl-launch/wrapper.sh launch_self "$@" ABORT # |# (load "/usr/share/common-lisp/source/cl-launch/header.lisp" :verbose nil :print nil) ;;;; CL-LAUNCH LISP INITIALIZATION CODE #-cl-launched (cl-launch::run :load :self) ;;;; END OF CL-LAUNCH LISP INITIALIZATION CODE ;;; 65bcc57c2179aad145614ec328ce5ba8 SOFTWARE WRAPPED BY CL-LAUNCH BEGINS HERE: (defun main () (format t "Hello world!~%")) (main)
I’m not really going to talk about the problem with Lisp, but only a problem. And I’m not really going to talk about Lisp, but Common Lisp. So this post should be called “A problem with Common Lisp”, but the current title is more catchy, isn’t it?
You are still with me? nice. Because I believe I have something important to say. A problem with Common Lisp is that you can’t make programs with it. That may have been another nice catchy title: “You can’t make programs with Lisp”. Continue reading
Common Lisp macros feel like cheating. I’ve reached chapter 9 of Practical Common Lisp, where the goal is to build a unit test framework, and you can see right away how the patterns are easily abstracted out with macros. It’s so easy it feels like cheating.
Getting a text representation of the test code to be able to point what when wrong, to show the piece of code failing, is supposed to be a hard task. Well, it is a hard task, sometimes impossible, in most programming languages. In Common Lisp it’s so trivial, it feels like cheating.
If you want to know what Lisp is about, read up to chapter 9 of PCL (Practical Common Lisp), at least. I used to tell people to at least read chapter 3, but it seems not to be enough, sadly, to impress the average programmer (either because they just don’t see it or chapter 3 is still too basic).
Comments at the original blog
Hey, good point. You know what also feels like cheating to me? The loop language.
I mean, from the 99 lisp problems:
Flatten a tree of lists:
(defun flatten (list) (loop for i in list if (listp i) append (flatten i) else collect i))
or, remove duplicated values from a list
(defun makeset (list) (loop for i in list unless (find i set) collect i into set finally (return set)))
At first it looks like cheating, but then i realized that the loop language is to lists what regular expressions are to strings, and it’s better than having a bunch of different people writing their loops and boilerplate in different ways.
I’ve discovered something recently. Most programmers have a favourite programming language. No, that’s not it, there’s more to my discovery. Whenever those programmers have an idea they open a text editor and start coding and/or they start playing with a REPL, if they are lucky to like a programming language that provides one.
You watch them code and they do it fast, with little errors. They don’t program fast because it’s a good language, they program fast because they know it, and they know it because they use it often, and they do that because they like it. That was the first part of my discovery. Continue reading