I'm back from various holidays and travelling and have completed my notes on Chapters 1 and 2 of The Land of Lisp, so here they are!
ch2.lisp in the GitHub repo contain each chapter's notes, walking you through the material covered therein. They can be loaded in the ECL REPL by calling
(load "/path/to/ch2.lisp"), and commented-out code (and, indeed, non-commented-out code) can be evaluated in a SLIME session by moving to the end of the S-expression to be evaluated and pressing
C-x C-e. I hope they're of use to you.
Get it here: http://www.github.com/loomcore/raspberry-lisp
Slightly oddly, Barski covers local variables and functions at the end of Chapter 2, just after we finish writing the 'Guess My Number' game. As that didn't really fit in with the main exercise, I thought I'd cover it here, rather than in the code itself.
We've used only global variables in the game, but it is possible to declare throwaway values that are only used within the scope of one expression. We call these 'local variables', as they are only used locally to one expression, rather than throughout the entire program (globally).
Lisp allows us to declare local variable using the
let function, as follows.
let takes two arguments: a list of lists defining mappings from values to local variable names (using a format of
((name1 val1) (name2 val2))), and an S-expression in which the defined local variables are bound. In the above expression, we map
x to the value 12 and
y to the value 34. We then call
(+ x y), which, in this case, is equivalent to
(+ 12 34), giving the answer 46.
Let's try another example:--
In this case,
(* a b) will quite happily return the answer 12, but note that once we are out of the scope of the
b are no longer defined, and thus
(+ a b) fails.
Functions can also be declared locally in Lisp, using the
flet function. For example:--
flet, similarly to
let, takes two arguments. The first is a list of lists defining local functions (using a format of
((name1 (arg1...argn) (fn1)) (name2 (arg1...argn) (fn2)))), and the second is an S-expression in which the local functions are bound. In the above expression, we define
(f x y) as
(+ x (* 2 y)), and
(g x) as
(- x 3). We then call
(g (f 2 3)), returning the answer 5. This is all well and good, but sadly
flet doesn't let us refer to other local functions in new definitions. This can instead be achieved by using the
f is referred to inside the definition of
g. The above expression performs the same operation as the one using
(- (+ 2 (* 2 3)) 3), returning the value 5 once again.
Being able to call functions in this way is useful, as it allows us to construct recursive local functions -- that is, functions that call themselves. Since we won't cover conditionals until the next instalment, I will spare you an explanation of recursion for now, but bear in mind that it is absolutely fundamental to successful Lisp programming (and, indeed, functional programming as a whole), so be prepared.
Once again, I hope this was useful for you. Stay tuned for Chapters 3 and 4 next time!