4/10/2012

Versions of LISP Why Study Lisp? • LISP is an acronym for LISt Processing language • It’s a simple, elegant yet powerful language • Lisp (b. 1958) is an old language with many variants • You will learn a lot about PLs from studying it – Fortran is only older language still in wide use • We’ll look at how to implement a Scheme Lisp and – Lisp is alive and well today interpreter in Scheme and Python • Most modern versions are based on • Scheme is one of the major variants • Many features, once unique to Lisp, are now in – We’ll use Scheme, not Lisp, in this class “mainstream” PLs: python, javascript, perl … Scheme I – Scheme is used for CS 101 in some universities • It will expand your notion of what a PL can be • The essentials haven’t changed much • Lisp is considered hip and esoteric among computer scientists

LISP Features

• S-expression as the universal data type – either at atom (e.g., number, symbol) or a list of atoms or sublists • Style – computation done by applying functions to arguments, functions are first class objects, minimal use of side-effects • Uniform Representation of Data & Code – (A B C D) can be interpreted as data (i.e., a list of four elements) or code (calling function ‘A’ to the three parameters B, C, and D) • Reliance on Recursion – iteration is provided too, but We lost the documentation on quantum mechanics. You'll have to decode recursion is considered more natural and elegant the regexes yourself. • Garbage Collection – frees programmer’s explicit memory management How Programming Language Fanboys See Each Others’ Languages

1 4/10/2012

What’s Functional Programming? Pure Lisp and Common Lisp Scheme

• The FP paradigm: computation is applying • Lisp has a small and elegant conceptual core • Scheme is a dialect of Lisp that is favored by functions to data that has not changed much in almost 50 years. people who teach and study programming languages • Imperative or procedural programming: a • McCarthy’s original Lisp paper defined all of program is a set of steps to be done in order Lisp using just seven primitive functions • Why? – ’ • FP eliminates or minimizes side effects and • Common Lisp, developed in the 1980s as an It s simpler and more elegant than Lisp mutable objects that create/modify state ANSI standard, is large (>800 builtin functions), –It’s pioneered many new programming language ideas (e.g., continuations, call/cc) –E.g., consider f1( f2(a), f2(b)) has most modern data-types, good program- –It’s influenced Lisp (e.g., lexical scoping of variables) • FP treats functions as objects that can stored, ming environments, and good compilers – ’ ’ passed as arguments, composed, etc. It s still evolving, so it s a good vehicle for new ideas

But I want to learn Lisp! But I want to learn ! DrScheme and MzScheme • We’ll use the PLT Scheme system developed by • Lisp is used in many practical systems, but • Clojure is a new Lisp dialect that compiles to a group of academics (Brown, Northeastern, Scheme is not the Java Virtual Machine Chicago, Utah) • Learning Scheme is a good introduction to Lisp • It offers advantages of both Lisp (dynamic • It’s most used for teaching introductory CS typing, functional programming, closures, etc.) • We can only give you a brief introduction to courses either language, and at the core, Scheme and and Java (multi-threading, fast execution) • MzScheme is the basic scheme engine and can Lisp are the same • We’ll look at Clojure briefly later be called from the command line and assumes • We’ll point out some differences along the way a terminal style interface • DrScheme is a graphical programming environ- ment for Scheme

2 4/10/2012

Mzscheme DrScheme on gl.umbc.edu

Informal Scheme/Lisp Syntax Hello World DrRacket • An atom can be an integer, or an identifier, or a string, or… (define (helloWorld) • A list is a left parenthesis, followed by ;; prints and returns the message. zero or more S-expressions, followed by a right parenthesis (printf "Hello World\n")) • An S-expression is an atom or a list • Example: () • (A (B 3) (C) ( ( ) ) )

3 4/10/2012

Square REPL What is evaluation? • We evaluate an expression producing a value • Lisp and Scheme are interactive and use what –Evaluating “2 + sqrt(100)” produces 12 > (define (square n) is known as the “read, eval, print loop” • Scheme has a set of rules specifying how to –While true ;; returns square of a numeric argument evaluate an s-expression •Read one expression from the open input (* n n)) • We will get to these very soon •Evaluate the expression –There are only a few rules > (square 10) •Print its returned value –Creating an interpreter for scheme means writing 100 • (define (repl) (print (eval (read))) (repl)) a program to • read scheme expressions, • apply the evaluation rules, and • print the result

