Data Abstraction. An Abstraction for Inductive Data Types. Philip W. L. Fong.

Similar documents
A Brief Introduction to Scheme (II)

CS 342 Lecture 8 Data Abstraction By: Hridesh Rajan

Lecture 09: Data Abstraction ++ Parsing is the process of translating a sequence of characters (a string) into an abstract syntax tree.

Lecture08: Scope and Lexical Address

Comp 411 Principles of Programming Languages Lecture 7 Meta-interpreters. Corky Cartwright January 26, 2018

6.184 Lecture 4. Interpretation. Tweaked by Ben Vandiver Compiled by Mike Phillips Original material by Eric Grimson

Lecture 12: Conditional Expressions and Local Binding

6.037 Lecture 4. Interpretation. What is an interpreter? Why do we need an interpreter? Stages of an interpreter. Role of each part of the interpreter

CSE 413 Languages & Implementation. Hal Perkins Winter 2019 Structs, Implementing Languages (credits: Dan Grossman, CSE 341)

Procedures. EOPL3: Section 3.3 PROC and App B: SLLGEN

Essentials of Programming Languages Language

Essentials of Programming Languages Language

Functional Programming. Pure Functional Programming

C311 Lab #3 Representation Independence: Representation Independent Interpreters

CS152: Programming Languages. Lecture 2 Syntax. Dan Grossman Spring 2011

Lecture 3: Expressions

Trees. CS 5010 Program Design Paradigms Bootcamp Lesson 5.1

Why do we need an interpreter? SICP Interpretation part 1. Role of each part of the interpreter. 1. Arithmetic calculator.

Type Inference and Type Habitation (5/10/2004)

CSE341: Programming Languages Lecture 17 Implementing Languages Including Closures. Dan Grossman Autumn 2018

Using Symbols in Expressions (1) evaluate sub-expressions... Number. ( ) machine code to add

CSCI-GA Scripting Languages

Streams, Delayed Evaluation and a Normal Order Interpreter. CS 550 Programming Languages Jeremy Johnson

Syntactic Sugar: Using the Metacircular Evaluator to Implement the Language You Want

CS 342 Lecture 7 Syntax Abstraction By: Hridesh Rajan

Comp 311: Sample Midterm Examination

Introduction to Scheme

CS152: Programming Languages. Lecture 11 STLC Extensions and Related Topics. Dan Grossman Spring 2011

Lecture 2: Data Types and their Representations; Syntax: Scanning and Parsing

A Brief Introduction to Scheme (I)

Lexical and Syntax Analysis. Top-Down Parsing

6.037 Lecture 7B. Scheme Variants Normal Order Lazy Evaluation Streams

CSE413: Programming Languages and Implementation Racket structs Implementing languages with interpreters Implementing closures

Programming Languages

LECTURE 3. Compiler Phases

CSc 520 Principles of Programming Languages

Static Semantics. Winter /3/ Hal Perkins & UW CSE I-1

CS61A Midterm 2 Review (v1.1)

CS 440: Programming Languages and Translators, Spring 2019 Mon

Contents. Chapter 1 SPECIFYING SYNTAX 1

Functional Programming. Pure Functional Languages

CS 275 Name Final Exam Solutions December 16, 2016

Typed Scheme: Scheme with Static Types

Parsing. Zhenjiang Hu. May 31, June 7, June 14, All Right Reserved. National Institute of Informatics

CS 242. Fundamentals. Reading: See last slide

Last class. CS Principles of Programming Languages. Introduction. Outline

Principles of Programming Languages

A Simple Syntax-Directed Translator

SEMANTIC ANALYSIS TYPES AND DECLARATIONS

An Explicit-Continuation Metacircular Evaluator

Types and Programming Languages. Lecture 5. Extensions of simple types

Chapter 4. Abstract Syntax

Topics Covered Thus Far. CMSC 330: Organization of Programming Languages. Language Features Covered Thus Far. Programming Languages Revisited

Lexical and Syntax Analysis

Lexical vs. Dynamic Scope

Intermediate Code Generation

