Fall Lecture 3 September 4. Stephen Brookes

Similar documents
Fall Recursion and induction. Stephen Brookes. Lecture 4

Fall 2018 Stephen Brookes. LECTURE 2 Thursday, August 30

15 150: Principles of Functional Programming. Exceptions

Fall 2018 Lecture N

15 150: Principles of Functional Programming. More about Higher-Order Functions

Fall 2018 Lecture 1

Lecture 3: Recursion; Structural Induction

A quick introduction to SML

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

CSE 341 Section 5. Winter 2018

Lecture 2: SML Basics

Standard ML. Data types. ML Datatypes.1

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

Lecture 15 CIS 341: COMPILERS

SML A F unctional Functional Language Language Lecture 19

Australian researchers develop typeface they say can boost memory, that could help students cramming for exams.

Chapter 3 Linear Structures: Lists

Variables and Bindings

Formal Semantics. Prof. Clarkson Fall Today s music: Down to Earth by Peter Gabriel from the WALL-E soundtrack

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

Plan (next 4 weeks) 1. Fast forward. 2. Rewind. 3. Slow motion. Rapid introduction to what s in OCaml. Go over the pieces individually

CMSC 330: Organization of Programming Languages. Formal Semantics of a Prog. Lang. Specifying Syntax, Semantics

Introduction to SML Getting Started

Begin at the beginning

F28PL1 Programming Languages. Lecture 12: Standard ML 2

(Refer Slide Time: 4:00)

The Substitution Model

Chapter 3 Linear Structures: Lists

Types, Expressions, and States

Exercises on ML. Programming Languages. Chanseok Oh

To figure this out we need a more precise understanding of how ML works

A Second Look At ML. Chapter Seven Modern Programming Languages, 2nd ed. 1

Denotational Semantics. Domain Theory

News. Programming Languages. Recap. Recap: Environments. Functions. of functions: Closures. CSE 130 : Fall Lecture 5: Functions and Datatypes

A Brief Introduction to Standard ML

Programming Languages Third Edition

Side note: Tail Recursion. Begin at the beginning. Side note: Tail Recursion. Base Types. Base Type: int. Base Type: int

Tail Recursion: Factorial. Begin at the beginning. How does it execute? Tail recursion. Tail recursive factorial. Tail recursive factorial

Programming Languages

Programming Languages

Programming Languages and Compilers (CS 421)

CSc 372. Comparative Programming Languages. 2 : Functional Programming. Department of Computer Science University of Arizona

OCaml. ML Flow. Complex types: Lists. Complex types: Lists. The PL for the discerning hacker. All elements must have same type.

Functional Programming

Functional programming Primer I

Products and Records

Exercise 1 ( = 22 points)

COSE212: Programming Languages. Lecture 3 Functional Programming in OCaml

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

CMSC 330: Organization of Programming Languages

Programming Languages

Types and Type Inference

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

