Products and Records

Similar documents
Lists. Michael P. Fourman. February 2, 2010

A quick introduction to SML

A Brief Introduction to Standard ML

Data Types The ML Type System

SML A F unctional Functional Language Language Lecture 19

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

Introduction to SML Getting Started

Chapter 3 Linear Structures: Lists

ITT8060: Advanced Programming (in F#)

Programming Languages Lecture 14: Sum, Product, Recursive Types

Chapter 3 Linear Structures: Lists

The story so far. Elements of Programming Languages. Pairs in various languages. Pairs

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

Specification and Verification in Higher Order Logic

Part I: Written Problems

Fall Lecture 3 September 4. Stephen Brookes

Haskell 5.1 INTERACTIVE SESSIONS AND THE RUN-TIME SYSTEM

Specification, Implementation, and Use

Overloading, Type Classes, and Algebraic Datatypes

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

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

02157 Functional Programming. Michael R. Ha. Lecture 2: Functions, Types and Lists. Michael R. Hansen

15 150: Principles of Functional Programming. Exceptions

CS 360: Programming Languages Lecture 10: Introduction to Haskell

F28PL1 Programming Languages. Lecture 12: Standard ML 2

Haskell 98 in short! CPSC 449 Principles of Programming Languages

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

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

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

Solution sheet 1. Introduction. Exercise 1 - Types of values. Exercise 2 - Constructors

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

COSE212: Programming Languages. Lecture 3 Functional Programming in OCaml

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

OCaml Style Guide Fall 2017

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

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

Fundamentals. Fundamentals. Fundamentals. We build up instructions from three types of materials

CSE3322 Programming Languages and Implementation

Intermediate Code Generation

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

Flang typechecker Due: February 27, 2015

Exercises on ML. Programming Languages. Chanseok Oh

Chapter 2 SML, a Functional Programming Language

2.1. Expressions. Chapter 2 SML, a Functional Programming Language. Integers. Interacting with ML

Programming Languages Third Edition. Chapter 9 Control I Expressions and Statements

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

CSE341: Programming Languages Lecture 9 Function-Closure Idioms. Dan Grossman Fall 2011

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

Programming in Standard ML: Continued

Lecture 2: The Basis of SML

Introduction to Haskell

Why OCaml? Introduction to Objective Caml. Features of OCaml. Applications written in OCaml. Stefan Wehr

News. Programming Languages. Complex types: Lists. Recap: ML s Holy Trinity. CSE 130: Spring 2012

Introduction to Objective Caml

If we have a call. Now consider fastmap, a version of map that uses futures: Now look at the call. That is, instead of

6.001 Notes: Section 17.5

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

Programming Lecture 3

Induction and Semantics in Dafny

x = 3 * y + 1; // x becomes 3 * y + 1 a = b = 0; // multiple assignment: a and b both get the value 0

(Refer Slide Time: 4:00)

6.001 Notes: Section 8.1

Lecture 2: SML Basics

Sample Exam; Solutions

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

Type Checking and Type Inference

Pattern Matching and Abstract Data Types

Fall 2018 Stephen Brookes. LECTURE 2 Thursday, August 30

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

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

2.1. Expressions. Chapter 2 ML, a Functional Programming Language. Integers. Interacting with ML

Handout 2 August 25, 2008

CS558 Programming Languages

CSc 520. Principles of Programming Languages 11: Haskell Basics

Note that pcall can be implemented using futures. That is, instead of. we can use

Recap. Recap. If-then-else expressions. If-then-else expressions. If-then-else expressions. If-then-else expressions

Begin at the beginning

SMURF Language Reference Manual Serial MUsic Represented as Functions

DaMPL. Language Reference Manual. Henrique Grando

Wellesley College CS251 Programming Languages Spring, 2000 FINAL EXAM REVIEW PROBLEM SOLUTIONS

EMBEDDED SYSTEMS PROGRAMMING Language Basics

CSc 372 Comparative Programming Languages

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

Some Advanced ML Features

Practical Haskell. An introduction to functional programming. July 21, Practical Haskell. Juan Pedro Villa-Isaza. Introduction.

Functional Programming

CSCI-GA Scripting Languages

CS558 Programming Languages

CS131 Typed Lambda Calculus Worksheet Due Thursday, April 19th

CSc 372. Comparative Programming Languages. 8 : Haskell Function Examples. Department of Computer Science University of Arizona

CSE 341 Section 5. Winter 2018

Type Systems, Type Inference, and Polymorphism

Module 10A Lecture - 20 What is a function? Why use functions Example: power (base, n)

Sequential Search (Searching Supplement: 1-2)

Haskell Syntax in Functions

CIS24 Project #3. Student Name: Chun Chung Cheung Course Section: SA Date: 4/28/2003 Professor: Kopec. Subject: Functional Programming Language (ML)

Functional Programming

Difference Between Dates Case Study 2002 M. J. Clancy and M. C. Linn

Control Structures. Lecture 4 COP 3014 Fall September 18, 2017

02157 Functional Programming Lecture 1: Introduction and Getting Started

Transcription:

Products and Records Michael P. Fourman February 2, 2010 1 Simple structured types Tuples Given a value v 1 of type t 1 and a value v 2 of type t 2, we can form a pair, (v 1, v 2 ), containing these values. The type of the pair is t 1 * t 2. Triples, quadruples etc are built in an analogous way. To decompose such values we extend the class of patterns to include tuple patterns, so that (pat 1,..., pat n ) is now a pattern. Note the use of the pattern (i,s) in the following example: fun f (i,s) = i + (size s); This declares a function int string f int Evaluating f (4, "abc"); would produce the value 7. All functions in SML take a single argument and return a single result. However, as the argument can be a tuple, and pattern matching allows us to break down a tuple into its components, syntactically it looks as though a function can take more than one argument. Although pattern-matching is a convenient way to access the components of a tuple, sometimes it is useful to use functions that extract the components. The components of a pair may be extracted using the selector functions, #1, and #2, shown in the following diagram. A #1 A B #2 B Our function, f could, equivalently, have been declared as 1

fun f (p: int * string) = #1 p + size (#2 p) The type constraint is needed; without it, the compiler could not tell that the argument to f must be a pair. In this example, pattern-matching is clearer. A function can also return more than one result, as in fun g s = (size s, s); If a function takes an argument of type t 1 and returns a result of type t 2, then the type of the function is displayed as t 1 -> t 2. In the examples above, f: int * string -> int, and g: string -> (int * string). All values in ML are first-class; they can be passed as arguments, returned as results, and used as components of other, structured values. Pairs 1 are values and so can be manipulated just like the values of the basic types. As an example, consider the definition of an infix function ++, for adding two vectors, component-wise. infix ++; fun ((vx, vy) ++ (wx, wy)) = (vx + wx : real, vy + wy : real); This function takes a pair of pairs of reals as argument, and returns a pair of reals as result. If we use it to define a further function, summing three vectors, we don t need to decompose each vector into its components. fun sumvecs (u, v, w) = u ++ v ++ w; Records The components of a tuple are unnamed we retrieve a component by its position. SML also has a type, called a record, analogous to a C structure, or Pascal record. To build a record you must specify the field names and the corresponding values, as in val point = {x = 3, y = 4, colour = "red"}; Such a value would have type {x: int, y: int, colour: string}. To decompose such values we extend the definition of a pattern to include record patterns. The order of the fields is unimportant, and so we could define fun pointcolour {colour = c, x = xp, y = yp} = c; 1 This also applies to values of other types, that we will introduce later. It even applies to functions, even the built-in ones; they are also first-class values. 2

Applying this function to point would return the value "red". We can also use a shorthand for record patterns, to introduce variables with the same names as the labels of the record. fun pointinfo {colour, x, y} = (colour, x*x + y*y); Applying pointinfo to point would give the value (red, 25). Records provide documentation for code, but they make code more verbose and the documentation supplied is sometimes redundant. They may need to be handled by special-purpose functions, whereas corresponding functions on tuples could be placed in a library. 2 Functions and pattern matching So far our elementary patterns have been restricted to variables and larger patterns constructed using just tuple and record patterns. We now look at other kinds of pattern. Consider the definition of a function that returns the first element of a pair: fun fst (x, y) = x; It s clearly important that we give a name to the first component of the pair, x, as we refer to it in the body of the function. Having to specify a name for the second component, in this case y, is tedious as it is never used. SML allows to be used as a wild-card pattern in these cases. This avoids forcing the programmer to think up pointless names, and indicates to the reader that this subcomponent is not referred to in the body. For example, fun fst (x, _) = x; fun snd (_, y) = y; When we use pattern-matching against a pattern composed from variables and wild-cards, to decompose a value into subcomponents, the type system ensures that such a decomposition always succeeds. There are other cases where the pattern-matching can fail. The simplest situation where this can happen is if we allow constants such as integers, booleans and strings as patterns. For example, consider the following function declaration: fun f ("abc", true, x) = x + 1; The pattern only matches values of type string * bool * int where the first component is the string "abc" and the second component is true. What happens if you apply f to an argument that doesn t match this pattern? The system will raise an exception and return control to the top-level prompt. We 3

will see later in the course how to explicitly raise and catch such exceptions. If a pattern doesn t match all values of the type it may be applied to then the system warns you of this with a message such as Warning Matches are not exhaustive. Found near... The system also warns you if some patterns are redundant, in the sense that every possible argument will be matched by some earlier pattern. Both types of warning should be heeded a well written, robust program will not generate warnings. Definition by cases Often it is useful to define a function by cases. For example, we might use strings to represent colours. We can then define a function to help choose our clothes by checking whether two colours clash. If the first colour is "yellow" and the second one is "brown" then we should (perhaps) return true. Similarly, we should return true if the colours are "brown" and "red". Each one of the clashing choices can be expressed as a pattern on pairs. We extend the syntax for defining functions to allow a number of separate clauses (a clausal functional declaration): fun function name pattern 1 = expression 1 function name pattern 2 = expression 2. function name pattern n = expression n ; A (tasteless) version of the clash function may now be defined by fun clash ("yellow", "brown") = true clash ("brown", "red") = true clash _ = false; When the function is applied to an argument the patterns are tried in sequence. If pattern i is the first one that matches then expression i is evaluated. Thus in the above example the third clause is only applicable if the first two don t match. Variables and constants It might seem inefficient to use strings to model colours, and the unwary might try the following definitions: 4

val red = 1; val brown = 2; val yellow = 3; fun clash (yellow, brown) = true clash (brown, red) = true clash _ = false; However, the occurrences of yellow and brown in the patterns will be treated as variables, not constants. The first clause will always match, binding the first colour to the variable yellow and the second element of the pair to the variable brown. This is an easy mistake to make, although in this simple case the compiler should warn you that the second and third clauses are redundant. We will see how to introduce constructors, new constants that can be used in patterns, later in the course when enumerated types are introduced. Patterns are linear Patterns, in SML, are said to be linear. This means that you can t repeat a variable in a pattern to indicate that two subcomponents are equal. Thus you must write instead of fun testpair (x, y) = if (x = y) then "same" else "different"; fun testpair (x, x) = "same" testpair (_, _) = "different"; Layered patterns Sometimes you would like to name a component of an argument and name some of its subcomponents. Layered patterns, using the keyword as to join two patterns that will both be matched against the same value, allow you to do this, as in fun f (x as (y,_), _) = (x, (y,y)); Without layered patterns you would have to write fun f ((y,z), _) = ((y,z), (y,y)); This definition is rather artificial. However, as the course progresses you will find many places where layered patterns arise naturally. 5

The case expression A function may be used to discriminate between different forms of argument. SML also provides a case expression: case expression of pattern 1 => expression 1 pattern 2 => expression 2. pattern n => expression n Here is an example illustrating its use. fun check {day, month, year} = let val leap = year mod 4 = 0 andalso year mod 100 <> 0 val daysinmonth = case month of "january" => 30 "february" => if leap then 29 else 28 (*... *) "december" => 31 _ => error "month not recognised" in day <= daysinmonth end; (C) Michael Fourman 1994-2006 6