norvig / paip-lisp

Lisp code for the textbook "Paradigms of Artificial Intelligence Programming"
MIT License
7.18k stars 702 forks source link

"Running the Code" - for the ultra newbie #194

Open sarnobat opened 1 month ago

sarnobat commented 1 month ago

It wasn't obvious to me how to get anything working but I think I've figured it out. Here is my helloworld.sh quick start:

cd paip-lisp.git/lisp/

cat <<EOF > ./run.lisp

(declaim (sb-ext:muffle-conditions cl:style-warning))
(load "auxfns")
(load "examples")
(do-examples 1)

EOF

sbcl --non-interactive --load run.lisp

Do you think it warrants adding in the following section, or maybe enabling the Wiki for this repo? I'd be happy to add it to the wiki. https://github.com/norvig/paip-lisp/tree/main?tab=readme-ov-file#running-the-code

sarnobat commented 1 month ago

Expected output

This is SBCL 2.4.8, an implementation of ANSI Common Lisp.
More information about SBCL is available at <http://www.sbcl.org/>.

SBCL is free software, provided as is, with absolutely no warranty.
It is mostly in the public domain; some portions are provided under
BSD-style licenses.  See the CREDITS and COPYING files in the
distribution for more information.
STYLE-WARNING: using deprecated EVAL-WHEN situation names LOAD COMPILE EVAL
STYLE-WARNING: using deprecated EVAL-WHEN situation names COMPILE EVAL LOAD

Chapter  1. Introduction to Lisp
This chapter is for people with little or no experince in Lisp.
Intermediate or advanced readers can skim or skip this chapter.

Lisp expressions are in prefix notation: the operator first.
; page 4
> (+ 2 2)
4
; page 5
> (+ 1 2 3 4 5 6 7 8 9 10)
55
This is Lisp for (900 + 900 + 90 + 9) - (5000 + 500 + 50 + 5)
> (- (+ 9000 900 90 9) (+ 5000 500 50 5))
4444

Section 1.1 Symbolic Computation
This is an example of computation on lists:
; page 6
> (append '(pat kim) '(robin sandy))
(PAT KIM ROBIN SANDY)
The quote mark instructs Lisp to treat the list as data.
> '(pat kim)
(PAT KIM)
Let's look at some more list processing functions

