The Android SDK Tools

EQL5-Android | Common Lisp for Android App Development 2018


After installing Qt, check whether its version is 5.9 or later.


If so, install the Android SDK Tools by installing Android Studio.

If you use Ubuntu 18.04 or later, you can use the snap command to install Android Studio.


Besides installing Android Studio, it also automatically updates Android Studio regularly.

— Me@2018-12-12 02:21:45 PM



2018.12.12 Wednesday (c) All rights reserved by ACHK


Common Lisp for Android App Development 2018


The first step to set up EQL5-Android is to install Qt.


In Ubuntu, if you do not need the most updated Qt, you can just install the Qt-Creator using apt-get.

— Me@2018-12-08 09:18:19 PM



2018.12.08 Saturday (c) All rights reserved by ACHK

Common Lisp for Android App Development 2018

An REPL called “CL REPL” is available in the Google Play Store. But itself is not for developing standalone Android apps, unless those apps are Common Lisp source code files only.

However, “CL REPL” itself is an open source GUI app using Common Lisp and Qt. So by learning and using its source, in principle, we can create other Android apps using Common Lisp with Qt.

The library that “CL REPL” uses is EQL5-Android.

— Me@2018-11-23 04:07:54 PM



2018.11.23 Friday (c) All rights reserved by ACHK

defmacro, 2

Defining the defmacro function using only LISP primitives?


McCarthy’s Elementary S-functions and predicates were

atom, eq, car, cdr, cons


He then went on to add to his basic notation, to enable writing what he called S-functions:

quote, cond, lambda, label


On that basis, we’ll call these “the LISP primitives”…

How would you define the defmacro function using only these primitives in the LISP of your choice?

edited Aug 21 ’10 at 2:47

asked Aug 21 ’10 at 2:02


Every macro in Lisp is just a symbol bound to a lambda with a little flag set somewhere, somehow, that eval checks and that, if set, causes eval to call the lambda at macro expansion time and substitute the form with its return value. If you look at the defmacro macro itself, you can see that all it’s doing is rearranging things so you get a def of a var to have a fn as its value, and then a call to .setMacro on that var, just like core.clj is doing on defmacro itself, manually, since it doesn’t have defmacro to use to define defmacro yet.

– dreish Aug 22 ’10 at 1:40



2018.11.17 Saturday (c) All rights reserved by ACHK




Alt + Up/Down

Switch between the editor and the REPL

— Me@2018-11-07 05:57:54 AM




(defmacro our-expander (name) `(get ,name 'expander))

(defmacro our-defmacro (name parms &body body)
  (let ((g (gensym)))
       (setf (our-expander ',name)
	     #'(lambda (,g)
		 (block ,name
		   (destructuring-bind ,parms (cdr ,g)

(defun our-macroexpand-1 (expr)
  (if (and (consp expr) (our-expander (car expr)))
      (funcall (our-expander (car expr)) expr)


A formal description of what macros do would be long and confusing. Experienced programmers do not carry such a description in their heads anyway. It’s more convenient to remember what defmacro does by imagining how it would be defined.

The definition in Figure 7.6 gives a fairly accurate impression of what macros do, but like any sketch it is incomplete. It wouldn’t handle the &whole keyword properly. And what defmacro really stores as the macro-function of its first argument is a function of two arguments: the macro call, and the lexical environment in which it occurs.

— p.95


— On Lisp

— Paul Graham


(our-defmacro sq (x)
  `(* ,x ,x))

After using our-defmacro to define the macro sq, if we use it directly,

(sq 2)

we will get an error.

The function COMMON-LISP-USER::SQ is undefined.
[Condition of type UNDEFINED-FUNCTION]

