Pattern Matching and Abstract Data Types

Similar documents
CSE 341 Section 5. Winter 2018

Lists. Michael P. Fourman. February 2, 2010

Structural polymorphism in Generic Haskell

Exercise 1 ( = 18 points)

Lecture #23: Conversion and Type Inference

Processadors de Llenguatge II. Functional Paradigm. Pratt A.7 Robert Harper s SML tutorial (Sec II)

Conversion vs. Subtyping. Lecture #23: Conversion and Type Inference. Integer Conversions. Conversions: Implicit vs. Explicit. Object x = "Hello";

Lecture #13: Type Inference and Unification. Typing In the Language ML. Type Inference. Doing Type Inference

CSC324- TUTORIAL 5. Shems Saleh* *Some slides inspired by/based on Afsaneh Fazly s slides

Mini-ML. CS 502 Lecture 2 8/28/08

Chapter 13: Reference. Why reference Typing Evaluation Store Typings Safety Notes

GADTs. Wouter Swierstra and Alejandro Serrano. Advanced functional programming - Lecture 7. [Faculty of Science Information and Computing Sciences]

GADTs. Alejandro Serrano. AFP Summer School. [Faculty of Science Information and Computing Sciences]

Exercise 1 ( = 24 points)

Lecture: Functional Programming

CS 320: Concepts of Programming Languages

CS 4110 Programming Languages & Logics. Lecture 27 Recursive Types

CS 4110 Programming Languages & Logics. Lecture 28 Recursive Types

Programming Languages and Techniques (CIS120)

Supplementary Notes on Recursive Types

Programming Languages Lecture 14: Sum, Product, Recursive Types

Exercise 1 ( = 22 points)

GADTs. Wouter Swierstra. Advanced functional programming - Lecture 7. Faculty of Science Information and Computing Sciences

CPS 506 Comparative Programming Languages. Programming Language Paradigm

Data Types The ML Type System

Lecture Notes on Data Representation

SMURF Language Reference Manual Serial MUsic Represented as Functions

Typed Scheme: Scheme with Static Types

CS 360: Programming Languages Lecture 12: More Haskell

CSE-321 Programming Languages 2010 Midterm

Isabelle s meta-logic. p.1

The Typed Racket Guide

Principles of Programming Languages COMP251: Functional Programming in Scheme (and LISP)

CS558 Programming Languages

Programming Languages Lecture 15: Recursive Types & Subtyping

Type-indexed functions in Generic Haskell

Programming Paradigms

Typed Compilation of Recursive Datatypes

Harvard School of Engineering and Applied Sciences CS 152: Programming Languages

Chapter 15. Functional Programming Languages

Combining Programming with Theorem Proving

Programming Languages and Compilers (CS 421)

Handout 2 August 25, 2008

Data types à la carte

4 Programming with Types

The type checker will complain that the two branches have different types, one is string and the other is int

Symbolic Programming. Dr. Zoran Duric () Symbolic Programming 1/ 89 August 28, / 89

Chapter 3 Linear Structures: Lists

CSCI-GA Scripting Languages

Two approaches to writing interfaces

CS558 Programming Languages

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

Products and Records

Data types for mcrl2

Datatype declarations

A First Look at ML. Chapter Five Modern Programming Languages, 2nd ed. 1

Haskell 98 in short! CPSC 449 Principles of Programming Languages

Chapter 3 Linear Structures: Lists

Dependent types and program equivalence. Stephanie Weirich, University of Pennsylvania with Limin Jia, Jianzhou Zhao, and Vilhelm Sjöberg

Syntax and Grammars 1 / 21

ADT. Typing. Recursive Types. Java. Preliminary: syntax, operational semantics. Untyped lambda calculus. Simply typed lambda calculus

OCaml Data CMSC 330: Organization of Programming Languages. User Defined Types. Variation: Shapes in Java

CSE-321 Programming Languages 2012 Midterm

COSE212: Programming Languages. Lecture 3 Functional Programming in OCaml

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

Functional Programming

CSE341 Section 3. Standard-Library Docs, First-Class Functions, & More

Typed Racket: Racket with Static Types

Some Advanced ML Features

CSE341: Programming Languages Lecture 9 Function-Closure Idioms. Dan Grossman Winter 2013

Functional Programming with Isabelle/HOL

LISP - SEQUENCES. The function make-sequence allows you to create a sequence of any type. The syntax for this function is:

Functional Programming and Haskell

A Brief Introduction to Standard ML

Inductive datatypes in HOL. lessons learned in Formal-Logic Engineering

CS 11 Ocaml track: lecture 4. Today: modules

l e t print_name r = p r i n t _ e n d l i n e ( Name : ^ r. name)

Inductive Definitions, continued

Lecture Notes on Induction and Recursion

CS 11 Haskell track: lecture 1

CS Lectures 2-3. Introduction to OCaml. Polyvios Pratikakis

Flang typechecker Due: February 27, 2015

Questions? Static Semantics. Static Semantics. Static Semantics. Next week on Wednesday (5 th of October) no

