LISPnotes.pdf - Intro to Lisp LISP = LISt Processing Originated w McCarthy(1959 Implemented Church's lambda-calculus(recursive function theory

LISPnotes.pdf - Intro to Lisp LISP = LISt Processing...

This preview shows page 1 out of 139 pages.

You've reached the end of your free preview.

Want to read all 139 pages?

Unformatted text preview: Intro to Lisp  LISP = LISt Processing  Originated w/ McCarthy (1959)  Implemented Church's lambda-calculus (recursive function theory)  Manipulation of symbolic information  The initial Lisp was impractical (no iteration)  Many versions: Franz, Mac, Inter, Common (now the standard)  Guy Steele (1990): VERY useful reference. 12 Why Lisp? First, Lisp is much more exible than most languages. Users have such total control over what goes on that if they do not like the syntax of the language, they may change it to suit themselves. Suppose that you do not like the method for de ning programs in, say, Fortran, can you do anything about it? Short of switching to another language the answer is clearly no. Indeed the very idea seems absurd. But not to Lisp users. (Spector, 1995, PC.) ...The second reason for choosing lisp is the way in which Lisp in oriented toward the manipulation of symbols as opposed to, say, numbers.Norvig, (PoAIP, p. 25): What is it that sets Lisp apart from other languages? Why is it a good language for AI applications? There are at least seven important factors (from Norvig):  Built-in Support for Lists  Automatic Storage Management  Dynamic Typing  First-Class Functions  Uniform Syntax  Interactive Environment  Extensibility 13 Characteristics of Lisp  Interactive (somewhat super cially), Recursive, Very simple syntax (does automatic memory mgmt), variables not explicitly typed, may be interpreted or compiled.  Oriented toward: (1) non-numeric symbol manipulation; (2) structure building and modi cation.  Programs and data have same form  Lisp is the defacto standard language in AI 14 Some di erences between Lisp and Conventional Languages  Symbolic Processing  Structure Building and Modi cation  Programs and data have same form | Not only assigns values to symbols, but also permits dynamic construction and dissection of data structures | Can construct pgms on the y and even use them Additional di erences (noted in Norvig)  Many langs distinguish between stmts and expressions. | Statements have e ects (x = 2 + 2). | Expressions return values (2 + 2). In Lisp, ALL every expression returns a value; Some of those expressions also have side e ects.   Lexical rules are very simple. | Fewer punctuation chars, only parens and white space. x=2+2 is one single symbol; need to insert spaces: (x = 2 + 2) to separate the symbols. No need for semicolons as a delimiter. | Expressions delimited by parentheses. (Semi colons are for comments.) 15 Syntax of Lisp  Lisp is based on symbolic expressions or S-expressions: | An atom is an S-expression: (a) symbol (b) non-symbol (number, string, array); Examples: X, JOHN, SETQ, 7.2, "John" | A list is an S-expression: (S-expr S-expr ); Examples: (+ 1 2), (A (B C)) | Note: case insensitive ::: THAT'S ALL THERE IS TO THE SYNTAX!!! (except for dot notation and special characters | we'll get to special chars later). S-expression atom list (a b 3) symbol, number, string, character, array dotted pair (3 . a) (a . (b . (3 . nil))) Note: A list is a special case of a dotted pair where the last cell = NIL So, actually: an S-expression is either an atom or a dotted pair.  So (A) is an abbrev for (A . NIL).  Lists more commonly used than dotted pairs (convenient).  Note: (nil . nil) = (() . ()) = (() . nil) = (()) 6= nil 16 Basic Idea of Using Lisp  Sit in front of terminal  Enter Lisp (interactive)  Now you're in a read-eval-print loop  EVAL = give me an expression to evaluate; returns a value for an s-expr. (analogy: words in sentences vs. meaning)  Lisp reads the S-expr, evaluates the S-expr, then prints the result of the evaluation. 17 Atoms: Atoms and Lists atom turkey 1492 3turkeys *abc Lists: (atom) (atom turkey) (atom 1492 ocean blue) (an-atom (a list inside) and more atoms) (a list containing 5 atoms) (a list containing 8 atoms and a list (that contains 4 atoms)) (((a list containing a list containing a list of 11 atoms))) () (a list that ends with the null list ()) (not a list (not) a list )not again The Lisp evaluation rule: To evaluate an atom: If it is a numeric atom, the value is the number Else it must be a variable symbol; so the value is the value of the variable To evaluate a list: Assume the first item of the list is a function, and apply that function to the values of the remaining elements of the list. 18 Result of Evaluation: What is the value?  Number ! number itself (e.g., 7 ! 7)  String ! string itself (e.g., "hi" ! "hi")  Symbol ! value of symbol (e.g., X ! 5, if X has that value) | Symbols like variables in most langs, have a value associated with them. Special: T, NIL  List ! normally function evaluation | Normally write fcn as f(a,b, ,n) or in x a+b+ +n | In Lisp: put f inside left paren: (f a b n) ::: ::: :::  By convention, we assume that when given a list to evaluate, the rst atom has a value associated with it which is the body of a function. ([name of fn] [args]) | (+ 1 2) ! 3 | First elt of list is special: applied to rest of elts.  Evaluation of list: (1) eval each elt of list ( rst elt should return fcn body, rest return args); (2) apply fcn from 1st atom to rest.  Important Note: use ' to indicate \the S-expr stated" rather than the value of that S-expr. (e.g., 'X returns X, whereas X returns the value stored in X).  We'll run through what a sample session looks like in a minute. 19 Quote symbol Examples: | '2 ! 2 | 2!2 | 'John ! John | John ! ERROR: not a bound variable  Quote: use ' to indicate \the S-expression stated" rather than the value of that S-expression.  Serves to BLOCK evaluation of following expression, returning it literally.  Example: '(Pat Kim) ! (PAT KIM) If we just had (Pat Kim), it would consider Pat as a function and apply it to the value of the expression Kim. 20 Sample Session Fire up Lisp ... (+ 1 1) => 2 (* 23 13) => 299 (+ 1 (* 23 13)) => 300 (+ (* 2 2) (- 10 9)) => 5 (* 2 2 2 2) => 16 (sqrt (* 2 2 2 2)) => 4 (/ 25 5) => 5 (/ 38 4) => 19/2 "Hello, world!" => "Hello, world!" 'x => X x => Error: Unbound variable X ; Can abort out of this (abort current ; computation and return to read-eval-print loop) 21 Sample Session (continued) (setf x 5) => 5 ; Setf gives a value to a variable. ; effect and ALSO returns a value (setf y (reverse '(+ a b))) => (B A +) ; Reverse reverses a list. (setf l '(a b c d e)) => (A B C D E) ; l's value will now be a list. (length l) => 5 ; length --> gives length of a list (append l '(f)) => (A B C D E F) (length l) => 5 It has a side ; append --> merges to lists together ; (Note use of quote; l not quoted) ; Note that the length of l has not changed. (length (append '(pat Kim) (list '(John Q Public) 'Sandy))) => 4 ; Symbolic computations can be nested and ; mixed with numeric computations. ;;; Note: "list" puts elts into a list; doesn't merge them like "append" does. ;;; Note: Order of evaluation critical. (Eval args first.) ;;; Note: Parens MUST match --> source of bizarre errors if not. (car l) => A ; (first l) (cdr l) => (B C D E) ; (rest l) (first (rest l)) => B (cons 'q l) => (Q A B C D E) ; MAIN CONSTRUCTOR used in Lisp. 22 Understanding LISP: Lisp Data Structures  Best way to understand Lisp: Develop an intuitive understanding of its data structures (remember: pgms and data stored the same way).  First step: forget conventional pgming langs w/ which you are familiar (else confusion).  Three notations for Lisp data structures: (1) paren/list (printed) (2) dot (printed only if req; list notation is abbrev. for this); (3) pictorial or graphic or box/cell notation (never printed; shows what's going on inside).  We will return to relate these three.  Note: parenthesized notation = surface appearance (typing in/out at terminal) whereas pictorial notation = what's happening below the surface (i.e., how the computer is really doing it).  Need to be able to switch back and forth between these two easily. 24 Pictorial Notation: used to describe what goes on in Memory Note: combinations of CAR/CDR (up to 4), e.g., CADR = (CAR (CDR ..)) CONS Cell: A cell in memory (w/ left and right halves) A B A B (CONS ’A ’B) Also: FIRST, SECOND, ... TENTH (car,cadr,caddr, ...) A B CAR = A CDR = B These are off in memory Note: No SIDE EFFECT (important later) Difference Between: CONS, LIST, APPEND nil A B A (LIST ’A ’B) Adds one mem cell Adds one mem cell for each elt (A . B) A B (APPEND ’(A) ’(B)) B (CONS ’A ’B) All args must be lists! Last ptr of each elt points to next elt (A B) Note: can have (CONS ’A NIL)-> (A) nil (A B) Note: can have (LIST ’A) -> (A) same Suppose: X = (A) Y = (B) What is (CONS X Y)? What is (LIST X Y)? nil nil B A nil (CONS X Y) = ((A) B) A nil B nil (LIST X Y) = ((A) (B)) 25 Quote (continued from last time) The quote function inhibits the evaluation of its argument. It returns its argument literally. If the variable barney has the value 22, then: Evaluating barney yields 22 Evaluating (quote barney) yields barney Evaluating (car (quote (betty bambam))) yields betty The single quote mark (') (it is actually an apostrophe) can be used as an abbreviation for (quote ...). 2 Taking lists apart (continued from last time) The rst element of a list (be it an atom or another list) is the car of the list. (car '(alphabet soup)) => alphabet (car '((pickles beer) alphabet (soup))) =>(pickles beer) (car '(((miro (braque picasso))) leger)) =>((miro (braque picasso))) Everything except the rst element of a list is the cdr of the list. (cdr '(alphabet soup)) =>(soup) (cdr '((pickles beer) alphabet (soup))) => (alphabet (soup)) (cdr '(((miro (braque picasso))) leger)) =>(leger) Given a complex S-expression, you can obtain any of its component S-expressions through some combination of car and cdr. cadr is the car of the cdr: (cadr '(old mcdonald had a farm)) =>MCDONALD cdar is the cdr of the car: => (cdar '((do you)(really think so?))) (YOU) There are more variations, at least up to 4 a's or d's: (caddar '((deep (in the (nested) structure) lies truth))) => LIES 3 Taking lists apart (continued)  rst is a synonym for car  second is a synonym for cadr  third is a synonym for caddr .......  rest is a synonym for cdr (setf x '(eenie meenie minie moe)) => (EENIE MEENIE MINIE MOE) (first x) => EENIE (third x) => MINIE (rest x) => (MEENIE MINIE MOE) The null list: (cdr '(just-one-item)) => NIL '() => NIL 4 Putting lists together cons builds lists. (cons 'woof '(bow wow)) => (woof bow wow) (cons '(howl) '(at the moon)) => ((howl) at the moon) You can create any list with cons. (cons 'naked-atom '()) => (NAKED-ATOM) (cons 'naked-atom nil) =>(NAKED-ATOM) car, cdr, and cons are all non-destructive: (setf x '(the rain in spain)) =>(THE RAIN IN SPAIN) (car x) =>THE (cdr x) =>(RAIN IN SPAIN) (cons 'darn x) =>(DARN THE RAIN IN SPAIN) x =>(THE RAIN IN SPAIN) 5 Atoms and Dotted Pairs (continued from last time) You get errors if you try to take the car or cdr of a non-nil atom (car 'foo) => > Error: Can't take CAR of FOO. (cdr 'foo) => > Error: Can't take CDR of FOO. You get \funny dots" if you try to cons things onto non-lists (cons 'a 'b) => (A . B) Although \dotted pairs" have their uses, we mostly won't use them beyond the rst problem set. That means that you're probably doing something wrong if you get dots in your answers. 6 Generalized assignment (setf)  Earlier dialects: not available (used something called setq) setq assigns a value to a symbol (setq my-favorite-list '(fe fi fo fum)) => (fe fi fo fum) my-favorite-list => (fe fi fo fum)    setq is an exception to the normal evaluation rule; the rst argument is not evaluated. (q = quote) But setq cannot be used for generalized vars ! rplaced with setf. A generalized var refers to any place a ptr may be stored. "A has the value (3)" A 3 A    nil "A has the value 3" 3 Other places a ptr can be stored? car/cdr of cons cell Asst ! replacing one ptr with another (setf A ’(4)) (setf (car A) 4) A A 3 nil 3 nil "A has the value (4)" 4 4 nil Can use an accessor such as CAR, CDR, FIRST, etc. 7 More about setting variables  Lisp doesn't need type declaration because everything is a pointer (i.e., the values of symbols have types associated w/ them; atoms, lists, integers, etc.)  Typical memory org: Lisp system Cons nodes Strings Integers Symbols  Symbol: \indivisible atoms" actually have parts. Typically each atom is a table: X Name Value Function "X" (string -- not same as symbol) (if nothing here, atom is unbound) (function definition) Prop List Package  What does setf do? (setf x 7) Changes value slot of X's table to point to 7  Can access slots: (symbol-name 'reverse) ! "reverse" (symbol-function 'reverse) ! #<compiled-fn reverse> 8 Eval    EVAL = explicit evaluation. | (+ 3 5) ! evaluated w/o user explicitly asking for eval'n | EVAL is applied by the system (LISP = read-eval-print loop) | Explicit eval = extra evaluation | Sort of the opposite of quote. Examples: Suppose (setf x 'y), (setf y 'z) |x!y | (eval x) ! z | (eval 'x) ! y What is eval useful for? { retrieving value of symbol whose name is not known until runtime: (setf a 3) (eval 'a) ! 3 NOT REALLY A GOOD IDEA: Can use symbol-value; no reason to use eval. { evaluating form that is constructed at runtime:   (eval (list <fn> args ...)) (eval (list 'setf arg1 arg2)) (where arg1='x and arg2=3) evaluates (setf x 3) Note: basically building a (trivial) function and running it on the y; in the \old" days, this was considered the \key" to Lisp's exibility NOT REALLY A GOOD IDEA: Use symbol-value again: (setf (symbol-value 'arg1) (symbol-value 'arg2)) But might be cases where don't have enough info; if the list '(setf x 3) is passed into a fn to be evaluated, then probably best thing to do is eval: (1) can't use funcall/apply cause setf is macro; (2) don't know enough about the args w/o extensive testing to be able to use (or in this case not use) symbol-value. But in general, we no longer need eval, really. Some people (e.g., Norvig) say you're doing something wrong if you use it. But you should know it is there, and that sometimes there's no choice. 9 Comments Common Lisp provides 2 ways to comment your code: #| this could be a really big comment |# (car '(a b c)) ; this is a comment => A (cdr '(here is #| a list with a comment |# huh?)) => (IS HUH?) 10 Commonlisp Forms  Function: (+ 3 5) Can test with (functionp x) Note: Arguments to a function can themselves be a function (nesting): (+ (* 3 5) 5)  Macro: (setf x 1) Can test with (macro-function x) Note: violates eval'n rule: don't eval x, only eval 1.  Special form: (if test a b) Can test with (special-form x) Two others we'll learn about later: let, let*  We'll initially concentrate on this rst type of form (the function).  We'll talk about macros in detail later. 11 Predicates  A Predicate is a function that is called to answer a yes-or-no question.  A predicate returns boolean truth values (T = true / NIL = false)  T/NIL special symbols; prede ned to have self as value. (The atom t means true, and evaluates to itself. The atom NIL means false, and evaluates to itself.)  Predicates may return t for true, or they may return any other non-nil value.  Predicates in Common Lisp take various forms, but often end with p. 12 Predicates (continued) 1. <, > (numeric functions) 2. macros may serve as predicates: (AND t nil), (OR t nil) Note: implementation of these allows them to be control constructs (and nil t t t) | stop at rst nil, (or t nil nil nil) | stop at rst t. Note: Generally considered poor style to use and/or for side e ect: (or (setf x (<fn> ...)) (setf x 'fail)) | should use to test logical condition. 3. (atom x), (null x), (not x), (listp x), (consp x), (numberp x), (stringp x), (arrayp x), (vectorp x), (characterp x), (member x y :test <test>) Note: All conses are lists, but converse not true: (consp nil) ! nil Note: Member doesn't just return t or nil! 13 Sample Session: Predicates (null 'fig-tree) => NIL (null '(bismark)) => NIL (null '()) => T (null ()) => T (null nil) => T (atom 'eggplant) => T (atom 99) => T (atom 3.141592) => T (atom '(floating point number)) => NIL (atom nil) => T (atom ()) => T (listp 'apple) => NIL (listp '(fish and telephones)) => T (listp 33) => NIL (listp nil) => T (setq lucky-number 23) => 23 (evenp lucky-number) => NIL (not (evenp lucky-number)) => T 14 Sample Session: Predicates Taking More Than One Argument (> 22 11) => T (> 11 22) => NIL (<= 23 23) => T (>= 23 23) => T (>= 100 1) => T (>= 1 100) => NIL (< 1 2 3 4 5 6 7 8 9) => T (< 1 2 3 4 5 6 7 8 7) => NIL 15 Equality Common lisp has a variety of Equality Predicates, of which equalp is the most general (see CLtL2 p. 103). And, or, and not allow the combination of predicates into complex predicates.  EQ and EQUAL { two most commonly used.  EQ tests whether args eval to exact same Lisp obj  EQUAL compares any two s-expressions (lists, strings, etc.)  = used for numbers (must be same number)  EQL: EQ or =  EQUALP | same as EQUAL but disregards case (for strings).  Others: tree-equal, char-equal, string-equal, string=, char= Note: these are all a special case of equal; Tree-equal tests whether two trees are equal except that the leaf nodes are expected to be symbol atoms (not, eg., strings) Note: can specify :TEST such as string=. x 'x '0 '(x) '"xy" '"Xy" '0 '0 y 'x '0 '(x) '"xy" '"xY" '0.0 '1 = err T err err err nil nil eq T ? nil nil nil nil nil eql T T nil nil nil nil nil equal T T T T nil nil nil equalp T T T T T T nil 16 Equality: Need to think about what's happening in memory So far: S-exprs drawn so that symbol referenced more than once drawn multiple times in memory What’s really going on? nil nil A B A B EQ A  In reality, both pointers to A point to the SAME symbol (i.e., the same exact mem location)  EQ: tests for memory location exactly | therefore, atoms only!  LISP automatically makes sure that all refs to some symbol actually point to the UNIQUE point in mem that the symbol happens to be stored physically. This way, any info stored w/ it (e.g., its value) is accessible from every ref.  Anytime LISP sees new symbol, it adds the symbol to its storehouse of known atoms. 17 Sample Session: Equality (equalp 'foot 'foot) => T (equalp 'nose 'ear) => NIL (equalp (+ 22 33 44) (* 33 3)) => T (setq long-list '(1 2 3 4 can I show you out the door?)) => (1 2 3 4 CAN I SHOW YOU OUT THE DOOR?) (setq lucky-number 23) => 23 (or (equalp lucky-number (car long-list)) (equalp (* (car long-list) 2) (car (cdr long-list)))) => T (and (equalp lucky-number (car long-list)) (equalp (* (car long-list) 2) (car (cdr long-list)))) => NIL 18 Conditionals     IF: special form (if (= x 21) (print 'blackjack)) WHEN: macro; has same form: (when (= x 21) (print 'blackjack)) Di erence: IF has else part; should use if only when there is an else part ! (if z 'not-empty 'empty) [z is a boolean] | IF: most useful for 2-way fork where then/else are each 1 expr | WHEN: used for 1-way fork (then may be more than 1 expr) What if more than 2-way fork? Use COND! (cond (C1 ( E11 E21...)) (C2 (E21 E22 ...)) ... (Cn (En1 En2 ...))) (if C E1 E2) C Y E1 E2     E11 E12... C1 Y E11 E12... Cn Y N (when C E1 E2) C Y C1 N Y E1 E2... En1 En2... COND: Powerful multiway branching construct; Arbitrary number of args (called clauses) Note: general form ! can have more than one action. Each clause is a list of s-exprs Example: (Ci Ei1 Ei2 ... Eim). Value returned : Eim, where Ci is rst non-nil condition (No more Ci or Ei's are evaluated.) Convention for our class: last Ci is the constant T (guaranteed to be non-nil). 19 Conditionals: Examples  (cond (x 'b) (y 'c) (t 'd)) What if x = 'a? (then returns b) What if x = nil, y = t? (then returns c) What if x = nil y = nil? (then returns d)  (cond (x (setf x 1) (+ x 2)) (y (setf y 2) (+ y 2)) (t (setf x 0) (setf y 0))) What if x = t? (then returns 3) What is x? (x = 1) What if x = nil, y = t? (then returns 4) What are x/y? (nil/2) What if x = nil y = nil? (then returns 0) What are x/y? (...
View Full Document

  • Spring '16
  • PR. LANGAT
  • Recursion, Nil, Lisp programming language

  • Left Quote Icon

    Student Picture

  • Left Quote Icon

    Student Picture

  • Left Quote Icon

    Student Picture