Lecture - 15: Scheme

Introduction to Scheme
Scheme
COP-4020
1
Scheme
• Meta-language for coding interpreters
– “clean” semantics
• Scheme = LISP + ALGOL
–
–
–
–
simple uniform syntax; symbols and lists
block structure; static scoping
statement : evaluated for its effect
expression : evaluated for its value
• Dynamic type checking
– flexible but inefficient (rapid prototyping)
Scheme
COP-4020
2
Expressions
Literals
• Literals
Variables
Procedure calls
• numerals(2), strings(“abc”), boolean(#t), etc.
• Variables
• Identifier represents a variable. Variable reference
denotes the value of its binding.
x
5
ref
Scheme
COP-4020
3
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
Scheme
COP-4020
4
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.
(+
((f
Scheme
x
2
(p
3)
2
5
3))
6)
COP-4020
5
Special Forms
• Definition
• (define <var>
<expr>)
• Conditional
• (if <test>
<then>
<else>)
(define false #f)
(if
(zero? 5)
Scheme
COP-4020
0
#t)
6
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
Scheme
COP-4020
7
Symbols
• Identifiers treated as primitive values.
Manipulated at run-time.
– Distinct from identifiers that name variables in
the program text.
– Distinct from strings (sequence of characters).
• Meta-programming
quote
symbol?
Scheme
COP-4020
8
Lists
• Ordered sequence of elements of arbitrary
types (Heterogeneous)
• operations
– car, cdr, cons, null?, ...
– list, append, ...
– first, second, ..., ninth
Scheme
COP-4020
9
Pairs
(cons ’a ’b)
b
a
(cons
’a
a
Scheme
(cons
’b
b
COP-4020
nil) )
nil
()
10
Equivalence Test
(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
Scheme
COP-4020
11
Vectors
• Both records and arrays provide random
access to components. However, records are
heterogeneous, while arrays are
homogenoeus.
• Vectors are heterogeneous structures that
provide random access to components using
a computable index.
Scheme
COP-4020
12
• Constructors and accessors
(define v (vector 1 (+ 1 2)))
#(1 3)
(vector-ref
v 0)
1
(vector-length
v)
2
• Index is 0-based.
Scheme
COP-4020
13
Procedures
• In Scheme, procedures are first-class
objects. That is, they may be passed to or
returned from procedures or stored in a data
structure.
(if (procedure? 3) car cdr)
#<procedure>
(procedure?
append)
#t
Scheme
COP-4020
14
( (if (procedure? procedure?)
car
cdr)
(cons cdr car))
’(list append))
=
( (car (cons cdr car))
’(list append))
=
(cdr ’(list append))
=
(append)
Scheme
COP-4020
15
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>)
Scheme
COP-4020
16
(apply
apply
(list procedure?
(list apply)))
= (apply apply
[ proc-fn [ apply-fn ] ]
)
= (apply proc-fn
[apply-fn] )
= #t
Scheme
COP-4020
17
Anonymous Fucntions
(lambda <formals> <body-expr>)
E.g.,
( (lambda (n) (+ n 2)) 5) = 7
• Evaluate actual argument expressions
• Bind these values to formals
• Evaluate body expression (static scoping)
Scheme
COP-4020
18
Variable Arity Procedures
(+ 1 2 3)
(append ’(1 (p q)) () ’(a b c))
(list
1 2 3 4 5)
(lambda <formal> <body>)
• <formal> is bound to the list of actual
argument values supplied in a call.
Scheme
COP-4020
19
(define mul
(lambda x
(if (null? x)
1
(* (car x)
(apply mul
(cdr x))
)
)) ; 1 is identity w.r.t *
)
; assuming * is binary
(mul 1 (+ 2 3) 5)
Scheme
COP-4020
20
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
Scheme
COP-4020
21
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
Scheme
COP-4020
22
> (let ( (x y) (y 7) ) y)
> *error* “y” undefined
>
>
>
>
>
>
>
(define y
(let ( (x
7
(let ( (x
5
(let ( (y
5 (not 7)
Scheme
5)
y) (y 7) ) y)
y) (y 7) ) x)
7) (x y) ) x)
COP-4020
23
>
>
>
>
(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*.
Scheme
COP-4020
24
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
)
Scheme
COP-4020
25
letrec-construct
> (letrec ( (f
(lambda(n)
(- 1 n)) )) ) )
(if
(zero? n) 1
(f
(f
5)
)
> 1
> (letrec (
( f
(lambda () g)
( g
)
2 )
)
( f )
)
> 2
Scheme
COP-4020
26
boolean connectives
(or test1 test2
(and test1 test2
…
…
testn)
testn)
• or and and are not Scheme procedures.
• They use short circuit evaluation rather than
traditional call-by-value.
Scheme
COP-4020
27
Branching constructs
(cond
(test1
(test2
…
(testn
(else
)
Scheme
(case
key
exp1)
(keylist1
exp1)
exp2)
(keylist2
exp2)
…
expn)
(keylistn
expn)
exp)
(else
exp)
)
COP-4020
28