Built-in Scheme Datatypes Lisp: T and NIL Scheme: #t, #f, and ‘() • Scheme cleaned this up a bit Basic Datatypes The Rest • Since 1958, Lisp has used two special symbols: • Booleans • Bytes & Byte Strings NIL and T • Scheme’s boolean datatype includes #t and #f • Keywords • Numbers • NIL is the name of the empty list, ( ) • #t is a special symbol that represents true • Characters • • #f represents false Strings • Vectors • As a boolean, NIL means “false” • Procedures • Hash Tables • T is usually used to mean “true,” but… • In practice, anything that’s not #f is true • Symbols • Boxes • …anything that isn’t NIL is “true” • Booleans evaluate to themselves • Pairs and Lists • Void and Undefined • NIL is both an atom and a list • Scheme represents empty lists as the literal ( ) which is also the value of the symbol null – it’s defined this way, so just accept it –(define null ‘())

4 4/10/2012

Numbers Strings Predicates

• Numbers evaluate to themselves • Strings are fixed length arrays of characters • A predicate (in any computer language) is a function that returns a boolean value • Scheme has a rich collection of number –"foo" types including the following • In Lisp and Scheme predicates returns –"foo bar\n" –Integers (42) either #f or often something else that –Floats (3.14) –"foo \"bar\"” might be useful as a true value –Rationals: (/ 1 3) => 1/3 • Strings are immutable – The member function returns true iff it’s –Complex numbers: (* 2+2i -2-2i) => 0-8i • Strings evaluate to themselves 1st argument is in the list that is it’s 2nd –Infinite precision integers: (expt 99 99) => 369…99 – (member 3 (list 1 2 3 4 5 6)) => (3 4 5 6)) (contains 198 digits!) –And more…

Function calls and data Simple evaluation rules Example • Numbers evaluate to themselves (define a 100) • define is a special form • A function call is written as a list > a that doesn’t follow the – the first element is the name of the function • #t and #f evaluate to themselves regular evaluation rules 100 – remaining elements are the arguments • Any other atoms (e.g., foo) represents • Scheme only has a few of > add1 these • Example: (F A B) variables and evaluate to their values # • Define doesn’t evaluate its – F A B • A list of n elements represents a function call calls function with arguments and first argument –e.g., (add1 a) > (add1 (add1 a)) • Data is written as atoms or lists • if is another special form –Evaluate each of the n elements (e.g., add1->a 102 • (F A B) Example: is a list of three elements procedure, a->100) > (if (> a 0) (+ a 1)(- a 1)) • What do you think is – special about if? Do you see a problem here? –Apply function to arguments and return value 103

5 4/10/2012

Quoting Symbols Basic Functions • Is (F A B) a call to F, or is it just data? • Symbols are atomic names • car returns the head of a list • All literal data must be quoted (atoms, too) > ’foo (car ‘(1 2 3)) => 1 • (QUOTE (F A B)) is the list (F A B) foo (first ‘(1 2 3)) => 1 ;; for people who don’t like car – QUOTE is not a function, but a special form > (symbol? ‘foo) • cdr returns the tail of a list – Arguments to a special form aren’t evaluated #t (cdr ‘(1 2 3)) => (2 3) or are evaluated in some special manner • Symbols are used as names of variables and (rest ‘(1 2 3)) => (2 3) ;; for people who don’t like cdr • '(F A B) is another way to quote data procedures • constructs a new listbeginning with it’s first arg ’ – There is just one single quote at the beginning –(define foo 100) and continuing with it s second (cons 1 ‘(2 3)) => (1 2 3) – It quotes one S-expression –(define (fact x) (if (= x 1) 1 (* x (fact (- x 1)))))

CAR, CDR and CONS More Basic Functions Comment on Names

• These names date back to 1958 • eq? compares two atoms for equality • Lisp used the convention (inconsistently) of ending predicate functions with a P –Before lower case characters were invented (eq? ‘foo ‘foo) => #t –E.g., MEMBERP, EVENP • CONS = CONStruct (eq? ‘foo ‘bar) => #f • Scheme uses the more sensible convention to • CAR and CDR were each implemented by a Note: eq? is just a pointer test, like Java’s ‘=‘ use ? at the end such functions single hardware instruction on the IBM 704 • equal? tests two list structures –e.g., eq?, even? –CAR: Contents of Address Register (equal? ‘(a b c) ‘(a b c)) =#t • –CDR: Contents of Decrement Register Even Scheme is not completely consistent in (equal? ‘(a b) ‘((a b))) => #f using this convention

Note: equal? compares two complex objects, –E.g., the test for list membership is member and not like a Java object’s equal method member?

6 4/10/2012

Other useful Functions More useful Functions More useful Functions

