the little schemer
-
a [[book]]
- [[preview]] https://via.hypothes.is/https://ipfs.io/ipfs/bafykbzacedbxckanhuutgrhd3og4pvau23oihmc4tzgzoo5tb57zs6vrbshfk?filename=Bibby%2C%20Duane_Felleisen%2C%20Matthias_Friedman%2C%20Daniel%20P%20-%20Daniel%20P.%20Friedman%20%26%20Matthias_%20The%20Little%20Schemer-MIT%20Press%20%282007%29.pdf
- recommended by [[danlistensto]]
The Little Schemer
tags : [[lisp]] [[functional programming]] [[Scheme]]
Some of my examples are written in Emacs Lisp, as at the time I hadnβt installed a Scheme interpreter. It doesnβt make a huge difference.
1. Toys
-
an atom is a simple element, separated by spaces
-
a list is a series of atoms, surrounded by parentheses
-
an atom or a list
-
car
retrieves first element of list(car '(123))
-
cdr
retrieves everything besides the first element of a list(cdr '(a b c))
-
cons
adds an atom to the front of a list(cons 100 '(a b c)) (cons '(a b) '(c d))
-
null
tests for empty lists(null ())
-
atom
tests for atoms(atom 123)
-
eq
tests equality for non-numeric atoms(eq 'a 'b)
2. Do It, Do It Again
- always ask
null?
first! - this chapter serves as a good introduction to recursion and tracing through lisp programs
3. Cons the Magnificent
cons
is for building lists- important: when building lists from lists, figure out what the first element looks like, then recur over the
cdr
of the rest of the list
(defun firsts (l)
(cond
((null l) '())
(t (cons (car (car l)) (firsts (cdr l)) ))))
(firsts '((a b) (c d))) ;; => (a c)
a | c |
5. Oh My Gawd: Itβs full of Stars
-
In Scheme (and other Lisps?) a * suffix means βrepeat this throughout the list.β More specifically, it means to recur on the
car
of the list.For example:
(rember* 'sauce ((tomato sauce) bean sauce)) ;; => ((tomato) bean) (rember 'sauce ((tomato sauce) bean sauce)) ;; => ((tomato) bean sauce)
-
The first commandment says that, when recurring, you must ask between two to three questions. For a list of atoms, itβs β
null?
β and βelse
β, and for S-expressions, itβs βnull?
β, βatom? (car l)
β, and βelse
β -
The fourth commandment says that, when recurring, you must change at least one argument. When traversing over a list, decrement the list using
cdr
-
The sixth commandment is very important: βsimplify only after the function is correctβ
6. Shadows
The Seventh Commandment : Recur on the subparts that are of the same nature
An attempt at value
(for only +
) in Emacs Lisp:
```emacs-lisp
(defun my-value (nexp)
(cond
((atom nexp) nexp)
((eq (car (cdr nexp)) '+) (+ (value (car nexp)) (value (car (cdr (cdr nexp))))))
(t nexp)))
(my-value '(1 + 2))
```
The Eighth Commandment : Use help functions to abstract from representations