# 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 ```emacs-lisp (car '(123)) ``` - `cdr` retrieves everything besides the first element of a list ```emacs-lisp (cdr '(a b c)) ``` - `cons` adds an atom to the front of a list ```emacs-lisp (cons 100 '(a b c)) (cons '(a b) '(c d)) ``` - `null` tests for empty lists ```emacs-lisp (null ()) ``` - `atom` tests for atoms ```emacs-lisp (atom 123) ``` - `eq` tests equality for non-numeric atoms ```emacs-lisp (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 ```emacs-lisp (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: ```scheme (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