• list makes a list of its arguments • append concatenates two lists • (null? S) tests if S is the empty list – (list 'A '(B C) 'D) => (A (B C) D) – (append ‘(1 2) ‘(3 4)) => (1 2 3 4) – (null? ‘(1 2 3) => #f – (list (cdr '(A B)) 'C) => ((B) C) – (append '(A B) '((X) Y)) => (A B (X) Y) – (null? ‘()) => #t • Note that the parenthesized prefix notation makes it – (append ‘( ) ‘(1 2 3)) => (1 2 3) • (list? S) tests if S is a list easy to define functions that take a varying number of arguments. • append takes any number of arguments – (list? ‘(1 2 3)) =>#t – (list ‘A) => (A) – ‘ ‘ ‘ – (list? ‘3) => #f (append (1) (2 3) (4 5 6)) => (1 2 3 4 5 6) – (list) => ( ) – (append ‘(1 2)) => (1 2) • Lisp dialects use this flexibility a lot – (append) => null – (append null null null) => null

If then else Cond Cond Example • In addition to cond, Lisp and Scheme have an (cond ((not (number? x)) if special form that does much the same thing cond (short for conditional) is a special form (if (not (number? x)) that implements the if ... then ... elseif ... then ... 0) 0 • (if ) elseif ... then ... control structure ((< x 0) 0) (if ( foo ((< x 10) x) 0 – (if (< 4 2) ‘foo ‘bar) => bar (COND a clause (#t 10)) (if (< x 10) – (define (min x y) (if (< x y) x y)) (condition1 result1 ) x 10))) • In Lisp, the else clause is optional and defaults (condition2 result2 )

to null, but in Scheme it’s required . . . (#t resultN ) )

7 4/10/2012

Cond is superfluous, but loved Defining Functions Example: member • Any cond can be written using nested “if” (DEFINE (function_name . parameter_list) member is a built-in function, but here’s how expressions . function_body ) we’d define it • But once you get used to the full form, it’s very Examples: useful (define (member x lst) ;; Square a number ;; x is a top-level member of a list if it is the first –It subsumes the conditional and switch statements (define (square n) (* n n)) ;; element or if it is a member of the rest of the list • One example: (cond ((null? lst) #f) (cond ((test1 a) • Note: If no clause is ;; absolute difference between two numbers. ((equal? x (car lst)) list) selected, then cond (do1 a)(do2 a)(value1 a)) returns # (define (diff x y) (if (> x y) (- x y) (- y x))) (#t (member x (cdr lst))))) • It’s as if every cond ((test2 a))) had a final clause like (#t (void))

Example: member Append concatenate lists Example: define append • We can also define it using if: > (append '(1 2) '(a b c)) • (append ‘(1 2 3) ‘(a b)) => (1 2 3 a b) (1 2 a b c) (define (member x lst) • Lists are immutable • Here are two versions, using if and cond: (if (null> lst) > (append '(1 2) '()) • Append constructs new lists null (1 2) (define (append l1 l2) (if (equal x (car lst)) > (append '() '() '()) (if (null? l1) list () l2 (member x (cdr lst))))) > (append '(1 2 3)) (cons (car l1) (append (cdr l1) l2)))))

(1 2 3) • We could also define it using not, and & or (define (append l1 l2) (define (member x lst) > (append '(1 2) '(2 3) '(4 5)) (cond ((null? l1) l2) (and (not (null lst)) (1 2 2 3 4 5) (#t (cons (car l1) (append (cdr l1) l2))))) (or (equal x (car lst)) > (append) (member x (cdr lst))))) ()

8 4/10/2012

Example: SETS Example: SETS Example: SETS

• Implement sets and set operations: union, • Union is only slightly more complicated Intersection is also simple intersection, difference (define (set-union S1 S2)

• Represent a set as a list and implement the ;; returns the union of sets S1 and S2 (define (set-intersection S1 S2) operations to enforce uniqueness of membership (if (null? S1) S2 ;; returns the intersection of sets S1 and S2 • Here is set-add (add-set (car S1) (cond ((null? s1) nil) (define (set-add thing set) (set-union (cdr S1) S2))) ((member (car s1) s2) ;; returns a set formed by adding THING to set SET (set-intersection (cdr s1) s2)) (if (member thing set) set (cons thing set))) (#t (cons (car s1) (set-intersection (cdr s1) s2)))))

Reverse Programs on file Comments • In Lisp, a comment begins with a semicolon (;) • Reverse is another common operation on Lists • Use any text editor to create your program and continues to the end of the line • It reverses the “top-level” elements of a list • Save your program on a file with the extension – Speaking more carefully, it constructs a new list equal to it’s • Conventions for ;;; and ;; and ; .ss argument with the top level elements in reverse order. • Function document strings: • (reverse ‘(a b (c d) e)) => (e (c d) b a) • (Load “foo.ss”) loads foo.ss (defun square (x) (define (reverse L) • (load “foo.bar”) loads foo.bar (if (null? L) “(square x) returns x*x” • Each s-exprssion in the file is read and null (* x x)) (append (reverse (cdr L)) (list (car L)))) evaluated.

9