# 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

.

.

# EQL5-Android

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

.

.

# 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

.

.

# 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
Isaac

asked Aug 21 ’10 at 2:02
hawkeye

.

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

.

.

# defmacro

SLIME, 2

.

Alt + Up/Down

Switch between the editor and the REPL

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

~~~

defmacro

.

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

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

(defun our-macroexpand-1 (expr)
(if (and (consp expr) (our-expander (car expr)))
(funcall (our-expander (car expr)) 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

— A MODEL OF MACROS

— 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

.

.

# funcall

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

.

.

.

# 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

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

gallerdude 3 months ago

There’s a good moral here. Everytime they had a question, they asked their users. Users don’t lie.

atYevP 3 months ago

Yev from Backblaze here -> That’s right! For better or worse they usually tell it like they see it, and that helps us inform decisions!

— How Backblaze Got Started (2017)

— Hacker News

.

.

2018.05.14 Monday ACHK

# The best software

somethingsimple 3 months ago

> Software is the currency that we pay to solve problems, which is our actual goal. We should endeavor to build as little software as possible to solve our problems.

.

ScottBurson 3 months ago

My point today is that, if we wish to count lines of code, we should not regard them as “lines produced” but as “lines spent”: the current conventional wisdom is so foolish as to book that count on the wrong side of the ledger. — E. W. Dijkstra

.

That’s why the best choice of software is often no software …

— Coding Horror

— by Jeff Atwood

.

— Write dumb code

— Hacker News

.

.

2018.05.01 Tuesday 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 lispcode@paulgraham.com.

(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)
(cond
((atom e) (assoc. e a))
((atom (car e))
(cond
((eq (car e) 'quote) (cadr e))
((eq (car e) 'atom)  (atom   (eval. (cadr e) a)))
((eq (car e) 'eq)    (eq     (eval. (cadr 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)
((eq (car e) 'cond)  (evcon. (cdr e) a))
('t (eval. (cons (assoc. (car e) a)
(cdr e))
a))))
((eq (caar e) 'label)
(eval. (cons (caddar e) (cdr e))
(cons (list. (cadar e) (car e)) a)))
((eq (caar e) 'lambda)
(append. (pair. (cadar e) (evlis. (cdr e) a))
a)))))

(defun evcon. (c a)
(cond ((eval. (caar 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

(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)
acc
(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

# Exercise 6.2

f :: a -> b
f' :: a -> m a
unit :: a -> m a

f' * g' = (bind f') . (bind g')

bind f xs = concat (map f xs)

bind unit xs = concat (map unit xs)

unit x = [x]

bind unit xs
= concat (map unit xs)
= concat (map unit [x1, x2, ...])
= concat [unit x1, unit x2, ...]
= concat [[x1], [x2], ...]
= [x1, x2, ...]
= xs

f' = lift f

lift f = unit . f

unit (or return) can directly act on an ordinary value only, but not on a monadic value. To act on a monadic value, you need to bind it.

How come we do not need to lift return?

f :: a -> b

liftM :: Monad m => (a -> b) -> m a -> m b

return :: a -> m a

(liftM f) :: m a -> m b

(>>=) :: Monad m => m a -> (a -> m b) -> m b

lifeM cannot be applied to return at all.

unit (or return) is neither a pure function nor a monadic function. Instead, it is an half-monadic function, meaning that while its input is an ordinary value, its output is a monadic value.

(bind return xs) -> ys

(bind return) applies to xs.

return applies to x.

liftM is merely fmap implemented with (>>=) and return

— Me@2016-01-26 03:05:50 PM

# Inception 11

.

Inception contains most of the important topics I have thought of in these few months:

1. Multi-mind

2. Layers of consciousness

3. Dream time

4. Lucid dream

5. Idea/software as a way to save Earth people

.

The deeper the consciousness, the more powerful it is.

The deepest layer is the Light.

The Light of everyone is the same.

— Me@2010.08.06

.

— Me@2010.08.09

.

.

.

2011.01.15 Saturday (c) ACHK

Game design

They got the key, and then some other stuff happened, and then they reached the door, and were able to open it; but “acquiring the key” and “opening the door” were stored as two separate, disconnected events in the player’s mind.

If the player had encountered the locked door first, tried to open it, been unable to, and then found the key and used it to open the door, the causal link would be unmistakable. You use the key to open the locked door, because you can’t open the locked door without the key.

Math education

I’ve drawn parallels between game design and education before, but it still took me a while to realize that problem-solution ordering issues crop up just as often in the classroom as they do in games.

Remember how, in high school math class, a lot of the work you were doing felt really, really pointless?

Consider Dan Meyer’s question for math educators: if math is the aspirin, then how do you create the headache?

In other words: if you introduce the solution (in this case, a new kind of math) before introducing the kind of problems that it’s meant to solve, the solution is likely to come across as pointless and arbitrary. But if you first let students try to tackle these problems with the math they already understand, they’re likely to come away with a kind of intellectual “headache” – and, therefore, to better understand the purpose of the “aspirin” you’re trying to sell.

Functional programming

— Locked doors, headaches, and intellectual need

— 27 October 2015

— Affording Play

Here are some excerpts of an elegant essay. Please go to the author’s website to read the whole.

— Me@2015-11-03 03:46:41 PM

2015.11.03 Tuesday ACHK

# Inception 4.2

.

What’s the most resilient parasite? An Idea. A single idea from the human mind can build cities. An idea can transform the world and rewrite all the rules. Which is why I have to steal it.

— Inception (film)

— Me@2010.07.30

.

.

.

2011.01.20 Thursday ACHK

# Exercise 6a (Corrected version)

Show that f' * unit = unit * f' = bind f'

——————————

f :: a -> b
f' :: a -> m a
unit :: a -> m a

lift f = unit . f
f' = lift f

The lift function in this tutorial is not the same as the liftM in Haskell. So you should use lift (but not liftM) with bind.

— Me@2015-10-13 11:59:53 AM

(f' * g') xs
= ((bind f') . (bind g')) xs

bind f' xs = concat (map f' xs)
unit x = [x]

bind unit xs
= concat (map unit xs)
= concat (map unit [x1, x2, ...])
= concat [unit x1, unit x2, ...]
= concat [[x1], [x2], ...]
= [x1, x2, ...]
= xs

(f' * unit) (x:xs)
= bind f' (bind unit (x:xs))
= bind f' (concat (map unit (x:xs)))
= bind f' (concat (map unit [x1, x2, ...]))
= bind f' (concat [[x1], [x2], ...])
= bind f' [x1, x2, ...]
= concat (map f' [x1, x2, ...])
= concat [f' x1, f' x2, ...]
= concat [(unit . f) x1, (unit . f) x2, ...]
= concat [(unit (f x1)), (unit (f x2)), ...]
= concat [[f x1], [f x2], ...]
= [f x1, f x2, ...]

(unit * f') (x:xs)
= ((bind unit) . (bind f')) (x:xs)
= bind unit (bind f' (x:xs))
= bind unit (concat (map f' (x:xs)))
= bind unit (concat (map f' [x1, x2, ...]))
= bind unit (concat [f' x1, f' x2, ...])
= bind unit (concat [(unit . f)  x1, (unit . f) x2, ...])
= bind unit (concat [(unit (f x1)), (unit (f x2)), ...])
= bind unit (concat [[f x1], [f x2], ...])
= bind unit [f x1, f x2, ...]
= concat (map unit [f x1, f x2, ...])
= concat [[f x1], [f x2], ...]
= [f x1, f x2, ...]

— Me@2015-10-15 07:19:18 AM

If we use the identity bind unit xs = xs, the proof will be much shorter.

(f' * unit) (x:xs)
= ((bind f') . (bind unit)) (x:xs)
= bind f' (bind unit (x:xs))
= bind f' (x:xs)

(unit * f') (x:xs)
= ((bind unit) . (bind f')) (x:xs)
= bind unit (bind f' (x:xs))
= bind f' (x:xs)

— Me@2015-10-15 11:45:44 AM