University of Massachusetts Lowell

The Typed Racket Guide

Typed Racket: Racket with Static Types

G Programming Languages Spring 2010 Lecture 6. Robert Grimm, New York University

CITS3211 FUNCTIONAL PROGRAMMING. 6. Folding operators

CMSC 330: Organization of Programming Languages

CSc 520. Principles of Programming Languages 7: Scheme List Processing

Types and Static Type Checking (Introducing Micro-Haskell)

CS 360 Programming Languages Interpreters

Announcements. The current topic: Scheme. Review: BST functions. Review: Representing trees in Scheme. Reminder: Lab 2 is due on Monday at 10:30 am.

Typical workflow. CSE341: Programming Languages. Lecture 17 Implementing Languages Including Closures. Reality more complicated

Functional Programming. Pure Functional Languages

Review. CS152: Programming Languages. Lecture 11 STLC Extensions and Related Topics. Let bindings (CBV) Adding Stuff. Booleans and Conditionals

CSc 520 Principles of Programming Languages. Examining Lists. Constructing Lists... 7: Scheme List Processing

CS 314 Principles of Programming Languages

Compiler Theory. (Semantic Analysis and Run-Time Environments)

B The SLLGEN Parsing System

Note first midterm date: Wed. evening, Feb. 23 Today's class: Types in OCaml and abstract syntax

CSCE 314 Programming Languages. Type System

Functional Programming - 2. Higher Order Functions

Principles of Programming Languages

Note that in this definition, n + m denotes the syntactic expression with three symbols n, +, and m, not to the number that is the sum of n and m.

CMSC 330: Organization of Programming Languages. Lambda Calculus

Lexical and Syntax Analysis

CSE505, Fall 2012, Midterm Examination October 30, 2012

Lecture 16: Object Programming Languages

COP4020 Programming Assignment 1 - Spring 2011

CVO103: Programming Languages. Lecture 5 Design and Implementation of PLs (1) Expressions

CMSC 330: Organization of Programming Languages

From Syntactic Sugar to the Syntactic Meth Lab:

Parsing a primer. Ralf Lämmel Software Languages Team University of Koblenz-Landau

Fundamentals of Artificial Intelligence COMP221: Functional Programming in Scheme (and LISP)

CA Compiler Construction

5. Semantic Analysis!

Scheme in Scheme: The Metacircular Evaluator Eval and Apply

COMP 181. Agenda. Midterm topics. Today: type checking. Purpose of types. Type errors. Type checking

Project 2: Scheme Interpreter

n n Try tutorial on front page to get started! n spring13/ n Stack Overflow!

CSE341 Spring 2017, Final Examination June 8, 2017

Scheme: Strings Scheme: I/O

More Assigned Reading and Exercises on Syntax (for Exam 2)

1. For every evaluation of a variable var, the variable is bound.

