1 / 41

A Scheme Refresher (Functional Subset)

A Scheme Refresher (Functional Subset). Prabhaker Mateti. Overview of Scheme. Guy Steele and Gerald Sussman , MIT, 1975 Interpreted or compiled to machine code REPL (Read, Eval , Print, Loop) Like Python, MatLab Lisp syntax + lexical scope Lists are a fundamental built-in data type

eljah
Download Presentation

A Scheme Refresher (Functional Subset)

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. A Scheme Refresher(Functional Subset) Prabhaker Mateti

  2. SchemeRefresher Overview of Scheme • Guy Steele and Gerald Sussman, MIT, 1975 • Interpreted or compiled to machine code • REPL (Read, Eval, Print, Loop) • Like Python, MatLab • Lisp syntax + lexical scope • Lists are a fundamental built-in data type • Everything in prefix form: • (+ a b) instead of the infix a + b • Procedures represented by computable data structures

  3. SchemeRefresher Standards Docs for Scheme • Official Standard: The IEEE standard, 1178-1990 (R1995) standards.ieee.org/ • De Facto Std: R6RS (2007) Revised^6 Report on the Algorithmic Language Scheme www.r6rs.org/ • Older R5RS (1998) www.schemers.org/ Documents/Standards/R5RS/

  4. SchemeRefresher “Implementations” of Scheme • Many (~100 ?) that meet R5RS and R6RS. • On Linux, Windows, … • CS784 choice: http://racket-lang.org/ • Previously (< June 2010) known as PLT-Scheme • DrRacket, … • “Determine language from source” • EOPL3 • Many extensions

  5. SchemeRefresher Scheme Reading • Teach Yourself Scheme in Fixnum Days, DoraiSitaram, free download, www.ccs. neu.edu/home/dorai/ (For programmers.) • How to Design Programs, Felleisen, Bruce Findler, Flatt and Krishnamurthi, MIT Press, 2001. on-line www.htdp.org/ (For beginners.) • Scheme Wiki: community.schemewiki.org/

  6. SchemeRefresher Examples, Discussion, … • http://community.schemewiki.org/ • http://practical-scheme.net/ • http://www.schemers.org/ • http://lambda-the-ultimate.org/

  7. SchemeRefresher Examples-1 • (define x 10) • (define y 20) • (cons x y) • (cdr (cons x y)) • (symbol? '123) • (string->symbol "one, two")

  8. SchemeRefresher Examples-2 • (define list-length • (lambda (lst) • (if (null? lst) • 0 • (+ 1 (list-length (cdrlst)))))) • (define remove-first • (lambda (s los) • (if (null? los) • '() • (if (eqv? (car los) s) • (cdr los) • (cons (car los) (remove-first s (cdr los)))))))

  9. SchemeRefresher Example-3 EOPL3 p19 • (define occurs-free? • (lambda (var exp) • (cond • ((symbol? exp) (eqv? var exp)) • ((eqv? (car exp) 'lambda) • (and • (not (eqv? var (car (cadr exp)))) • (occurs-free? var (caddr exp)))) • (else • (or • (occurs-free? var (car exp)) • (occurs-free? var (cadr exp)))))))

  10. SchemeRefresher Example-4 EOPL3 p21 • (define subst-in-s-exp • (lambda (new old sexp) • (if (symbol? sexp) • (if (eqv? sexp old) new sexp) • (subst new old sexp)))) • (subst 'a 'b '((b c) (b () d)))  '((a c) (a () d))

  11. SchemeRefresher Example-5 EOPL3 p23 • (define number-elements-from • (lambda (lst n) • (if (null? lst) '() • (cons • (list n (car lst)) • (number-elements-from (cdrlst) (+ n 1)))))) • (define number-elements • (lambda (lst) • (number-elements-from lst 0))) • (number-elements '(a b c d e))  '((0 a) (1 b) (2 c) (3 d) (4 e))

  12. SchemeRefresher Built-In Data Types • Booleans: #t #f • Numbers • Characters • Strings (Unicode) • Bytes and Byte Strings • Symbols • Keywords • Pairs and Lists • Vectors • Hash Tables • Boxes (a container for a value) • Void and Undefined

  13. SchemeRefresher Four Types of Expressions • Constants: numbers, booleans. • Variables: names for values. Created using the special form define • Special forms have special rules for evaluation. • Cannot be redefined • 15 “magic words” and, begin, case, cond, define, do, if, lambda, let, let*, letrec, or,quasiquote, quote, set! • a special form is not a first-class object like a procedure • Combination: (operator operands) • "function calls" or • "procedure applications."

  14. SchemeRefresher Mantras of Scheme • Every expression has a value • except for • errors, • infinite loops, and • define special form • Computing the value of a combination • (operator operands …) • Compute all sub-expressions (in any order) • Apply the value of the first to the values of the rest • Applicative Order • The value of a lambda expression is a procedure

  15. SchemeRefresher Expressions • Literals • 2, 22/7, 3.1, "abc", #t • '(define x 12) • Variables • (define x 12) • x • Function Calls (aka Procedure Applications) • ( ‹id› ‹expr›* )

  16. SchemeRefresher Symbols • A symbol is an atomic value. • An expression that starts with ' and continues with an identifier. • Distinct from identifiers that name variables in the program text. • Distinct from strings (sequence of characters). • Examples • (symbol? 'blah)  #t • (string->symbol "one, two") |one, two|

  17. SchemeRefresher Pairs • cons procedure: • (cons 10 20) constructs a pair  (10 . 20) • (cons '() 'blah)  (() . blah) • (cons "blah" '())  ("blah") • (cons 'blah '())  (blah) • car procedure: first value • cdr procedure: second value • (cdr (cons 10 20))  20 • (pair?  '(1 2))   #t

  18. SchemeRefresher Lists • A list is recursively defined: • the constant null, or • a pair whose second value is a list. • Ordered sequence of elements of arbitrary types (Heterogeneous) • (list? (cons  alpha (cons 2  '())))   #t • (list? (cons  alpha 2))  #f

  19. SchemeRefresher Procedure Call/Application • ( ‹id› ‹expr›* ) • (proc exp1 exp2 exp3 ...) is in other languages proc(exp1 exp2 exp3 ...) • (equal?  6  "half dozen") • ((f #t 3) (string? s) 6) • Order of evaluation of the sub-expressions is deliberately left unspecified by Scheme. • cf. C is silent about it. • cf. Java specifies a left to right processing.

  20. SchemeRefresher procedure:  (eq? v1 v2) • Return #t  if v1 and v2 refer to the same object, #f  otherwise • (eq?  'yes  'yes)  #t • (eq? "yes" "yes" )  #f • (eq? (cons 1 2) (cons 1 2))  #f

  21. SchemeRefresher procedure:  (eqv? v1 v2) • Two values are eqv? if and only if they are eq?, • except for number and character data types • Examples • (eqv? (expt 2 100) (expt 2 100))  #t • (eq? (expt 2 100) (expt 2 100))  #f

  22. SchemeRefresher procedure:  (equal? v1 v2) • Two values are equal? if and only if they are eqv?, • except for strings, byte strings, numbers, pairs, mutable pairs, vectors, hash tables, and inspectable structures. • A rule of thumb is that objects are generally equal? if they print the same. • For precise details, see the docs of Scheme implementation you are using.

  23. SchemeRefresher eq? eqv? equal? • (equal? (expt 2 100) (expt 2 100))  #t • (eqv? (expt 2 100) (expt 2 100))  #t • (eq? (expt 2 100) (expt 2 100))  #f • (equal? (make-string 3 #\z) (make-string 3 #\z))  #t • (eqv? (make-string 3 #\z) (make-string 3 #\z))  #f • (eq? (make-string 3 #\z) (make-string 3 #\z))  #f

  24. SchemeRefresher procedure:  (vector v ...)  • Returns a new mutable “array” with the slots initialized to contain the given v … in order. Index starts at 0. • (vector 'a 20 "yes")  #(a 20 "yes") • (define v (vector 'a 20 "yes")) • (vector-ref v 2)  "yes“ • (vector-length v)  3 • (vector->list  v)     (a 20 "yes") • (list->vector '(a 20 "yes"))  #(a 20 "yes") • (build-vector  5  add1)   '#(1 2 3 4 5)

  25. SchemeRefresher Special Forms • A special form is an expression that follows special evaluation rules. • Lambda Expressions • Definitions • Assignments • Conditionals • Sequencing • Iteration

  26. SchemeRefresher (defineidexpr) • binds id to the result of expr • (define x 10) • (define v (vector 'a 20 "yes"))

  27. SchemeRefresher (define (headargs) body ...+) • binds  id, in the head, to a procedure. • (define (g x) (+ x 1)) • (define ((f x)) (+ x 20)) • ((f 10))  30 • (f 10)  #<procedure>

  28. SchemeRefresher (define fnid (lambda (id …) …) • (define (factx n) • (if (= n 0) 1 • (* n (facty (- n 1))))) • (factx 4)  24 • (define facty • (lambda (n) • (if (= n 0) 1 • (* n (facty (- n 1)))))) • (facty 4)  24 • (equal? factx facty)  #f • (eqv? factx facty)  #f • (eq? factx facty)  #f

  29. SchemeRefresher Procedures are first-class data • The definition of a procedure is stored as a data structure. • Can pass them as arguments to other procedures. • A procedure can create and return another procedure.

  30. SchemeRefresher define-syntax • (define-syntax idexpr) • (define-syntax foo • (syntax-rules () • ((_ a ...) • (printf"~a\n" (list a ...))))) • (foo 1 2 3 4)  (1 2 3 4) • (define-syntax (headargs) body ...+) • (define-syntax (bar syntax-object) • (syntax-case syntax-object () • ((_ a ...) • #'(printf "~a\n" (list a ...))))) • (bar 1 2 3 4)   (1 2 3 4)

  31. SchemeRefresher (define-syntax equal?? …) • (define-syntax equal?? • (syntax-rules () • ((_ test-exp correct-ans) • (let ((observed-ans test-exp)) • (if (not (equal? observed-ans correct-ans)) • (printf"~s returned ~s, should have returned ~s~%" • 'test-exp • observed-ans • correct-ans) • (printf"pmateti ~s OK~%" • 'test-exp))))))

  32. SchemeRefresher (applyprocv ... ) → any • Applies proc using the content of v... as the (by-position) arguments. • (apply +  1  2  '(3))   6 • (define compose  (lambda (f g)    (lambda args      (f (apply g args))))) • ((compose sqrt *)  12 75)    30

  33. SchemeRefresher (lambda  formals body)  • A lambda expression evaluates to an anonymous procedure. • (lambda (x) (+ 12 x))  #<procedure> • ((lambda (x) (+ 12 x)) 20)  32 • ((lambda (x y) (list y x)) 1 2)    '(2 1) • ((lambda (x [y 5]) (list y x)) 1 2)    '(2 1)

  34. SchemeRefresher (iftestthen-expelse-exp) • If test produces any value other than #f, then then-exp is the result. Otherwise, else-exp is the result. • (if  (> 3 2)  (- 3 2)  (+ 3 2))    1 • (if  'we-have-no-bananas "yes" "no") "yes"

  35. SchemeRefresher (cond clause1 clause2  ...) • clause ::= ( test expression ) • (cond • [(positive? -5) (error "doesn't get here")] • [(zero? -5) (error "doesn't get here, either")] • [(positive? 5) 'here])  here • (cond • [(member 2 '(1 2 3)) • => (lambda (x) (map - x))])  (-2 -3) • (cond [(member 2 '(1 2 3))])  (2 3)

  36. SchemeRefresher (case key clause1 clause2 ...) • clause ::= ( keyList expression ) • (case (- 7 5) • [(1 2 3) 'small] • [(10 11 12) 'big])  'small • (define (classify c) • (case (char-general-category c) • [(lllultln lo) "letter"] • [(ndnl no) "number"] • [else "other"])) • (classify #\A)  "letter " • (classify #\1)  "number" • (classify #\!)  "other"

  37. SchemeRefresher Local Binding: let • (let ([idval-expr] ...) body ...+) • Evaluates the val-exprs left-to-right, creates a new location for each id, and places the values into the locations. It then evaluates the bodys, in which the ids are bound. • (let ([x 5]) • (let ([x 2] • [y x]) • (list y x)))  '(5 2)

  38. SchemeRefresher Local Binding: let • (letproc-id ([idinit-expr] ...) body ...+) • Defines a local procedure. Evaluates the init-exprs; these become arguments to the proc. The ids must be distinct. • (let fac ([n 10]) • (if (zero? n) • 1 • (* n (fac (sub1 n)))))  3628800

  39. SchemeRefresher Local Binding: let* • (let* ([idval-expr] ...) body ...+) • Similar to let, but evaluates the val-exprs one by one, creating a location for each id as soon as the value is available. The ids are bound in the remainingval-exprs as well as the bodys, and the ids need not be distinct; later bindings shadow earlier bindings. • (let* ([x 1] • [y (+ x 1)]) • (list y x))  (2 1)

  40. SchemeRefresher Local Binding: letrec • (letrec ([idval-expr] ...) body ...+) • Similar to let, but the locations for all ids are created first and filled with #<undefined>, and all ids are bound in all val-exprs as well as the bodys. The ids must be distinct. • (letrec ((a b) (b 34) (c (+ b 5))) • (list a b c))  (#<undefined> 34 39) • (letrec ([is-even? (lambda (n) • (or (zero? n) • (is-odd? (sub1 n))))] • [is-odd? (lambda (n) • (and (not (zero? n)) • (is-even? (sub1 n))))]) • (is-odd? 11))  #t

  41. SchemeRefresher Comparison: let, let*, letrec • (let/let*/letrec ((v1 e1 ) (v2 e2 ) … (vn en )) body ) • let • no vi is created until all ei are evaluated. • none of ei can refer to any vi • let* • e1 is evaluated; v1 created, bound to e1; • e2 is evaluated; v2 created, bound to e2; …; • ej can refer to earlier vi, i < j. • letrec • vi are created with #undefined as their value. • with the above in effect, e1, …, en are evaluated l-to-r • each vi is now bound to ei

More Related