320 likes | 514 Views
Introduction to Scheme. Scheme. Meta-language for coding interpreters “clean” semantics Scheme = LISP + ALGOL simple uniform syntax; symbols and lists block structure; static scoping expression : evaluated for its value statement : evaluated for its effect Dynamic type checking
E N D
Introduction to Scheme L2Scm
Scheme • Meta-language for coding interpreters • “clean” semantics • Scheme = LISP + ALGOL • simple uniform syntax; symbols and lists • block structure; static scoping • expression : evaluated for its value • statement : evaluated for its effect • Dynamic type checking • flexible but inefficient (rapid prototyping) L2Scm
Expressions Literals Variables Procedure calls • Literals • numerals(2), strings(“abc”), boolean(#t), etc. • Variables • Identifier represents a variable. Variable reference denotes the value of its binding. x 5 ref L2Scm
Expressible vs Denotable values • Booleans are expressible in (early) FORTRAN, but not denotable. • Functions are denotable in Pascal/C, but are not expressible. • In (functional subset of) Scheme, both value spaces are identical. • In (full) Scheme, variable references (pointers) are denotable but not expressible. L2Scm
Scheme Identifiers • E.g., y,x5,+,two+two,zero?, etc • (Illegal) 5x,y)2,ab c, etc • Identifiers • reserved keywords • variables • pre-defined functions/constants • ordinary • functions = procedures L2Scm
Procedure Call (application) • (operator-expr operand-expr ...) • prefix expression (proc/op arg1 arg2 arg3 ...) • Order of evaluation of the sub-expressions is “explicitly” left unspecified by Scheme. • cf. C is silent about it. • cf. Java specifies a left to right processing. (+ x (p 2 3)) ((f 2 3) 5 6) L2Scm
Special Forms • Definition • (define <var> <expr>) > (define false #f) • Conditional • (if <test> <then> <else>) > (if (zero? 5) 0 #t) > (if '() 'emptyList'never) emptyList L2Scm
Data Types • values, operations, canonical representation • Type-checking • static : compile-time : efficient • dynamic : run-time : flexible • numbers: +, -, *, number?, =, etc. • booleans: #t, #f, boolean?, etc. • strings: string?, string->list, etc. L2Scm
Symbols • Identifiers treated as primitive values. • Distinct from identifiers that name variables in the program text. • Distinct from strings (sequence of characters). • Primitive operations quote symbol? • Facilitates meta-programming L2Scm
Lists • Ordered sequence of elements of arbitrary types (Heterogeneous) • operations • car, cdr, cons, null?, ... • list, append, ... • cadr, caadr, caddddr, … (cadar X) = (car (cdr (car X))) L2Scm
Pairs: Expression, Internal Representation and Print form (cons 'a 'b) (cons 'a (cons 'b '()) ) = (a . b) b a = (a . (b . ()) ) = (a b) () a b L2Scm
Domain Equations for defining S-Expressions and Lists Sexpr = Atoms U SexprXSexpr List = () U SexprXList L2Scm
Equivalence : Syntactic vs Semantic (eq? (cons 3 '()) (cons 3 '())) #f (define a (cons 3 '())) (define b (cons 3 '())) (eq? a b) #f (define c a) (eq? a c) #t L2Scm
Equivalence : Syntactic vs Semantic (equal? (cons 3 '()) (cons 3 '())) #t (equal? (make-vector 5 'a) (make-vector 5 'a)) #t (equal? (lambda(x)x) (lambda(y)y)) #f Formallyunspecified L2Scm
Vectors • Both records and arrays provide random access to components. However, records are heterogeneous, while arrays are homogeneous. • Vectors are heterogeneous structures that provide random access to components using a computable index. L2Scm
Constructors and accessors (define v (vector 1 (+ 1 2))) #(1 3) (vector-ref v 0) 1 (vector-length v) 2 • Index is 0-based. L2Scm
Procedures • In Scheme, procedures are first-class objects. That is, they may be (i) passed to procedures or (ii) returned from procedures or (iii) stored in a data structure. (procedure? append) #t (if (procedure? 3) car cdr) #<procedure> L2Scm
(( (if (procedure? procedure?) car cdr) (cons cdr car)) '(list append)) = ( (car (cons cdr car)) '(list append)) = (cdr '(list append)) = (append) L2Scm
Apply-function (apply cons '( x (y z))) = (cons 'x '(y z)) = (x y z) (apply f '(a1 a2 ... an)) = (f 'a1 'a2 ... 'an) (apply <func> <list-of-args>) L2Scm
Apply-function • Apply-function is not compelling if the function is of fixed arity and statically known. • Apply-function is indispensable if we wish to define variable arity function or the function will be computed dynamically. • Apply-function enables us to unify functions of different arities, and is an important component of an interpreter. L2Scm
(apply apply (list procedure? (list apply))) = (apply apply [proc?-fn [ apply-fn ] ] ) = (applyproc-fn [apply-fn] ) = (procedure? apply) = #t L2Scm
Anonymous Functions (lambda<formals-list> <body-expr>) E.g., ((lambda (n) (+ n 2)) (+ 1 4) ) = 7 • Evaluate actual argument expressions • Bind these values to corresponding formals in formals-list • Evaluate body expression (static scoping) L2Scm
Variable Arity Procedures (+ 1 2 3) (append '(1 (p q)) '() '(a b)) (list 1.2 3/4 5) (lambda<formal> <body>) • <formal> is bound to the list of actual argument values supplied in a call. L2Scm
(define mul (lambda x (if (null? x) 1 (* (car x) (applymul (cdrx)) ) )) ; 1 is identity w.r.t * ); assuming * is binary (mul 2 (+ 2 2) 5) L2Scm
Binding constructs in Scheme • define • binds value to a name. • l-function application • binds formal parameters to actual argument values. • let-constructs • introduces local bindings • let • let* • letrec L2Scm
let-construct ( let ( (var1 exp1) … (varn expn)) exp ) • exp1 to expn are evaluated in the surrounding context. • var1,…,varn are visible only in exp. • (let ( (x 2) (y 7) ) y) • 7 L2Scm
(let ( (x y) (y 7) ) y) • *error* “y” undefined • (define y 5) • (let ( (x y) (y 7) ) y) • 7 • (let ( (x y) (y 7) ) x) • 5 • (let ( (y 7) (x y) ) x) • 5 (not 7) L2Scm
(define y 5) • (let ( (y 7) (x y) ) x) • 5 • (let ( (y 7) ) (let ( (x y) ) x) ) • 7 • (let* ( (y 7) (x y) ) x) • 7 • let* abbreviates nested-lets. • Recursive and mutually recursive functions cannot be defined using let and let*. L2Scm
letrec-construct ( letrec ( (var1 exp1) … (varn expn)) exp ) • var1,…,varn are visible in exp1 to expn in addition to exp. • (letrec ( (x (lambda() y)) (y (lambda() x)) ) x ) L2Scm
letrec-construct • (letrec ( (f (lambda(n) (if (zero? n) 1 (f (- 1 n)) )) ) ) (f 5) ) • 1 • (letrec ( ( f (lambda () g) ) ( g 2) ) ( f ) ) • 2 L2Scm
boolean connectives (or test1 test2 … testn) (and test1 test2 … testn) • or and and are not Scheme procedures. • They use short circuit evaluation rather than traditional call-by-value. L2Scm
(cond (test1 exp1) (test2 exp2) … (testn expn) (else exp) ) (case key (keylist1 exp1) (keylist2 exp2) … (keylistn expn) (else exp) ) Branching constructs L2Scm