Land of Lisp
Posted on by Idorobots
I finally got around to writing a proper review of this book...
Lisp is a unique language that I decided to learn and use daily, so I grabbed the Land of Lisp by Conrad Barski and took off towards Alpha Centauri. It's a mighty fine read indeed, see for yourself:
> (new-game)
You are in the study. The wizard Astronis is snoring loudly on the couch. There is a ladder going upstairs from here. There is a staircase going downstairs from
here. You see a bottle on the ground. You see a potion on the ground.
pickup potion
You pick up the potion
inventory
Items- potion
walk downstairs
You are in the basement. There are some chests here. There is a door going west from here. There is a staircase going upstairs from here. You see a bucket on the
ground. You see a staff on the ground. You see a robe on the ground.
pickup staff
You pick up the staff
walk china
You cannot go there.
quit
Bye bye!
(This is my slightly modified version.)
It's really simple, yet very cool. In chapter 7 we even create a utility that allows us to visualize the game world a little:
We use the same utility again in chapter 8, which you can download for free here, creating another graph based game - Grand Theft Wumpus.
The purpose of the game is to catch Wumpus, who slapped our sh*t, in a maze-like city. We have to watch out for the police and local gangs. I have to admit that this game is very playable, I've spent a whole evening playing it.
The graph utility uses Graphviz. It's a nice little tool for graph visualization.
In chapter 9 we create yet another game - Orc battle. This one is a tiny strategic game where we have to survive an ambush by several vicious monsters, it shows Common Lisp's basic OOP capabilities (CLOS not included).
> (orc-battle)
You: HP: 30 AGI: 30 STR: 30
Your foes:
1. HP: 1 A wicked orc with a level 2 club.
2. HP: 1 A malicious hydra with 1 heads.
3. HP: 4 A wicked orc with a level 2 club.
4. HP: 3 A fierce BRIGAND.
5. HP: 8 A slime mold with a sliminess of 5.
6. HP: 8 A malicious hydra with 8 heads.
7. HP: 3 A slime mold with a sliminess of 3.
8. HP: 10 A slime mold with a sliminess of 4.
9. HP: 7 A malicious hydra with 7 heads.
10. HP: 2 A wicked orc with a level 1 club.
11. HP: 8 A malicious hydra with 8 heads.
12. HP: 7 A fierce BRIGAND.
Attack style: [s]tab, [d]ouble swing, [r]oundhouse: r
You chop off 1 of the hydra's heads!
You hit the BRIGAND for 1 health points!
The corpse of the fully decapitated and decapacitated hydra falls to the floor!
You hit the ORC for 1 health points!
The game uses several Common Lisp's advanced data types such as structs, hash tables and arrays. Believe it or not, but Lisp is not all about lists all the time.
Chapter 10, at this point, the real Lisp starts - we learn about the loop
and format
macros. Loop is an extremely useful macro that does anything you possibly could imagine. It's Turing-complete! Just look at this awesome snippet:
(defparameter salary (make-hash-table))
(setf (gethash 'Bob salary) 10000)
(setf (gethash 'Alice salary) 7500) ; *coolface*
(loop for person being each hash-key of salary
do (print person))
It's real code. No kidding. There's even a periodic table for this macro introduced at one point:
We then write a genetic algorithm using loop
. It evolves some animals in a dual environment leading to speciation:
> *animals*
(#S(ANIMAL :X 22 :Y 11 :ENERGY 111 :DIR 7 :GENES (12 7 8 4 2 3 8 5))
#S(ANIMAL :X 51 :Y 13 :ENERGY 137 :DIR 3 :GENES (3 9 12 23 4 4 11 1))
#S(ANIMAL :X 55 :Y 4 :ENERGY 94 :DIR 5 :GENES (13 7 7 1 3 1 8 6))
#S(ANIMAL :X 49 :Y 19 :ENERGY 133 :DIR 5 :GENES (3 10 13 23 3 5 11 1))
#S(ANIMAL :X 43 :Y 8 :ENERGY 103 :DIR 6 :GENES (5 10 10 21 2 3 10 1))
#S(ANIMAL :X 53 :Y 11 :ENERGY 98 :DIR 4 :GENES (4 8 13 23 3 3 10 1))
#S(ANIMAL :X 52 :Y 10 :ENERGY 167 :DIR 0 :GENES (3 10 11 23 2 5 11 2))
#S(ANIMAL :X 47 :Y 10 :ENERGY 95 :DIR 3 :GENES (5 9 12 23 3 3 10 1))
#S(ANIMAL :X 72 :Y 4 :ENERGY 172 :DIR 1 :GENES (14 9 7 2 2 3 8 6))
#S(ANIMAL :X 43 :Y 11 :ENERGY 107 :DIR 6 :GENES (3 10 12 23 4 4 11 1))
#S(ANIMAL :X 79 :Y 5 :ENERGY 79 :DIR 5 :GENES (13 8 5 2 1 2 9 6))
#S(ANIMAL :X 49 :Y 12 :ENERGY 144 :DIR 4 :GENES (3 10 12 22 3 4 10 1))
#S(ANIMAL :X 70 :Y 9 :ENERGY 74 :DIR 4 :GENES (13 7 7 1 2 1 9 6))
#S(ANIMAL :X 49 :Y 16 :ENERGY 88 :DIR 0 :GENES (5 8 11 22 3 3 10 2))
...)
After a few hundred thousand "days" we'll see two different genotypes easily.
Format is a swiss army knife of printing text. Coupling it with loop
is just... Just beautiful...
> (format t "|~{~<|~%|~,33:;~2d ~>~}|"
(loop for numbers below 100 collecting numbers))
| 0 1 2 3 4 5 6 7 8 9 |
|10 11 12 13 14 15 16 17 18 19 |
|20 21 22 23 24 25 26 27 28 29 |
|30 31 32 33 34 35 36 37 38 39 |
|40 41 42 43 44 45 46 47 48 49 |
|50 51 52 53 54 55 56 57 58 59 |
|60 61 62 63 64 65 66 67 68 69 |
|70 71 72 73 74 75 76 77 78 79 |
|80 81 82 83 84 85 86 87 88 89 |
|90 91 92 93 94 95 96 97 98 99 |
Don't expect me to explain this code. Go read a book.
Starting with chapter 13 we begin coding the ultimate mind-bending game - Dice of Doom. Chapter 13 builds a web server needed to run the game. Then we have a little jump into functional programming and lispy macros.
Next, we create a little DSL for handling HTML and SVG code needed for the game, it's preeeeetty.
The last chapters are truly diamonds. Lazy programming from chapter 18 chew onto my mind like it was bubble gum. My only concern is that such important and hard techniques were given so little attention by the author, but hell, it's a book for the newbies after all, you'll have to deal with it, Myself.
Lastly, the effects of our struggles in those last chapters - the fun, mind-opening game with all kinds of computer science under the hood:
IMO, the book is great. I had lots of fun reading it and I've learnt so much it blew my mind. If you're looking for a good book to start your Lisp-adventure you might want to try Land of Lisp.
2016-02-18: Adjusted some links & tags.