Section 1.4 Lists
; page 10
> (setf p '(john q public))
; in: SETF P
;     (SETF P '(JOHN Q PUBLIC))
;
; caught WARNING:
;   undefined variable: COMMON-LISP-USER::P
;
; compilation unit finished
;   Undefined variable:
;     P
;   caught 1 WARNING condition
(JOHN Q PUBLIC)
> (first p)
JOHN
> (rest p)
(Q PUBLIC)
> (second p)
Q
> (third p)
PUBLIC
> (fourth p)
NIL
> (length p)
3
It is also possible to build up new lists
; page 11
> p
(JOHN Q PUBLIC)
> (cons 'mr p)
(MR JOHN Q PUBLIC)
> (cons (first p) (rest p))
(JOHN Q PUBLIC)
> (setf town (list 'anytown 'usa))
; in: SETF TOWN
;     (SETF TOWN (LIST 'ANYTOWN 'USA))
;
; caught WARNING:
;   undefined variable: COMMON-LISP-USER::TOWN
;
; compilation unit finished
;   Undefined variable:
;     TOWN
;   caught 1 WARNING condition
(ANYTOWN USA)
> (list p 'of town 'may 'have 'already 'won!)
((JOHN Q PUBLIC) OF (ANYTOWN USA) MAY HAVE ALREADY WON!)
> (append p '(of) town '(may have already won))
(JOHN Q PUBLIC OF ANYTOWN USA MAY HAVE ALREADY WON)
> p
(JOHN Q PUBLIC)

Section 1.5 Defining New Functions
The special form DEFUN stands for 'define function.'
It is used here to define a new function called last-name:
> (requires "intro")

; file: /Volumes/trash/trash/paip-lisp/lisp/intro.lisp
; in: SETF NAMES
;     (SETF NAMES
;             '((JOHN Q PUBLIC) (MALCOLM X) (ADMIRAL GRACE MURRAY HOPPER) (SPOT)
;               (ARISTOTLE) (A A MILNE) (Z Z TOP) (SIR LARRY OLIVIER)
;               (MISS SCARLET)))
;
; caught WARNING:
;   undefined variable: COMMON-LISP-USER::NAMES
;
; compilation unit finished
;   Undefined variable:
;     NAMES
;   caught 1 WARNING condition
(T)
; page 13
> (last-name p)
PUBLIC
> (last-name '(rex morgan md))
MD
> (last-name '(spot))
SPOT
> (last-name '(aristotle))
ARISTOTLE
We can also define the function first-name.
Even though the definition is trivial (it is the same as FIRST),
it is good practice to define first-name explicitly.
> p
(JOHN Q PUBLIC)
> (first-name p)
JOHN
> (first-name '(wilma flintstone))
WILMA
; page 14
> (setf names
          '((john q public) (malcolm x) (admiral grace murray hopper) (spot)
            (aristotle) (a a milne) (z z top) (sir larry olivier)
            (miss scarlet)))
; in: SETF NAMES
;     (SETF NAMES
;             '((JOHN Q PUBLIC) (MALCOLM X) (ADMIRAL GRACE MURRAY HOPPER) (SPOT)
;               (ARISTOTLE) (A A MILNE) (Z Z TOP) (SIR LARRY OLIVIER)
;               (MISS SCARLET)))
;
; caught WARNING:
;   undefined variable: COMMON-LISP-USER::NAMES
;
; compilation unit finished
;   Undefined variable:
;     NAMES
;   caught 1 WARNING condition
((JOHN Q PUBLIC) (MALCOLM X) (ADMIRAL GRACE MURRAY HOPPER) (SPOT) (ARISTOTLE)
 (A A MILNE) (Z Z TOP) (SIR LARRY OLIVIER) (MISS SCARLET))
> (first-name (first names))
JOHN

Section 1.6 Using Functions
Consider the following expression, which can be used to test LAST-NAME:
> (mapcar #'last-name names)
(PUBLIC X HOPPER SPOT ARISTOTLE MILNE TOP OLIVIER SCARLET)
The #' notation maps the name of a function to the function itself.
; page 15
> (mapcar #'- '(1 2 3 4))
(-1 -2 -3 -4)
> (mapcar #'+ '(1 2 3 4) '(10 20 30 40))
(11 22 33 44)
Now that we understand mapcar, let's use it to test FIRST-NAME:
> (mapcar #'first-name names)
(JOHN MALCOLM GRACE SPOT ARISTOTLE A Z LARRY SCARLET)
Suppose we wanted a version of FIRST-NAME that ignored titles like Miss:
> (defparameter *titles*
    '(mr mrs miss ms sir madam dr admiral major general)
    "A list of titles that can appear at the start of a name.")
*TITLES*
; page 16
> (defun first-name (name)
    "Select the first name from a name represented as a list."
    (if (member (first name) *titles*)
        (first-name (rest name))
        (first name)))
FIRST-NAME
> (mapcar #'first-name names)
(JOHN MALCOLM GRACE SPOT ARISTOTLE A Z LARRY SCARLET)
> (first-name '(madam major general paula jones))
PAULA
We can see how this works by tracing the execution of first-name:
> (trace first-name)
(FIRST-NAME)
; page 17
> (first-name '(john q public))
  0: (FIRST-NAME (JOHN Q PUBLIC))
  0: FIRST-NAME returned JOHN
JOHN
> (first-name '(madam major general paula jones))
  0: (FIRST-NAME (MADAM MAJOR GENERAL PAULA JONES))
    1: (FIRST-NAME (MAJOR GENERAL PAULA JONES))
      2: (FIRST-NAME (GENERAL PAULA JONES))
        3: (FIRST-NAME (PAULA JONES))
        3: FIRST-NAME returned PAULA
      2: FIRST-NAME returned PAULA
    1: FIRST-NAME returned PAULA
  0: FIRST-NAME returned PAULA
PAULA
> (untrace first-name)
T

Section 1.7 Higher-Order Functions
> (apply #'+ '(1 2 3 4))
10
> (apply #'append '((1 2 3) (a b c)))
(1 2 3 A B C)
Now we define a new function, self-and-double, and apply it to arguments.
> (defun self-and-double (x) (list x (+ x x)))
SELF-AND-DOUBLE
> (self-and-double 3)
(3 6)
> (apply #'self-and-double '(3))
(3 6)
Now let's return to the mapping functions:
> (mapcar #'self-and-double '(1 10 300))
((1 2) (10 20) (300 600))
> (mappend #'self-and-double '(1 10 300))
(1 2 10 20 300 600)
FUNCALL is similar to APPLY; it too takes a function as its
first argument and applies the function to a list of arguments,
but in the case of FUNCALL, the arguments are listed separately:
; page 20
> (funcall #'+ 2 3)
5
> (apply #'+ '(2 3))
5

Chapter  1. Introduction to Lisp done.