Functional Programming. Big Picture. Design of Programming Languages

4.5 Pure Linear Functional Programming

Sometimes it s good to be lazy

CS3110 Spring 2016 Lecture 6: Modules

Principles of Functional Programming

Lambda calculus. Wouter Swierstra and Alejandro Serrano. Advanced functional programming - Lecture 6

Introduction to SML Getting Started

Inductive data types

Data-Oriented System Development

CMSC 330: Organization of Programming Languages. Functional Programming with Lists

Computing Fundamentals 2 Introduction to CafeOBJ

Data types à la carte. Wouter Swierstra Dutch HUG 25/8/10

Homework 3 COSE212, Fall 2018

CS131 Typed Lambda Calculus Worksheet Due Thursday, April 19th

CSE341: Programming Languages Lecture 7 First-Class Functions. Dan Grossman Winter 2013

CMSC 330: Organization of Programming Languages. Functional Programming with Lists

SML Style Guide. Last Revised: 31st August 2011

Transcription:

Pattern Matching and Abstract Data Types Tom Murphy VII 3 Dec 2002 0-0

Outline Problem Setup Views ( Views: A Way For Pattern Matching To Cohabit With Data Abstraction, Wadler, 1986) Active Patterns ( A New Look at Pattern Matching in Abstract Data Types, Pedro, Peña, Núñez, 1996) Without language extensions ( Programming with Recursion Schemes, Wang, Murphy, 2002) In the context of module languages (some thoughts) Conclusion 1

Pattern Matching Pattern matching is a way of conveniently manipulating concrete data types. fun cat nil b = b cat (h :: t) b = h :: (cat t b) vs. fun cat a b = if List.null a then b else hd a :: (cat (tl a) b) 2

Pattern Matching This is great if we re working with types that are actually implemented with the datatype mechanism. Natural numbers can be thought of as a sort of datatype: fun fact Zero = Zero fact (m as Succ n) = m * fact n However, implementing natural numbers (for instance) with datatypes is much too inefficient. 3

Abstraction Of course, the solution is abstraction. We hide the dirty implementation details behind an interface. But pattern matching and abstraction are at odds: Pattern matching insists that the type be concrete while the entire point of abstraction is to hide such details. One solution: Wadler s views. 4

Views Views: Exhibit an isomorphism between an arbitrary type and a datatype (view). Provide in and out functions (that are inverses) Can have many views of the same type Can hold the type abstract while publishing views (using the normal mechanisms) (Note: I ve translated Wadler s examples to an SML-like notation.) 5

Views: Natural Numbers Here s a sample view of the existing int type. view int as Zero Succ int with in 0 = Zero in n = Succ(n - 1) and out Zero = 0 out (Succ n) = n + 1 Zero : int, Succ : int int (?), and act as SML constructors. 6

Using Views fun fib Zero = Zero fib (Succ Zero) = Succ Zero fib (Succ (Succ n)) = fib n + fib (Succ n) 7

A Second View We can add a second view: view int as Zero Even int Odd int with in 0 = Zero in n = if n mod 2 = 0 then Even (n div 2) else Odd (n div 2) and out Zero = 0 out (Even n) = 2 * n out (Odd n) = 2 * n + 1 8

Using this View fun power x Zero = 1 power x (Even n) = power (x * x) n power x (Odd n) = x * power (x * x) n 9

Views That s really all there is to it! Wadler gives some other neat examples, like viewing a list backwards: view α as nil α list Snoc α with in (x :: nil) = nil Snoc x in (x :: (l Snoc x )) = (x :: l) Snoc x and out (nil Snoc x) = (x :: nil) out ((x :: l) Snoc x ) = x :: (l Snoc x )... note that in/out are literally inverses. Also note that in invokes the view recursively by pattern matching against Snoc. 10

More... There are more similar examples in the paper about lists and trees. 11

Weird Stuff: & Let s code up the as pattern (call it &). view α as α & α with in x = x & x and out (x & y) = if x = y then x else raise Bogus fun fact Zero = Zero fact (m & Succ n) = m * fact n This makes sense, but what is the meaning of the expression 1 & 1? 12

Weird Stuff: Guards/Predicates view int as EvenP of int OddP of int with in n = if n mod 2 = 0 then EvenP else OddP and out (EvenP n) = if n mod 2 = 0 then n else raise Bogus out (OddP n) = if n mod 2 = 1 then n else raise Bogus fun cz (OddP 1) = () cz (EvenP n) = cz (n div 2) cz (OddP n) = cz (3 * n + 1)... again, what use are EvenP and OddP outside of patterns? What if we don t even want EvenP and OddP to carry arguments? 13

Views: Summary (+) Combines pattern matching, data abstraction (+) Views behave like existing datatype constructors (-) Need to validate that in and out are inverses (-) Effectful out functions force the programmer to understand the pattern compilation algorithm (TILT s is 1,500 lines)... 14

Views: Summary (-) Unnecessary symmetry with &, predicates we really just want the destructor (-) No treatment of typing (-) Views are not higher-order (-) Not supported in any language 15