Compilers. Type checking. Yannis Smaragdakis, U. Athens (original slides by Sam

Normal Order (Lazy) Evaluation SICP. Applicative Order vs. Normal (Lazy) Order. Applicative vs. Normal? How can we implement lazy evaluation?

Transcription:

Data Abstraction An Abstraction for Inductive Data Types Philip W. L. Fong pwlfong@cs.uregina.ca Department of Computer Science University of Regina Regina, Saskatchewan, Canada

Introduction This lecture covers [EOPL2] Sect. 2.2. We skip Sect. 2.1 for now. An Abstraction for Inductive Data Types p.1/43

Variant Records An Abstraction for Inductive Data Types p.2/43

Variant Records Aggregate data types Array element selection by indexing Record element (i.e., field) selection by field name Union Discriminated union (i.e., variant records) variant discrimination via a tag field An Abstraction for Inductive Data Types p.3/43

Example: Variant Records struct BinTree { enum { T_LEAF, T_INTERIOR } tag; union { struct { int datum; } leaf; struct { const char *symbol; const BinTree *left; const BinTree *right; } interior; } node; } An Abstraction for Inductive Data Types p.4/43

Variant Records for Scheme [EOPL2] provides a facility, datatype, for supporting the use of variant records in Scheme. Note: datatype is not a standard feature in Scheme. An Abstraction for Inductive Data Types p.5/43

Example: Binary Trees Grammar:!bintree" ::=!number" ::= (!symbol"!bintree"!bintree") An Abstraction for Inductive Data Types p.6/43

Design Goals 1. constructors that allow us to build variants of binary trees 2. a predicate to test if a given value is a binary tree 3. some way of determining, given a binary tree, whether it is a leaf or interior node 4. some way of extracting the components of each variant An Abstraction for Inductive Data Types p.7/43

Using datatype A datatype for binary trees: (define-datatype bintree bintree? (leaf-node (datum number?)) (interior-node (key symbol?) (left bintree?) (right bintree?))) An Abstraction for Inductive Data Types p.8/43

Using datatype A datatype for binary trees: (define-datatype bintree bintree? (leaf-node (datum number?)) (interior-node (key symbol?) (left bintree?) (right bintree?))) This declares a new datatype called bintree. An Abstraction for Inductive Data Types p.9/43

Using datatype A datatype for binary trees: (define-datatype bintree bintree? (leaf-node (datum number?)) (interior-node (key symbol?) (left bintree?) (right bintree?))) A predicate (bintree? x) is defined to test if x is a bintree. An Abstraction for Inductive Data Types p.10/43

Using datatype A datatype for binary trees: (define-datatype bintree bintree? (leaf-node (datum number?)) (interior-node (key symbol?) (left bintree?) (right bintree?))) A bintree can be either a leaf-node or an interior-node. An Abstraction for Inductive Data Types p.11/43

Using datatype A datatype for binary trees: (define-datatype bintree bintree? (leaf-node (datum number?)) (interior-node (key symbol?) (left bintree?) (right bintree?))) A leaf-node has only one field, called datum, which stores a number. The type of a field is specified by naming a predicate, such as number? in the case of datum. An Abstraction for Inductive Data Types p.12/43

Using datatype A datatype for binary trees: (define-datatype bintree bintree? (leaf-node (datum number?)) (interior-node (key symbol?) (left bintree?) (right bintree?))) A constructor procedure (leaf-node n) is defined so that one can construct a leaf-node out of a number n. An Abstraction for Inductive Data Types p.13/43

Using datatype A datatype for binary trees: (define-datatype bintree bintree? (leaf-node (datum number?)) (interior-node (key symbol?) (left bintree?) (right bintree?))) An interior-node consists of 3 fields: key, left, and right. Their types are respectively symbol, bintree, and bintree. An Abstraction for Inductive Data Types p.14/43

Using datatype A datatype for binary trees: (define-datatype bintree bintree? (leaf-node (datum number?)) (interior-node (key symbol?) (left bintree?) (right bintree?))) A constructor (interior-node S B1 B2 ) is defined so that one can create an interior-node out of a symbol S, and two bintrees B1 and B2. An Abstraction for Inductive Data Types p.15/43

Example > (define BT (interior-node a a (leaf-node 3) b 3 (interior-node b 5 0 (leaf-node 5) (leaf-node 0)))) > (bintree? BT) #t An Abstraction for Inductive Data Types p.16/43

Design Goals 1. constructors that allow us to build variants of binary trees 2. a predicate to test if a given value is a binary tree 3. some way of determining, given a binary tree, whether it is a leaf or interior node 4. some way of extracting the components of each variant An Abstraction for Inductive Data Types p.17/43

Variant Discrimination & Component Extraction: 1st Attempt Need a way of determining if a given bintree is a leaf-node. (leaf-node? tree) Need a way of extracting the datum field of a given leaf-node. (leaf-node-datum leaf ) Similar facilities for interior-node... (interior-node? tree) (interior-node-key node) (interior-node-left node) (interior-node-right node) An Abstraction for Inductive Data Types p.18/43

Pattern Matching The designer of the datatype facility did not go that path. That approach would have led to clumsy code. Instead, they have adopted a variant discrimination and component extraction mechanism known as pattern matching, which was first introduced in the functional programming language ML. Pattern matching for datatypes is provided via the cases syntactic form. An Abstraction for Inductive Data Types p.19/43

Example: leaf-sum (leaf-sum tree) Argument(s): tree: a bintree Return: sum of all data at the leaf nodes of tree An Abstraction for Inductive Data Types p.20/43

Example: leaf-sum (define leaf-sum (lambda (tree) (cases bintree tree (leaf-node (N) N) (interior-node (S L R) (+ (leaf-sum L) (leaf-sum R)))))) Write a (cases...) construct to discriminate variants. Identify the type of variant record (i.e., bintree) to be discriminated. An Abstraction for Inductive Data Types p.21/43

Example: leaf-sum (define leaf-sum (lambda (tree) (cases bintree tree (leaf-node (N) N) (interior-node (S L R) (+ (leaf-sum L) (leaf-sum R)))))) Apply the cases construct to an instance of a datatype (i.e., tree). An Abstraction for Inductive Data Types p.22/43

Example: leaf-sum (define leaf-sum (lambda (tree) (cases bintree tree (leaf-node (N) N) (interior-node (S L R) (+ (leaf-sum L) (leaf-sum R)))))) Identify all the variants (i.e., leaf-node & interior-node). For each variant, identify also a list of local variables to be bound to the components of that variant (i.e., (N) in the case of leaf-node, and (S L R) in the case of interior-node). An Abstraction for Inductive Data Types p.23/43

Example: leaf-sum (define leaf-sum (lambda (tree) (cases bintree tree (leaf-node (N) N) (interior-node (S L R) (+ (leaf-sum L) (leaf-sum R)))))) If tree is a leaf-node, then a list of local variables, (N), will be created, with bindings equal the corresponding components of the leaf-node. With these local bindings effective, the expression N will be evaluated, and its value is returned as the value of the cases construct. An Abstraction for Inductive Data Types p.24/43

Example: leaf-sum (define leaf-sum (lambda (tree) (cases bintree tree (leaf-node (N) N) (interior-node (S L R) (+ (leaf-sum L) (leaf-sum R)))))) If tree is an interior-node, then a list of local variables, (S L R), will be created, with bindings equal the corresponding components of the interior-node. With these local bindings effective, the expression (+ (leaf-sum L) (leaf-sum R)) will be evaluated. An Abstraction for Inductive Data Types p.25/43

Example: flip-bintree (flip-bintree tree) Argument(s): tree: a bintree Return: Return a bintree obtained by swapping the left and right subtrees of every interior node in tree. Example: a a 3 b 5 0 b 0 3 5 An Abstraction for Inductive Data Types p.26/43

Example: flip-bintree (define flip-bintree (lambda (tree) (cases bintree tree (leaf-node (N) (leaf-node N)) (interior-node (S L R) (interior-node S (flip-bintree R) (flip-bintree L)))))) An Abstraction for Inductive Data Types p.27/43

Abstract Syntax An Abstraction for Inductive Data Types p.28/43

Concrete Syntax Grammar for Lambda Calculus:!expression" ::=!identifier" ::= (lambda (!identifier")!expression") ::= (!expression"!expression") The brackets, the list representation, and key words such as lambda are introduced to make the language easy to write by humans. Inconvenient to work with for language processors (e.g., interpreters). An Abstraction for Inductive Data Types p.29/43

Example: Revisiting occurs-free? A variable x occurs free in a lambda calculus expression E iff 1. E is a variable reference such that E is the same as x; or 2. E is of the form (lambda (y ) E1 ), where y is different from x and x occurs free in E1 ; or 3. E is of the form (E1 E2 ) such that x occurs free in either E1 or E2. An Abstraction for Inductive Data Types p.30/43

Example: Revisiting occurs-free? An implementation for concrete syntax: (define occurs-free? (lambda (x E) (cond ((symbol? E) (eqv? x E)) ((eqv? (car E) lambda) (let ((y (caadr E)) (E1 (caddr E))) (and (not (eqv? (y x))) (occurs-free? x E1)))) (else (let ((E1 (car E)) (E2 (cadr E))) (or (occurs-free? x E1) (occurs-free? x E2))))))) An Abstraction for Inductive Data Types p.31/43

Abstract Syntax Rather than working with clumsy concrete syntax, a language processor (e.g., an interpreter) usually works with a more convenient internal representation called abstract syntax trees. The idea is that most of the concrete syntax information is discarded, leaving only the essential information that reflects the abstract syntactic structure of a program. An Abstraction for Inductive Data Types p.32/43

Abstract Syntax Trees Concrete syntax: (lambda (x) (f (f x))) Abstract syntax tree: lambda-exp id body x app-exp rtor rand var-exp app-exp id rtor f var-exp id rand var-exp id f f An Abstraction for Inductive Data Types p.33/43

Parsing A parser transforms a source program (in concrete syntax) to an abstract syntax tree (AST): program AST Parser Processor text An Abstraction for Inductive Data Types p.34/43

Defining Abstract Syntax Trees The art and science of building a parser belong to a course on compiler construction (CS410). A shallow coverage of this topic is given in Chapter 3 of [EOPL2]. In this lecture, we are concerned with with following question: Given a concrete syntax, how does one define a data structure for representing the corresponding abstract syntax trees? An Abstraction for Inductive Data Types p.35/43

Example: Lambda Calculus!expression" ::=!identifier" ::= (lambda (!identifier")!expression") ::= (!expression"!expression") An Abstraction for Inductive Data Types p.36/43

Example: Lambda Calculus!expression" ::=!identifier" var-exp (id) ::= (lambda (!identifier")!expression") lambda-exp (id body) ::= (!expression"!expression") app-exp (rator rand) One datatype for each nonterminal being defined. One variant for each production. One field for each occurrence of a nonterminal in a production. An Abstraction for Inductive Data Types p.37/43

Example: Lambda Calculus (define-datatype expression expression? (var-exp (id symbol?)) (lambda-exp (id symbol?) (body expression?)) (app-exp (rator expression?) (rand expression?))) An Abstraction for Inductive Data Types p.38/43

Example: Revisiting occurs-free? A variable x occurs free in a lambda calculus expression E iff 1. E is a variable reference such that E is the same as x; or 2. E is of the form (lambda (y ) E1 ), where y is different from x and x occurs free in E1 ; or 3. E is of the form (E1 E2 ) such that x occurs free in either E1 or E2. An Abstraction for Inductive Data Types p.39/43

Example: Revisiting occurs-free? An implementation based on processing abstract syntax trees: (define occurs-free? (lambda (x E) (cases expression E (var-exp (y) (eqv? y x)) (lambda-exp (y E1) (and (not (eqv? y x)) (occurs-free? x E1))) (app-exp (E1 E2) (or (occurs-free? x E1) (occurs-free? x E2)))))) An Abstraction for Inductive Data Types p.40/43

Example: Revisiting occurs-free? An implementation for concrete syntax: (define occurs-free? (lambda (x E) (cond ((symbol? E) (eqv? x E)) ((eqv? (car E) lambda) (let ((y (caadr E)) (E1 (caddr E))) (and (not (eqv? (y x))) (occurs-free? x E1)))) (else (let ((E1 (car E)) (E2 (cadr E))) (or (occurs-free? x E1) (occurs-free? x E2))))))) An Abstraction for Inductive Data Types p.41/43

Working with Abstract Syntax The language processors developed in this course maniputate abstract syntax trees rather than concrete syntax. Throughout this course, whenever a language grammar (i.e., concrete syntax) is given, we always define a corresponding set of datatypes to represent its abstract syntax trees. An Abstraction for Inductive Data Types p.42/43

Lecture Summary This lecture covers [EOPL2] Sect. 2.2. Variant records via datatype Pattern matching via cases Concrete syntax vs abstract syntax Parsing conversion of concrete syntax to abstract syntax trees Defining abstract syntax trees using datatype Manipulating abstract syntax trees using cases An Abstraction for Inductive Data Types p.43/43