Plt-2002-2 6/7/2014 3.2-1 Data Abstraction Programming Language Essentials 2nd edition Chapter 2.2...
-
Upload
nataly-hunting -
Category
Documents
-
view
215 -
download
1
Transcript of Plt-2002-2 6/7/2014 3.2-1 Data Abstraction Programming Language Essentials 2nd edition Chapter 2.2...
plt-2002-2 04/10/23 3.2-1
Data Abstraction
Programming Language Essentials
2nd edition
Chapter 2.2 An Abstraction for Inductive Data Types
plt-2002-2 04/10/23 3.2-2
define-datatype bintreebintree: 'Number' | '(' 'Symbol' bintree bintree ')'
(define-datatype bintree bintree? (leaf-node (datum number?)) (interior-node (key symbol?) (left bintree?) (right bintree?)))
predicateconstructors
plt-2002-2 04/10/23 3.2-3
Scheme 48 Imagehttp://www.cs.indiana.edu/eopl/code.zip
$ scheme48> ,open srfi-23> ,load r5rs.scm> ,load sllgen.scmsllgen.scm 2000-09-25 11:48> ,load define-datatype.scmdefine-datatype.scm version J3 2002-01-02> ,dump eopl.image EOPLWriting eopl.image
$ scheme48 -i eopl.image>
plt-2002-2 04/10/23 3.2-4
Terminology
aggregate: contains values of other types, e.g., array or record with named fields.
union: values are of other types.
discriminated union: value contains explanatory tag and value of union's types.
variant record: discriminated union of record types.
Scheme values are discriminated union of primitive types.
Inductively defined data types can be represented as variant records.
plt-2002-2 04/10/23 3.2-5
define-datatype
Scheme extension
(define-datatype type-name type-predicate-name
(variant-name
(field-name predicate) …
) …
)
creates variant record type with one or more variants with zero or more fields
type and variant names must be globally unique
must be used at top level
plt-2002-2 04/10/23 3.2-6
define-datatype (2)
creates type-predicate-name predicate with one argument
creates variant-name constructor with one argument per field
(define-datatype bintree bintree?
(leaf-node
(datum number?))
(interior-node
(key symbol?)
(left bintree?)
(right bintree?)))
plt-2002-2 04/10/23 3.2-7
define-datatype (3)(leaf-node 29)
(bintree? (leaf-node 29))
(interior-node 'foo (leaf-node 1) (leaf-node 2))
(bintree? (interior-node 'foo (leaf-node 1) (leaf-node 2)) )
plt-2002-2 04/10/23 3.2-8
s-lists-list: '(' symbol-expression* ')'symbol-expression: 'Symbol' | s-list
(define-datatype s-list s-list? (empty-s-list) (non-empty-s-list (first symbol-exp?) (rest s-list?)))
(define-datatype symbol-exp symbol-exp? (symbol-symbol-exp (data symbol?)) (s-list-symbol-exp (data s-list?)))
plt-2002-2 04/10/23 3.2-9
s-list based on Scheme lists(define-datatype s-list s-list?
(an-s-list
(data (list-of symbol-exp?))))
(define list-of ; returns predicate for list
(lambda (pred)
(lambda (val)
(or (null? val)
(and (pair? val)
(pred (car val))
((list-of pred) (cdr val))
) ) ) ) )
plt-2002-2 04/10/23 3.2-10
Examples(s-list? (empty-s-list))
(s-list?
(non-empty-s-list (symbol-symbol-exp 'a)
(empty-s-list)
) )
(s-list? (an-s-list '()))
(s-list?
(an-s-list (list (symbol-symbol-exp 'a)))
)
(s-list?
(an-s-list (cons (symbol-symbol-exp 'a)
'()
) ) )
plt-2002-2 04/10/23 3.2-11
Sum of leaves of bintree(define leaf-sum (lambda (tree) (cases bintree tree (leaf-node (datum) datum) (interior-node (key left right) (+ (leaf-sum left) (leaf-sum right))) ) ) )
(leaf-sum (interior-node 'foo (leaf-node 1) (leaf-node 2)) )
plt-2002-2 04/10/23 3.2-12
cases(cases type-name expression
(variant-name (field-name …) body)
…
(else body)
)
value of expression must be of type-name
variant selects appropriate variant-name
each field value is bound to field-name and body is executed
without else, all variants must be specified
plt-2002-2 04/10/23 3.2-13
Lambda Calculus Representationexpr: 'Symbol' | '(' 'lambda' '(' 'Symbol' ')' expr ')' | '(' expr expr ')'
(define-datatype expression expression? (var-exp (id symbol?)) (lambda-exp (id symbol?) (body expression?)) (app-exp (rator expression?) (rand expression?)))
plt-2002-2 04/10/23 3.2-14
Examples(expression? (var-exp 'x))(expression? (lambda-exp 'x (var-exp 'x)))(expression? (app-exp (var-exp 'f) (var-exp 'x)))(expression? (lambda-exp 'x (app-exp (var-exp 'f) (var-exp 'x))) )
plt-2002-2 04/10/23 3.2-15
Syntax and Representation
BNF specifies concrete syntax, external representation
define-datatype defines building blocks for abstract syntax, internal representation
expr: 'Symbol'
var-exp (id)
| '(' 'lambda' '(' 'Symbol' ')' expr ')'
lambda-exp (id body)
| '(' expr expr ')'
app-exp (rator rand)
plt-2002-2 04/10/23 3.2-16
Abstract Syntax Tree lambda-exp
id body
x app-exp
rator rand
var-exp app-exp
id rator rand
f var-exp var-exp
id id
f x
(lambda (x) (f (f x)))
plt-2002-2 04/10/23 3.2-17
Programming without an AST(define occurs-free?
(lambda (var exp)
(cond
((symbol? exp) (eqv? var exp))
((eqv? (car exp) 'lambda)
(and (not (eqv? (caadr exp) var))
(occurs-free? var (caddr exp))))
(else (or (occurs-free? var (car exp))
(occurs-free? var (cadr exp))
) ) ) ) )
plagued by c*r references
plt-2002-2 04/10/23 3.2-18
Programming with an AST(define occurs-free? (lambda (var exp) (cases expression exp (var-exp (id) (eqv? id var)) (lambda-exp (id body) (and (not (eqv? id var)) (occurs-free? var body))) (app-exp (rator rand) (or (occurs-free? var rator) (occurs-free? var rand)) ) ) ) )
plt-2002-2 04/10/23 3.2-19
Example(occurs-free?
'f
(lambda-exp 'x
(app-exp (var-exp 'f) (var-exp 'x))
) )
plt-2002-2 04/10/23 3.2-20
unparse-expression(define unparse-expression (lambda (exp) (cases expression exp (var-exp (id) id) (lambda-exp (id body) (list 'lambda (list id) (unparse-expression body) ) ) (app-exp (rator rand) (list (unparse-expression rator) (unparse-expression rand)) ) ) ) )
plt-2002-2 04/10/23 3.2-21
Example(unparse-expression
(lambda-exp 'x
(app-exp (var-exp 'f) (var-exp 'x))
) )
plt-2002-2 04/10/23 3.2-22
parse-expression(define parse-expression
(lambda (datum)
(cond
((symbol? datum) (var-exp datum))
((pair? datum)
(if (eqv? (car datum) 'lambda)
(lambda-exp (caadr datum)
(parse-expression (caddr datum)))
(app-exp
(parse-expression (car datum))
(parse-expression (cadr datum))
) ) )
(else (error 'parse-expression datum))
) ) )
plt-2002-2 04/10/23 3.2-23
Example(unparse-expression
(parse-expression
'(lambda (x) (f x))
)
)