Active Patterns 1. Like views, but higher-order. 2. Introduce a type of patterns. 3. Expose the assymetry between constructors and destructors 4. Emphasis is on patterns, since constructors are just functions 5. Strange syntax (examples will be in Haskell) 16

Active Patterns (* define datatype of complex numbers (as r,i) *) data cplx = Cart real real (* the Imag pattern extracts the i field *) Imag i match Cart i (*.. and we can use it like any pattern. *) isreal (Imag i) = (i == 0.0) 17

Computation, Multiple Arguments Active Patterns can do computation. Magnitude (sqrt (r*r + i*i)) match Cart r i And APs can also be of any arity. SelfAndNeg x ( x) match x 18

Active Patterns: @ as is written @ and can have a pattern on each side. Real r match Cart r add (Real r1) @ (Imag i1) (Real r2) @ (Imag i2) = Cart (r1 + r2) (i1 + i2) 19

Active Patterns: Asymmetry The assymetry of APs allows us to make sense of patterns that are just predicates. Even match n, if n mod 2 = 0 Odd match n, if n mod 2 = 1 cz 1 = () cz n @ Even = cz (n div 2) cz n @ Odd = cz (n * 3 + 1) To accomplish this with views, we needed to provide canonical representatives of Even and Odd integers for use as constructors. That didn t make sense. 20

Active Patterns: Typing If we want to pass around APs, we need to assign them types. If an AP matches values of type τ and has n arguments of types σ 1 through σ n, then its type is: σ 1,..., σ n, τ (Not a tuple. Just a crazy notation.) Even, Odd : < int > Real, Imag : < real, cplx > SelfAndNeg : < cplx, cplx, cplx > 21

Higher-order APs Now let s write functions that map between predicates and nullary APs. pred2ap : (α -> Bool) < α > ap2pred : < α > (α -> Bool) pred2ap p = let C match x, if p x in C end ap2pred C = λ x => case x of C => true => false 22

Higher-order APs: @ We can code up @ itself, too: @ : < α, α, α > (x @ x) match x 23

Active Patterns: Summary The authors formalize their system, and provide a method for compiling them efficiently, but the details are not interesting in the context of this class. 1. (+) First class patterns 2. (+) At least as powerful as views 3. (-) Requires separate syntactic classes for active patterns / variables 4. (-) Location of effects in patterns still obscured 24

Who needs language extensions? We can get much of the functionality of views by simply coding them up in existing functional languages. signature NAT = sig type t datatype a front = Zero Succ of a val inj : t front -> t val prj : t -> t front end 25

Implementing NAT structure Nat :> NAT = struct type t = int datatype a front = Zero Succ of a fun inj Zero = 0 inj (Succ n) = n + 1 fun prj 0 = Zero prj n = Succ (n - 1) end 26

Using Recursion Schemes open Nat val one = inj (Succ (inj Zero)) fun fact m = case prj m of Zero => one Succ n => m * fact n The important things here are the call to prj in the case object, and the calls to inj in one. 27

Recursion Schemes: Nested Patterns Nested patterns require a little rewriting: fun fib n = case prj n of Zero => inj Zero Succ n => case prj n of Zero => one Succ m => fib m + fib n... but we can define a function prj2 : t -> t front front, and then do a two-deep pattern easily. 28

Recursion Schemes: Saving Typing To save some more typing, we can provide isucc (= inj o Succ) and izero (= inj Zero), since we always inject after calling one of these constructors. The paper then goes on to describe how to program generically (fold, unfold) using these recursion schemes. 29

Recursion Schemes: Summary 1. Use polymorphic data types 2. explicit in/out functions. 3. (-) Harder to do nested patterns 4. (+) On the other hand, location of effects is explicit 5. (-) Performance penalty 6. (+) No language extension needed 30

Views as signatures Harper-Stone-like view of datatypes in signatures: is really datatype nat = Zero Succ nat structure nat = struct type t val construct : (unit + t) -> t val destruct : t -> (unit + t) end 31

Views as signatures... that is, datatypes are merely an abstract type with coercions into and out of the underlying recursive sum. (Recursion schemes are really just making this explicit. The sum type is the non-recursive polymorphic datatype.) The datatype declaration gives us one way to match this signature (by generating the coercions automatically). Why not others? 32

Views as signatures structure Nat :> datatype nat = Zero Succ of nat = struct type t = int fun construct (Inl ()) = 0 construct (Inr n) = n + 1 end fun destruct 0 = Inl () destruct n = Inr (n - 1) 33

Problems with this approach In SML, these coercions are known to be pure and total. Value restriction Most compilers attempt to avoid function calls when doing separate compilation (see Vanderwaart, et al. s TLDI 03 paper) Same problems with pattern compilation: When do effects happen? How many times? 34

Conclusion Making data abstraction cohabit with other language features can be tricky Views and Active Patterns combine abstraction, pattern matching Much of this functionality can be coded up in existing languages... but making new language extensions is tantalizing! 35

Have a good winter break! 36