DO

While DOLIST and DOTIMES are convenient and easy to use, they aren’t flexible enough to use for all loops. For instance, what if you want to step multiple variables in parallel?

(do (variable-definition*)
    (end-test-form result-form*)
  statement*)

— Practical Common Lisp

— Peter Seibel

.

(defun split-if (fn lst)
  (let ((acc nil))
    (do ((src lst (cdr src)))
        ((or (null src) (funcall fn (car src)))
         (values (nreverse acc) src))
      (push (car src) acc))))


>(split-if #'(lambda (x) (> x 4)) '(1 2 3 4 5 6 7 8 9 10))

(1 2 3 4)
(5 6 7 8 9 10)

— p.50

— On Lisp

— Paul Graham

.

Exercise 4.5

Implement the function split-if without using the macro do.

— Me@2019-01-30 09:58:30 PM

.

.

2019.01.30 Wednesday ACHK

duplicate

If (member o l) finds o in the list l, it also returns the cdr of l beginning with o. This return value can be used, for example, to test for duplication. If o is duplicated in l, then it will also be found in the cdr of the list returned by member. This idiom is embodied in the next utility, duplicate:

>(duplicate ’a ’(a b c a d))
(A D)

(defun duplicate (obj lst &key (test #’eql))
    (member obj (cdr (member obj lst :test test))
            :test test))

— p.51

— On Lisp

— Paul Graham

.

Exercise 4.4

Without using the existing function member, define duplicate as in

>(duplicate ’a ’(a b c a d))
(A D)

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

— This answer is my guess. —


(defun my-member (obj lst)
    (cond ((not lst) NIL)
          ((eq obj (car lst)) lst)
          (t (my-member obj (cdr lst)))))

— This answer is my guess. —

— Me@2019-01-21 06:34:46 AM

.

.

2019.01.21 Monday (c) All rights reserved by ACHK

Equality Predicates

6.3. Equality Predicates

Common Lisp provides a spectrum of predicates for testing for equality of two objects: eq (the most specific), eql, equal, and equalp (the most general).

eq and equal have the meanings traditional in Lisp.

eql was added because it is frequently needed, and equalp was added primarily in order to have a version of equal that would ignore type differences when comparing numbers and case differences when comparing characters.

If two objects satisfy any one of these equality predicates, then they also satisfy all those that are more general.

.

[Function]
eq x y

(eq x y) is true if and only if x and y are the same identical object. (Implementationally, x and y are usually eq if and only if they address the same identical memory location.)

.

The predicate eql is the same as eq, except that if the arguments are characters or numbers of the same type then their values are compared. Thus eql tells whether two objects are conceptually the same, whereas eq tells whether two objects are implementationally identical. It is for this reason that eql, not eq, is the default comparison predicate for the sequence functions defined in chapter 14.

.

[Function]
eql x y

The eql predicate is true if its arguments are eq, or if they are numbers of the same type with the same value, or if they are character objects that represent the same character.

.

[Function]
equal x y

The equal predicate is true if its arguments are structurally similar (isomorphic) objects. A rough rule of thumb is that two objects are equal if and only if their printed representations are the same.

Numbers and characters are compared as for eql. Symbols are compared as for eq. This method of comparing symbols can violate the rule of thumb for equal and printed representations, but only in the infrequently occurring case of two distinct symbols with the same print name.

.

[Function]
equalp x y

Two objects are equalp if they are equal; if they are characters and satisfy char-equal, which ignores alphabetic case and certain other attributes of characters; if they are numbers and have the same numerical value, even if they are of different types; or if they have components that are all equalp.

— Common Lisp the Language, 2nd Edition

— Guy L. Steele Jr.

.

Conrad’s Rule of Thumb for Comparing Stuff:

1. Use eq to compare symbols

2. Use equal for everything else

— Land of Lisp, p.63

— Conrad Barski, M. D.

.

.

2019.01.16 Wednesday ACHK

Clasp

Overview

Clasp is a new Common Lisp implementation that seamlessly interoperates with C++ libraries and programs using LLVM for compilation to native code. This allows Clasp to take advantage of a vast array of preexisting libraries and programs, such as out of the scientific computing ecosystem. Embedding them in a Common Lisp environment allows you to make use of rapid prototyping, incremental development, and other capabilities that make it a powerful language.

— Clasp README.md

.

I followed the official instructions to build Clasp:

d_2019_01_04__12_06_48_pm_

The building process had been going on for about an hour; and then I got this error:

d_2019_01_04__17_53_17_pm_

d_2019_01_04__23_07_39_pm_

— Me@2019-01-04 10:11:43 PM

.

.

2019.01.04 Friday (c) All rights reserved by ACHK

Build cross-compiled ECL for Android, 3

EQL5-Android | Common Lisp for Android App Development 2018

.

d_2018_12_19__22_56_00_PM_

After successfully running the command ./1-make-ecl-host.sh, when I tried to run the command ./2-make-ecl-android.sh, I got the following errors:

d_2018_12_29__23_30_22_PM_

— Me@2018-12-29 11:21:46 PM

.

.

2018.12.30 Sunday (c) All rights reserved by ACHK

Build cross-compiled ECL for Android, 2

EQL5-Android | Common Lisp for Android App Development 2018

.

The step 2 is to “build cross-compiled ECL for Android”. It should have been straightforward to follow the instructions in the README page of the EQL5-Android project.

d_2018_12_19__22_56_00_PM_

However, when trying to run the command ./1-make-ecl-host.sh, I got the following error messages:

d_2018_12_19__23_11_14_PM_

The error was caused by the fact that my Ubuntu 18.04’s 64-bit gcc toolchain could not compile any source code to create 32-bit executables.

The solution is to run the following command to install the 32-bit gcc toolchain first:

sudo apt-get install g++-multilib libc6-dev-i386

— Me@2018-12-25 09:51:02 PM

.

.

2018.12.25 Tuesday (c) All rights reserved by ACHK

Build cross-compiled ECL for Android

EQL5-Android | Common Lisp for Android App Development 2018

.

The step 2 is to “build cross-compiled ECL for Android”. It should have been straightforward to follow the instructions in the README page of the EQL5-Android project.

d_2018_12_19__22_56_00_PM_

However, when trying to run the command ./1-make-ecl-host.sh, I got the following error messages:

d_2018_12_19__23_11_14_PM_

A more serious problem was that I could not even locate the error log file config.log.

.

Another abnormality was that while the process claimed that it was

Creating directory 'build',

the directory build was actually not created at all.

So I manually created that directory before running the command ./1-make-ecl-host.sh again. Only then, I could find the error log file config.log in the build directory, after the failure of the compilation.

— Me@2018-12-19 10:50:31 PM

.

.

2018.12.19 Wednesday (c) All rights reserved by ACHK

The Android NDK Tools

EQL5-Android | Common Lisp for Android App Development 2018

.

After installing the Android SDK Tools by installing Android Studio, originally, you would be able to install the Android NDK through Android Studio’s SDK Manager.

d_2018_12_16__17_27_49_PM_

However, since EQL5-Android requires an old version of the NDK (version 10e), you have to download the NDK from the Android’s official NDK webpage.

d_2018_12_16__16_22_31_PM_

In Ubuntu, move the file android-ndk-r10e-linux-x86_64.zip to the same location as the Android SDK and then unzip it.

— Me@2018-12-16 09:25:10 PM

.

.

2018.12.16 Sunday (c) All rights reserved by ACHK

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.

d_2018_12_12__14_28_48_PM_

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.

d_2018_12_12__22_11_20_PM_

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

EQL5-Android

Common Lisp for Android App Development 2018

.

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

d_2018_12_08__21_55_22_PM_

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

.

.

2018.11.17 Saturday (c) All rights reserved by ACHK

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

.

.

2018.11.07 Wednesday (c) All rights reserved by ACHK

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

.

.

.

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

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 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)
                                    (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))
                  a))))
    ((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))
                     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)
		    acc
		  (rev (cdr lst) (cons (car lst) acc)))))
    (rev lst nil)))

— p.30

— On Lisp

— Paul Graham

.

.

2018.03.02 Friday ACHK

On Lisp

paulgraham_2202_3475946

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

SICP, 3

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