Dialects of ML. CMSC 330: Organization of Programming Languages. Dialects of ML (cont.) Features of ML. Functional Languages. Features of ML (cont.

Reasoning About Imperative Programs. COS 441 Slides 10

Programming Languages

Programming Languages

Automated Reasoning. Natural Deduction in First-Order Logic

OCaml. History, Variants. ML s holy trinity. Interacting with ML. Base type: Integers. Base type: Strings. *Notes from Sorin Lerner at UCSD*

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

Polymorphic lambda calculus Princ. of Progr. Languages (and Extended ) The University of Birmingham. c Uday Reddy

Lists. Adrian Groza. Department of Computer Science Technical University of Cluj-Napoca

Recap: Functions as first-class values

To figure this out we need a more precise understanding of how ML works

Recap from last time. Programming Languages. CSE 130 : Fall Lecture 3: Data Types. Put it together: a filter function

Lecture Notes on Induction and Recursion

Higher-Order Functions

Hard deadline: 3/28/15 1:00pm. Using software development tools like source control. Understanding the environment model and type inference.

CMSC 330: Organization of Programming Languages. Operational Semantics

CS153: Compilers Lecture 15: Local Optimization

Programming Languages

Module Title: Informatics 1 Functional Programming (first sitting) Exam Diet (Dec/April/Aug): December 2014 Brief notes on answers:

Programming Language Concepts, cs2104 Lecture 04 ( )

COMS 1003 Fall Introduction to Computer Programming in C. Bits, Boolean Logic & Discrete Math. September 13 th

Standard ML. Curried Functions. ML Curried Functions.1

Operational Semantics. One-Slide Summary. Lecture Outline

A Third Look At ML. Chapter Nine Modern Programming Languages, 2nd ed. 1

Haske k ll An introduction to Functional functional programming using Haskell Purely Lazy Example: QuickSort in Java Example: QuickSort in Haskell

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

Lecture 6: Sequential Sorting

Programming Languages

An introduction introduction to functional functional programming programming using usin Haskell

On Academic Dishonesty. Declarative Computation Model. Single assignment store. Single assignment store (2) Single assignment store (3)

CSE 341: Programming Languages

CS109A ML Notes for the Week of 1/16/96. Using ML. ML can be used as an interactive language. We. shall use a version running under UNIX, called

Chapter 3 Programming with Recursion

Chapter 11 :: Functional Languages

CSE341: Programming Languages Lecture 2 Functions, Pairs, Lists. Dan Grossman Fall 2011

CMSC 330: Organization of Programming Languages. OCaml Expressions and Functions

Defining Functions. CSc 372. Comparative Programming Languages. 5 : Haskell Function Definitions. Department of Computer Science University of Arizona

CS 320: Concepts of Programming Languages

The Substitution Model. Nate Foster Spring 2018

CMSC 330: Organization of Programming Languages. OCaml Higher Order Functions

CIS 110: Introduction to Computer Programming

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

Typed First-order Logic

Combining Programming with Theorem Proving

Redefinition of an identifier is OK, but this is redefinition not assignment; Thus

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

Fall Lecture 13 Thursday, October 11

Transcription:

15-150 Fall 2018 Lecture 3 September 4 Stephen Brookes

Today A brief remark about equality types Using patterns Specifying what a function does

equality in ML e1 = e2 Only for expressions whose type is an equality type Equality types include all types built from e.g. int, bool, *, -list int list int * bool (int * bool) list but NOT real or -> - 1+1 = 2; val it = true : bool - [1,1] = (0+1)::[2-1]; val it = true : bool - (fn x => x+x) = (fn y => 2*y); Error: operator and operand don't agree [equality type required]

patterns We introduced patterns, to be used for matching with values Matching p to value v either fails, or succeeds and binds names to values p ::= _ x n true false (p1,, pn) p1::p2 [p1,, pn] Can attach types if desired

Using patterns Recall divmod : int * int -> int * int fun check (x:int, y:int):bool = let val (q, r) = divmod (x, y) in (x = q*y + r) end Introduces check : int * int -> bool Binds check to a function value What does this function do?

eval : int list -> int fun eval ([ ]) = 0 eval (d::l) = d + 10 * (eval L) This definition uses list patterns [ ] matches (only) the empty list d::l matches a non-empty list, binds d to head of the list, L to its tail eval [2,4] =>* 42 What does this function do?

decimal : int -> int list fun decimal n = if n < 10 then [n] else (n mod 10) :: decimal (n div 10) Why didn t I define this function using integer patterns? decimal 42 = [2,4] decimal 0 = [0] What does this function do?

log : int -> int fun log x = if x = 1 then 0 else 1 + log (x div 2) log 3 =??? Q: How can we describe this function? A: Specify its applicative behavior - For what argument values does it terminate? - How does the output relate to the input?

Specifications For each function definition we specify: Type (of the function s argument and result) Assumption (about argument value) Guarantee (about result value, when assumption holds)

Format fun log (x:int) : int = if x=1 then 0 else 1 + log (x div 2) definition (* TYPE log : int -> int *) (* REQUIRES x *) (* ENSURES log x. *) type assumption guarantee For all values x : int satisfying the assumption, log x : int and its value satisfies the guarantee Any ideas?

log spec fun log (x:int) : int = if x=1 then 0 else 1 + log (x div 2) (* TYPE log : int -> int *) (* REQUIRES x > 0 *) (* ENSURES log x = the integer k 0 *) (* such that 2 k x < 2 k+1 *) For all integers x>0, log x evaluates to an integer k such that 2 k x < 2 k+1 relevant math facts?

notes Can use =>* or = in specs Use math notation and math facts, accurately! A function can have several specs different assumptions may lead to different guarantee

another log spec fun log (x:int) : int = if x=1 then 0 else 1 + log (x div 2) (* log : int -> int *) (* REQUIRES x = a power of 2 *) (* ENSURES log x = the integer k *) (* such that 2 k = x *) (a weaker spec why?) (actually implied by original spec)

eval spec fun eval ([ ] : int list) : int = 0 eval (d::l) = d + 10 * (eval L) TYPE eval : int list -> int REQUIRES R = a list of decimal digits ENSURES eval R = a non-negative integer (not the best spec for eval why not?) (doesn t say which non-negative integer!)

decimal spec fun decimal (n:int) : int list = if n<10 then [n] else (n mod 10) :: decimal (n div 10) TYPE decimal : int -> int list REQUIRES n 0 ENSURES decimal n = a list of decimal digits (again, not the best spec )

connection eval and decimal are designed to fit together They satisfy a connection spec TYPE decimal : int -> int list REQUIRES n 0 eval : int list -> int ENSURES eval(decimal n) = n (says which list and which integer )

Evaluation Expression evaluation produces a value if it terminates e => k e e => * v e evaluates to e in k steps e evaluates to v in finitely many steps Declarations produce value bindings d => * [ x1:v1,..., xk:vk ] Matching a pattern to a value either succeeds with bindings, or fails TYPE SAFETY

Basic properties e => * e if and only if k 0. e => k e e => 0 e If e1 => m e2 and e2 => n e3 then e1 => m+n e3

Substitution For bindings [ x1:v1,..., xk:vk ] and expression e we write [ x1:v1,..., xk:vk ] e for the expression obtained by substituting v1 for x1,..., vk for xk in e (for free occurrences, only) [ x:2 ] (x + x) is 2 + 2 [ x:2 ] (fn y => x + y) is fn y => 2 + y [ x:2 ] (fn x => x + x) is fn x => x + x

Explaining evaluation For each syntactic construct we give evaluation rules for => showing order-of-evaluation We derive evaluation laws for => * how expressions evaluate what is the value, if it terminates We can also count number of steps => (n)

Addition rules e1 => e1 e1 + e2 => e1 + e2 e2 => e2 v1 + e2 => v1 + e2 ei, vi : int v1 + v2 => v where v = v1 + v2 + evaluates from left-to-right

Addition law If e1 => * v1 and e2 => * v2 and v = v1 + v2 then e1 + e2 => * v (2+2) + (3+3) => 4 + (3+3) => 4 + 6 => 10 (2+2) + (3+3) => * 10 (2+2) + (3+3) => (3) 10

Application rules e1 => e1 e1 e2 => e1 e2 e2 => e2 (fn x => e) e2 => (fn x => e) e2 (fn x => e) v => [ x:v ] e a function call evaluates its argument

Application law If e1 => * (fn x => e) and e2 => * v then e1 e2 => * [x:v]e

Other rules div and mod evaluate from left to right Tuples evaluate from left to right Lists evaluate from left to right

Declaration rule In the scope of fun f(x) = e, f => (fn x => e) fun divmod(x, y) = (x div y, x mod y) divmod (3,2) => (fn(x, y) => (x div y, x mod y)) (3,2) => (3 div 2, 3 mod 2) => (1, 3 mod 2) => (1, 1)

Example fun f(x) = if x=0 then 1 else f(x-1) (* f : int -> int *) (* REQUIRES x >= 0 *) (* ENSURES f x = 1 *)

In the scope of Example fun f(x) = if x=0 then 1 else f(x-1) f(1-1) => (fn x => if x=0 then 1 else f(x-1)) (1-1) => (fn x => if x=0 then 1 else f(x-1)) 0 => if 0=0 then 1 else f(0-1) => if true then 1 else f(0-1) => 1 (justified by the rules given earlier!)

Patterns If matching p1 to v succeeds with [ B ], (fn p1 => e1 p2 => e2) v => * [ B ] e1 If matching p1 to v fails, and matching p2 to v succeeds with [ B ], (fn p1 => e1 p2 => e2) v => * [ B ] e2 If matching p1 to v fails, and matching p2 to v fails, (fn p1 => e1 p2 => e2) v fails uncaught exception Match [nonexhaustive match failure]

So far Using => and =>* we can talk precisely about program behavior But we may want to ignore evaluation order... For all expressions e1, e2 : int and all values v:int, if e1 + e2 => * v then e2 + e1 => * v In such cases, equational specs may be better For all expressions e1, e2 : int, e1 + e2 = e2 + e1 the same, more succinctly

Example fun add1(x, y) = x + y fun addr(x, y) = y + x addl and addr are indistinguishable Let E be a well-typed expression of type int Let E be obtained from E by replacing a call to addl with a call to addr E also has type int E and E have equal values Not easy to prove directly using =>*

Equivalence For each type t there is a mathematical notion of equivalence (or equality) =t for values of type t Expressions of type t are equivalent iff they evaluate to equivalent values, or both diverge v1 =int v2 v1 = v2 (equal integers) f1 =int->int f2 v1,v2:int. (v1 =int v2 implies f1 v1 =int f2 v2)

Extensionality When e 1 and e2 are values of type t -> t e1 = e2 if and only if for all values v1, v2 of type t v1 = v2 implies e1 v1 = e2 v2

Equations (when well-typed) Arithmetic e + 0 = e e1 + e2 = e2 + e1 e1 + (e2 + e3) = (e1 + e2) + e3 21 + 21 = 42 Boolean if true then e1 else e2 = e1 if false then e1 else e2 = e2 (0 < 1) = true

Equations (when well-typed) Applications only when the argument is a value (fn x => e) v = [x:v]e Declarations In the scope of fun f(x) = e the equation f = (fn x => e) holds

Compositionality (when well-typed) Substitution of equals If e 1 = e2 and e1 = e2 then (e1 e1 ) = (e2 e2 ) If e1 = e2 and e1 = e2 then (e1 + e1 ) = (e2 + e2 ) and so on

Equivalence fun add1(x, y) = x + y fun addr(x, y) = y + x Let E be a well-typed expression of type int containing a call to addl Let E be obtained by changing to addr Easy to show that addl =int * int -> int addr By compositionality, E = int E Hence, if E =>* 42 then also E =>* 42 Easy to prove using =

Equations (when well-typed) Applications (fn p1 => e1 p2 => e2) v = [B1]e if matching p1 to v succeeds with bindings [B1] (fn p1 => e1 p2 => e2) v = [B2]e if matching p1 to v fails & matching p2 to v succeeds with bindings [B2]

Equations Declarations In the scope of fun f(p1) = e1 f(p2) = e2 the equation f = (fn p1 => e1 p2 => e2 ) holds

Useful facts e => * v implies e = v e =>* v implies (fn x => E) e = [x:v] E evaluation is consistent with equivalence

So far Can use equivalence or = to specify the applicative behavior of functional programs Equality is compositional Equality is defined in terms of evaluation => * is consistent with = and ML evaluation

Guidelines Be clear and precise Use bound variable names consistently Use => * (evaluation) and = (equality) accurately Don t leave assumptions hidden