Instead, we should use (eval (our-macroexpand-1 ':

(eval (our-macroexpand-1 '(sq 2)))

— Me@2018-11-07 02:12:47 PM



2018.11.07 Wednesday (c) All rights reserved by ACHK


In Common Lisp, apply can take any number of arguments, and the function given first will be applied to the list made by consing the rest of the arguments onto the list given last. So the expression

(apply #’+ 1 ’(2))

is equivalent to the preceding four. If it is inconvenient to give the arguments as
a list, we can use funcall, which differs from apply only in this respect. This expression

(funcall #’+ 1 2)

has the same effect as those above.

— p.13

— On Lisp

— Paul Graham


Exercise 7.1

Define funcall.



















(defmacro our-funcall (f &rest p)
  `(apply ,f (list ,@p)))

— Me@2018-10-30 03:24:05 PM




2018.10.30 Tuesday (c) All rights reserved by ACHK

A Road to Common Lisp

tumba 57 days ago [-]

My advice is this: as you learn Common Lisp and look for libraries, try to suppress the voice in the back of your head that says “This project was last updated six years ago? That’s probably abandoned and broken.” The stability of Common Lisp means that sometimes libraries can just be done, not abandoned, so don’t dismiss them out of hand.

I have found this to be true in my own experience. The perception of stagnation is, however, a common initial objection to folks working in CL for the first time.

mike_ivanov 57 days ago [-]

My personal problem with CL libraries is not that, but rather the lack of documentation. More often than not, there is no documentation at all, not even a readme file.. It feels like some library authors simply don’t care. I’d say this attitude has a negative impact on how people perceive viability of those libraries — and by extension, of the language.

armitron 56 days ago [-]

A lot of libraries that don’t have separate documentation in the form of HTML/PDF/README.. are actually well-documented at source level in the form of docstrings.
Since Common Lisp is an interactive programming language and is meant to be used interactively (think Smalltalk, not Python) it is common practice to (interactively) load a library in a Common Lisp image and explore it (interactively). One can see what symbols are exported from packages, what these symbols are used for and (interactively) retrieve their documentation. All of this takes place within the editing environment (ideally Emacs) in a rapid feedback loop (again think Smalltalk, not Python) that feels seamless and tremendously empowering.

stevelosh 56 days ago [-]

I agree with this — it’s a real problem. My only solution has been to try to be the change I want to see in the world and document all of my own libraries before I officially release them.

— A Road to Common Lisp

— Hacker News



2018.10.24 Wednesday ACHK


SLIME, the Superior Lisp Interaction Mode for Emacs, is an Emacs mode for developing Common Lisp applications. SLIME originates in an Emacs mode called SLIM written by Eric Marsden. It is developed as an open-source public domain software project by Luke Gorrie and Helmut Eller. Over 100 Lisp developers have contributed code to SLIME since the project was started in 2003. SLIME uses a backend called Swank that is loaded into Common Lisp.

— Wikipedia on SLIME


C-x o

Window-Move to other

C-x C-e

Evaluate last expression

C-c C-r

Evaluate region



2018.10.19 Friday (c) ACHK

Lisp in Lisp

; The Lisp defined in McCarthy's 1960 paper, translated into CL.
; Assumes only quote, atom, eq, cons, car, cdr, cond.
; Bug reports to

(defun null. (x)
  (eq x '()))

(defun and. (x y)
  (cond (x (cond (y 't) ('t '())))
        ('t '())))

(defun not. (x)
  (cond (x '())
        ('t 't)))

(defun append. (x y)
  (cond ((null. x) y)
        ('t (cons (car x) (append. (cdr x) y)))))

(defun list. (x y)
  (cons x (cons y '())))

(defun pair. (x y)
  (cond ((and. (null. x) (null. y)) '())
        ((and. (not. (atom x)) (not. (atom y)))
         (cons (list. (car x) (car y))
               (pair. (cdr x) (cdr y))))))

(defun assoc. (x y)
  (cond ((eq (caar y) x) (cadar y))
        ('t (assoc. x (cdr y)))))

(defun eval. (e a)
    ((atom e) (assoc. e a))
    ((atom (car e))
       ((eq (car e) 'quote) (cadr e))
       ((eq (car e) 'atom)  (atom   (eval. (cadr e) a)))
       ((eq (car e) 'eq)    (eq     (eval. (cadr e) a)
                                    (eval. (caddr e) a)))
       ((eq (car e) 'car)   (car    (eval. (cadr e) a)))
       ((eq (car e) 'cdr)   (cdr    (eval. (cadr e) a)))
       ((eq (car e) 'cons)  (cons   (eval. (cadr e) a)
                                    (eval. (caddr e) a)))
       ((eq (car e) 'cond)  (evcon. (cdr e) a))
       ('t (eval. (cons (assoc. (car e) a)
                        (cdr e))
    ((eq (caar e) 'label)
     (eval. (cons (caddar e) (cdr e))
            (cons (list. (cadar e) (car e)) a)))
    ((eq (caar e) 'lambda)
     (eval. (caddar e)
            (append. (pair. (cadar e) (evlis. (cdr e) a))

(defun evcon. (c a)
  (cond ((eval. (caar c) a)
         (eval. (cadar c) a))
        ('t (evcon. (cdr c) a))))

(defun evlis. (m a)
  (cond ((null. m) '())
        ('t (cons (eval.  (car m) a)
                  (evlis. (cdr m) a)))))

— Paul Graham



2018.03.15 Thursday ACHK

Shape of a program

(defun bad-reverse (lst)
  (let* ((len (length lst))
	 (ilimit (truncate (/ len 2))))
    (do ((i 0 (1+ i))
	 (j (1- len) (1- j)))
	((>= i ilimit))
      (rotatef (nth i lst) (nth j lst)))))

It used to be thought that you could judge someone’s character by looking at the shape of his head. Whether or not this is true of people, it is generally true of Lisp programs. Functional programs have a different shape from imperative ones. The structure in a functional program comes entirely from the composition of arguments within expressions, and since arguments are indented, functional code will show more variation in indentation. Functional code looks fluid on the page; imperative code looks solid and blockish, like Basic.

Even from a distance, the shapes of bad- and good-reverse suggest which is the better program. And despite being shorter, good-reverse is also more efficient: O(n) instead of O(n^2).

(defun good-reverse (lst)
  (labels ((rev (lst acc)
		(if (null lst)
		  (rev (cdr lst) (cons (car lst) acc)))))
    (rev lst nil)))

— p.30

— On Lisp

— Paul Graham



2018.03.02 Friday ACHK

On Lisp


Lisp is an especially good language for writing extensible programs because it is itself an extensible program.

Because Lisp gives you the freedom to define your own operators, you can mold it into just the language you need. If you’re writing a text-editor, you can turn Lisp into a language for writing text-editors. If you’re writing a CAD program, you can turn Lisp into a language for writing CAD programs. And if you’re not sure yet what kind of program you’re writing, it’s a safe bet to write it in Lisp. Whatever kind of program yours turns out to be, Lisp will, during the writing of it, have evolved into a language for writing that kind of program.

— On Lisp: Advanced Techniques for Common Lisp

— Paul Graham



2018.02.21 Wednesday ACHK


Just as every day thoughts are expressed in natural language, and formal deductions are expressed in mathematical language, methodological thoughts are expressed in programming languages. A programming language is a method for communicating methods, not just a means for getting a computer to perform operations – programs are written for people to read as much as they are written for machines to execute.

— Lisp: A language for stratified design

— Harold Abelson, Gerald Jay Sussman

— SICP distilled

— jao 

2013.05.31 Friday ACHK

Professor 2

lisper 4 days ago | link

I was never in academia, but I was a researcher (at NASA) so I played the publishing game. And if you look at my record, I was relatively good at it. Not only was my publications list fairly long, but my work was also pretty widely referenced. But since my career no longer depends on it, I am now free to say that I credit my success almost entirely to gaming the system. This is not to say that I didn’t do good work (I think I did), but there was virtually no correlation between what I thought was quality work and what I actually got rewarded for. The vast majority of my publications were minor tweaks on previous work that were specifically engineered to get past the program committees of key conferences. My best work (by my own quality metric) either went unnoticed, or could not get accepted for publication at all. When it got to the point where I was faced with a very stark choice between continuing to produce bullshit and get rewarded for it, or to do what I thought was good work and eventually get fired, I quit.

Evbn 4 days ago | link

Industry isn’t so different. My salary is determined by 2 days of interviews and negotiations, and only slightly perturbed by my performance over the next several years.

— Hacker News

2013.01.11 Friday ACHK

Paul Graham

zatara 59 days ago | link

I am almost afraid to ask you this, but here it goes.

On the last few weeks/months before starting Viaweb, did you consider yourself a failure for being almost 30, well-educated but out of the formal career track, “poor” and unmarried? If so, was that the fuel behind your many amazing achievements later on?

pg 59 days ago | link

No, not really. I’d written the two Lisp books, and people liked those. Not a lot of people, but they were people whose opinions I cared about. Actually Viaweb felt like more of a compromise than the way I’d been living before, because it was something I was doing mostly for money.

sayemm 58 days ago | link

So, you finally had your first taste of startup success at age 34. And you started Y Combinator at 41.

Think your story, along with many others in the Valley (e.g. Jim Clark), goes to show that this is a long-term game, and it only gets better with age and experience.

— Hacker News

2013.01.11 Friday ACHK

Functional programming 6

A central concept in functional languages is that the result of a function is determined by its input, and only by its input. There are no side-effects! 

— Why Haskell matters

My question is, if a function makes changes only within its local environment, and returns the result, how can it interact with a database or a file system? By definition, wouldn’t that be accessing what is in effect a global variable or global state?

What is the most common pattern used to get around or address this?
— edited Dec 7 ’11 at 2:10, Matt Fenwick
— asked Dec 6 ’11 at 20:18, juwiley

The most common pattern for dealing with side-effects and impurity in functional languages is:

  •     be pragmatic, not a purist
  •     provide built-ins that allow impure code and side-effects
  •     use them as little as possible!


  •     Lisp/Scheme: set!
  •     Clojure: refs, and using mutating methods on java objects
  •     Scala: creating variables with var
  •     ML: not sure of specifics, but Wikipedia says it allows some impurity

Haskell cheats a little bit — its solution is that for functions that access the file system, or the database, the state of the entire universe at that instant, including the state of the filesystem/db, will be passed in to the function.(1) Thus, if you can replicate the state of the entire universe at that instant, then you can get the same results twice from such a function. Of course, you can’t replicate the state of the entire universe at that instant, and so the functions return different values …

But Haskell’s solution, IMHO, is not the most common.

(1) Not sure of the specifics here. Thanks to CAMcCann for pointing out that this metaphor is overused and maybe not all that accurate.   

— edited Dec 7 ’11 at 2:11

— answered Dec 6 ’11 at 22:00, Matt Fenwick

— Stack Overflow

2012.08.12 Sunday ACHK

Meaningful 7

upgrade path


— Me@2012-08-06 8:28:47 AM

Somewhere in the course of doing Viaweb, someone gave me a very useful piece of advice: users always want an upgrade path, even though as a rule they’ll never take it. Rtml was our upgrade path. If you wanted to, you could get absolute control over everything on your pages.

— Lisp in Web-Based Applications

— Paul Graham

2012.08.11 Saturday (c) All rights reserved by ACHK

The Dragon Book, 2

Most people don’t realize that writing a compiler like this is only about 2 months work for one talented person who read the Dragon book. Since the compiler only has one body of code to compile, it is much easier to write. It doesn’t have to be a general-purpose compiler. It doesn’t have a math library, for example.

And we have the ability to add any feature to the language that we want easily… this is the same power Paul Graham talks about in On Lisp, the power to invent new language features that suit your exact application domain. Lisp does this through a mechanism called macros.

— Wasabi

— Joel on Software

— Joel Spolsky

2012.06.20 Wednesday ACHK


Basically, Python can be seen as a dialect of Lisp with “traditional” syntax (what Lisp people call “infix” or “m-lisp” syntax).

Python can be seen as either a practical (better libraries) version of Scheme, or as a cleaned-up (no $@&% characters) version of Perl.

One of Python’s controversial features, using indentation level rather than begin/end or braces, was driven by this philosophy: since there are no braces, there are no style wars over where to put the braces. Interestingly, Lisp has exactly the same philosphy on this point: everyone uses emacs to indent their code, so they don’t argue over the indentation.

Take a Lisp program, indent it properly, and delete the opening parens at the start of lines and their matching close parens, and you end up with something that looks rather like a Python program.

— Python for Lisp Programmers

— Peter Norvig

2012.05.22 Tuesday ACHK

Lisp macros 2.2

I think one of the problems with Lisp is that it is too powerful. It has so much meta ability that it allows people to invent their own little worlds, and it takes a while to figure out each person’s little world (SoftwareGivesUsGodLikePowers).

— Lisp is Too Powerful

2012.02.19 Sunday ACHK

Lisp macros 2

People complain macros are difficult to understand. Macros are easy. If you can understand a program that concatenates lists to make a new list, you can understand a macro. Macros are quite literally ‘just lisp code’.

— ohyes 2 weeks ago

— Lisp is Too Powerful

— Hacker News

2012.01.07 Saturday ACHK