Lecture 2: The Basis of SML

Similar documents
Chapter 2 SML, a Functional Programming Language

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

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

Higher-Order Functions

Recursion. Lars-Henrik Eriksson. Functional Programming 1. Based on a presentation by Tjark Weber and notes by Sven-Olof Nyström

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

SML A F unctional Functional Language Language Lecture 19

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

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

Introduction to SML Basic Types, Tuples, Lists, Trees and Higher-Order Functions

F28PL1 Programming Languages. Lecture 11: Standard ML 1

02157 Functional Programming Lecture 2: Functions, Basic Types and Tuples

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

Standard ML. Curried Functions. ML Curried Functions.1

CSE 341 Section 5. Winter 2018

Chapter 3 Linear Structures: Lists

Chapter 3 Linear Structures: Lists

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

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

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

COP4020 Programming Languages. Functional Programming Prof. Robert van Engelen

Exercises on ML. Programming Languages. Chanseok Oh

Inductive Data Types

A Brief Introduction to Standard ML

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

CSCC24 Functional Programming Typing, Scope, Exceptions ML

Programming Paradigms Languages F28PL, Lecture 1

Datatype declarations

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

Chapter 3 Programming with Recursion

Recursion. Tjark Weber. Functional Programming 1. Based on notes by Sven-Olof Nyström. Tjark Weber (UU) Recursion 1 / 37

Products and Records

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

Functional programming Primer I

Pace University. Fundamental Concepts of CS121 1

Lecture #23: Conversion and Type Inference

Data Types The ML Type System

Specification and Verification in Higher Order Logic

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

Fall Lecture 3 September 4. Stephen Brookes

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

Functional Programming

Introduction to SML Getting Started

It is better to have 100 functions operate one one data structure, than 10 functions on 10 data structures. A. Perlis

Case by Case. Chapter 3

CSci 4223 Principles of Programming Languages

Lists. Michael P. Fourman. February 2, 2010

Announcements. CSCI 334: Principles of Programming Languages. Lecture 5: Fundamentals III & ML

LECTURE 16. Functional Programming

Functional Programming. Big Picture. Design of Programming Languages

Recursion and Induction: Haskell; Primitive Data Types; Writing Function Definitions

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

F28PL1 Programming Languages. Lecture 12: Standard ML 2

CSc 372 Comparative Programming Languages

Overloading, Type Classes, and Algebraic Datatypes

A general introduction to Functional Programming using Haskell

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

ITT8060: Advanced Programming (in F#)

Names and Functions. Chapter 2

The PCAT Programming Language Reference Manual

Lecture Notes on Induction and Recursion

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

Declaration and Memory

Programming in Standard ML: Continued

A quick introduction to SML

COSE212: Programming Languages. Lecture 3 Functional Programming in OCaml

CMSC 330: Organization of Programming Languages. OCaml Imperative Programming

Haskell through HUGS THE BASICS

CSE 3302 Programming Languages Lecture 8: Functional Programming

Haskell: Lists. CS F331 Programming Languages CSCE A331 Programming Language Concepts Lecture Slides Friday, February 24, Glenn G.

Quick Reference Guide

CSE341: Programming Languages Lecture 4 Records, Datatypes, Case Expressions. Dan Grossman Spring 2013

CMSC 330: Organization of Programming Languages. OCaml Imperative Programming

SMURF Language Reference Manual Serial MUsic Represented as Functions

G Programming Languages - Fall 2012

Functional Programming Languages (FPL)

Final Examination: Topics and Sample Problems

CS 320: Concepts of Programming Languages

02157 Functional Programming. Michael R. Ha. Lecture 1: Introduction and Getting Started. Michael R. Hansen

Conditionals !

Functional Programming

Index. Cambridge University Press Functional Programming Using F# Michael R. Hansen and Hans Rischel. Index.

All the operations used in the expression are over integers. a takes a pair as argument. (a pair is also a tuple, or more specifically, a 2-tuple)

CSE 341 Lecture 9. type systems; type safety; defining types Ullman 6-6.2; 5.3. slides created by Marty Stepp

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

CSc 372. Comparative Programming Languages. 4 : Haskell Basics. Department of Computer Science University of Arizona

UNIT 3

9/21/17. Outline. Expression Evaluation and Control Flow. Arithmetic Expressions. Operators. Operators. Notation & Placement

CSE 505. Lecture #9. October 1, Lambda Calculus. Recursion and Fixed-points. Typed Lambda Calculi. Least Fixed Point

Haskell 98 in short! CPSC 449 Principles of Programming Languages

CS 11 Haskell track: lecture 1

PROGRAMMING IN HASKELL. Chapter 2 - First Steps

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

G Programming Languages - Fall 2012

Lecture 2: List algorithms using recursion and list comprehensions

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

Programming Language Concepts, cs2104 Lecture 04 ( )

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

15 150: Principles of Functional Programming. Exceptions

Functional Programming

Transcription:

Lecture 2: The Basis of SML Jean-Noël Monette Functional Programming 1 September 9, 2013 Based on notes by Pierre Flener, Sven-Olof Nyström Jean-Noël Monette (UU) Lecture 2: The Basis of SML 1 / 73

Today More on SML: 1 Types and type inference 2 Literals and built-in operators 3 Value declarations 4 Tuples and record 5 Functions 6 Specifications of functions 7 Pattern Matching 8 Local declarations 9 New operators 10 Side Effects 11 Exceptions 12 Modules 13 Comparison with Imperative Programming 14 Exercises Jean-Noël Monette (UU) Lecture 2: The Basis of SML 2 / 73

Types and type inference Table of Contents 1 Types and type inference 2 Literals and built-in operators 3 Value declarations 4 Tuples and record 5 Functions 6 Specifications of functions 7 Pattern Matching 8 Local declarations 9 New operators 10 Side Effects 11 Exceptions 12 Modules 13 Comparison with Imperative Programming 14 Exercises Jean-Noël Monette (UU) Lecture 2: The Basis of SML 3 / 73

Types and type inference Basic types int: integers real: real numbers char: characters string: character sequences bool: truth values (or: Booleans) true and false unit: only one possible value: () Jean-Noël Monette (UU) Lecture 2: The Basis of SML 4 / 73

Types and type inference More types Some expressions may have a compound type. functions: e.g. int -> int tuples: e.g. int * int lists: e.g. int list > ([abs, ],( cool,3.5)); val it = ([fn, fn ], ( cool, 3.5)): ( int > int) list ( string real ) We will see later in the course that one can even declare his own datatypes. Jean-Noël Monette (UU) Lecture 2: The Basis of SML 5 / 73

Types and type inference Type inference SML is strongly typed, meaning that all expressions have a well-defined type that can be determined statically (without running the program). It is (most of the time) not necessary to declare the type of an expression. The compilers are able to infer the type of all expressions. It is necessary to give the right operands to an operator or function. fun double x = 2 x; ( infers type int > int ) double 3.0; ( Error Type error in function application. ) 2 3.0; ( Error Type error in function application. ) Jean-Noël Monette (UU) Lecture 2: The Basis of SML 6 / 73

Literals and built-in operators Table of Contents 1 Types and type inference 2 Literals and built-in operators 3 Value declarations 4 Tuples and record 5 Functions 6 Specifications of functions 7 Pattern Matching 8 Local declarations 9 New operators 10 Side Effects 11 Exceptions 12 Modules 13 Comparison with Imperative Programming 14 Exercises Jean-Noël Monette (UU) Lecture 2: The Basis of SML 7 / 73

Literals and built-in operators Integer and real literals Integers: Reals: In base 10: A sequence of digits (0-9), preceded by ~ for the negation. ~12 Base 16: A sequence of digits (0-9, A-F) preceded by 0x or 0X. ~0xA17f 1 An optional ~. 2 A sequence of one or more digits. 3 One or both of: A point and one or more digits. E or e, optional ~, one or more digits. 0.0 15.5e3 15E 2 Jean-Noël Monette (UU) Lecture 2: The Basis of SML 8 / 73

Literals and built-in operators Built-in operators SML has several built-in operators that work on the basic types. Several of them are overloaded for convenience. e.g. 2 + 3; 2.0 + 3.0; There is no explicit conversion. Operators are only a special case of functions. Jean-Noël Monette (UU) Lecture 2: The Basis of SML 9 / 73

Operators on Integers Literals and built-in operators op : type form precedence + : int int int infix 6 : int int int infix 6 : int int int infix 7 div : int int int infix 7 mod : int int int infix 7 = : int int bool infix 4 <> : int int bool infix 4 < : int int bool infix 4 <= : int int bool infix 4 > : int int bool infix 4 >= : int int bool infix 4 ~ : int int prefix abs : int int prefix ( the exact type will be defined later) Infix operators associate to the left. Jean-Noël Monette (UU) Lecture 2: The Basis of SML 10 / 73

Operators on Reals Literals and built-in operators op : type form precedence + : real real real infix 6 : real real real infix 6 : real real real infix 7 / : real real real infix 7 <, <= : real real bool infix 4 >, >= : real real bool infix 4 ~ : real real prefix abs : real real prefix Math.sqrt : real real prefix Math.ln : real real prefix ( the exact type will be defined later) Infix operators associate to the left. Remark the absence of = and <>. Jean-Noël Monette (UU) Lecture 2: The Basis of SML 11 / 73

Literals and built-in operators Characters and Strings A character value is written as the symbol # immediately followed by the character enclosed in double-quotes " A string is a character sequence enclosed in double-quotes " Control characters can be included: end-of-line: \n double-quote: \" backslash: \\ # a Hello!\nGoodbye Jean-Noël Monette (UU) Lecture 2: The Basis of SML 12 / 73

Literals and built-in operators Operators on Characters and Strings Let strchar strchar be char char or string string op : type form precedence = : strchar strchar bool infix 4 <> : strchar strchar bool infix 4 < : strchar strchar bool infix 4 <= : strchar strchar bool infix 4 > : strchar strchar bool infix 4 >= : strchar strchar bool infix 4 ˆ : string string string infix 6 size : string int prefix ( the exact type will be defined later) Use of the lexicographic order, according to the ASCII code Infix operators associate to the left. Jean-Noël Monette (UU) Lecture 2: The Basis of SML 13 / 73

Type Conversions Literals and built-in operators op : type real : int real ceil : real int floor : real int round : real int trunc : real int chr : int char ord : char int str : char string Int.toString : int string Conversions of chr and ord are done according to the ASCII code. Jean-Noël Monette (UU) Lecture 2: The Basis of SML 14 / 73

Literals and built-in operators Eager and Lazy Evaluation All the previous operators, as well as functions, are evaluated after all their operands are evaluated. This is called eager evaluation. Sometimes, it is however not necessary to evaluate all the operands to know the result of an operation. In such a case, we use lazy evaluation. The operands are only evaluated if needed. We will see several examples of lazy evaluation. Jean-Noël Monette (UU) Lecture 2: The Basis of SML 15 / 73

Literals and built-in operators Operators on Booleans op : type form precedence andalso : bool bool bool infix 3 orelse : bool bool bool infix 2 not : bool bool prefix = : bool bool bool infix 4 <> : bool bool bool infix 4 ( the exact type will be defined later) Infix operators associate to the left. and and or are not boolean operators! andalso and orelse are evaluated lazily. Jean-Noël Monette (UU) Lecture 2: The Basis of SML 16 / 73

Literals and built-in operators Lazy evaluation: Examples > ( 34 < 649 ) orelse ( Math.ln(12.4) 3.4 > 12.0 ) ; val it = true : bool The second operand is not evaluated because the first operand evaluates to true. > ( 34 < 649 ) orelse ( 0.0 / 0.0 > 999.9 ) ; val it = true : bool The second operand ( 0.0 / 0.0 > 999.9 ) is not evaluated, even though by itself it would lead to an error: > ( 0.0 / 0.0 > 999.9 ) ;! Uncaught exception: Div Jean-Noël Monette (UU) Lecture 2: The Basis of SML 17 / 73

Literals and built-in operators if..then..else if B then E1 else E2 This is an expression, not a control structure. B must be a boolean expression. The type of E1 and E2 must be the same. E1 is only evaluated if B evaluates to true. E2 is only evaluated if B evaluates to false. There is no if B then E expression. What would be the value of the expression when B is false? if-then-else as a lower precedence than all the other operators. Jean-Noël Monette (UU) Lecture 2: The Basis of SML 18 / 73

Exercises Literals and built-in operators 1 Express the following expressions as if-then-else expressions: 1 E orelse F 2 E andalso F 2 Evaluate by reduction the following expression: if 1 + 2 < 4 then size ( sal ^ ut! ) 2 else 4 div Jean-Noël Monette (UU) Lecture 2: The Basis of SML 19 / 73

Value declarations Table of Contents 1 Types and type inference 2 Literals and built-in operators 3 Value declarations 4 Tuples and record 5 Functions 6 Specifications of functions 7 Pattern Matching 8 Local declarations 9 New operators 10 Side Effects 11 Exceptions 12 Modules 13 Comparison with Imperative Programming 14 Exercises Jean-Noël Monette (UU) Lecture 2: The Basis of SML 20 / 73

Identifiers Value declarations Alphanumeric identifiers Symbolic identifiers made from + - / < > =! ~ \? : Do not mix alphanumeric and symbolic characters @ # $ % ^ & ` The identifier it always has the result of the last unidentified expression evaluated. 3 +~ 2 is different from 3 + ~ 2 One must separate the symbols + and ~ with a space, otherwise they form a new symbolic identifier Jean-Noël Monette (UU) Lecture 2: The Basis of SML 21 / 73

Value declarations Bindings and environments The execution of a declaration, say val x = expr, creates a binding: the identifier x is bound to the value of the expression expr A collection of bindings is called an environment > val sum = 24 ; val sum = 24 : int > val sum = 3.51 ; val sum = 3.51 : real Jean-Noël Monette (UU) Lecture 2: The Basis of SML 22 / 73

Value declarations Evaluation order Evaluation and declaration from left to right > val a = 1 ; val a = 1 : int > val b = 2 ; val b = 2 : int > val a = a+b val b = a+b ; val a = 3 : int val b = 5 : int and: Simultaneous evaluation of the right-hand sides of the declarations > val a = 1 val b = 2 ; val a = 1 : int val b = 2 : int > val a = a+b and b = a+b ; val a = 3 : int val b = 3 : int Jean-Noël Monette (UU) Lecture 2: The Basis of SML 23 / 73

Value declarations Identifiers are not variables > val x = 10; val x = 10: int > fun addx y = x+y; val addx = fn: int > int > addx 5; val it = 15: int > x = 100; val it = false : bool > val x = 100; val x = 100: int > addx 5; val it = 15: int Jean-Noël Monette (UU) Lecture 2: The Basis of SML 24 / 73

Tuples and record Table of Contents 1 Types and type inference 2 Literals and built-in operators 3 Value declarations 4 Tuples and record 5 Functions 6 Specifications of functions 7 Pattern Matching 8 Local declarations 9 New operators 10 Side Effects 11 Exceptions 12 Modules 13 Comparison with Imperative Programming 14 Exercises Jean-Noël Monette (UU) Lecture 2: The Basis of SML 25 / 73

Tuples and record Tuples Group n( 1) values of possibly different types into n-tuples by enclosing them in parentheses, say: (22>5, "abc", 123) Particular cases of n-tuples: pairs (or: couples), triples,... Careful: There are no 1-tuples in ML! (1) is just 1 in parentheses. Selector #i returns the i th component of a tuple It is possible to have tuples of tuples The value () is the only 0-tuple, and it has type unit Jean-Noël Monette (UU) Lecture 2: The Basis of SML 26 / 73

Tuples: examples Tuples and record > (2.3, 5) ; val it = (2.3, 5) : real int Operator here means the Cartesian product of types > val bigtuple = ((2.3, 5), two, (8, true )) ; val bigtuple = ((2.3, 5), two, (8, true )) : ( real int ) string ( int bool) > #3 bigtuple ; val it = (8, true) : int bool > #2(#1 bigtuple) + #1(#3 bigtuple) ; val it = 13 : int Jean-Noël Monette (UU) Lecture 2: The Basis of SML 27 / 73

Tuples and record Records A record is a generalised tuple where each component is identified by a label rather than by its integer position, and where curly braces are used instead of parentheses A record component is also called a field Selector #label returns the value of the component identifed by label It is possible to have records of records n-tuples are just records with integer labels (when n 1) Jean-Noël Monette (UU) Lecture 2: The Basis of SML 28 / 73

Records: examples Tuples and record > {course = FP, year = 2} ; val it = {course = FP, year = 2} : {course : string, year : int} > #a {a=1, b= xyz } ; val it = 1 : int > {a=1, b= xyz } = {b= xyz, a=1} ; val it = true : bool > (1, xyz ) = ( xyz, 1) ; Error Type error in function application.... > {2=1, 1= xyz } = ( xyz, 1) ; val it = true : bool Jean-Noël Monette (UU) Lecture 2: The Basis of SML 29 / 73

Functions Table of Contents 1 Types and type inference 2 Literals and built-in operators 3 Value declarations 4 Tuples and record 5 Functions 6 Specifications of functions 7 Pattern Matching 8 Local declarations 9 New operators 10 Side Effects 11 Exceptions 12 Modules 13 Comparison with Imperative Programming 14 Exercises Jean-Noël Monette (UU) Lecture 2: The Basis of SML 30 / 73

Functions Functions fun even x = x mod 2 = 0; val even = fn x => x mod 2 = 0; ( anonymous function ) fun odd x = not (even x); ( using another function ) Evaluation: > odd 17 orelse even 17; > (fn x=> not (even x)) 17 orelse even 17; > not (even 17) orelse even 17; > not ((fn x => x mod 2 = 0) 17) orelse even 17; > not (17 mod 2 = 0) orelse even 17; > not (1 = 0) orelse even 17; > not false orelse even 17; > true orelse even 17; > true; Jean-Noël Monette (UU) Lecture 2: The Basis of SML 31 / 73

> fun even x = x mod 2 = 0; val even = fn: int > bool > val plop = even; val plop = fn: int > bool > plop 3; val it = false : bool > (fn x => x mod 2 = 1) 3; val it = true: bool Jean-Noël Monette (UU) Lecture 2: The Basis of SML 32 / 73 Functions (cont.) Functions Function application has the highest precedence, and is evaluated from left to right. Functions are values, just as integers, tuples, etc. They have a type (that can be inferred by the system). If a type cannot be inferred from the context, then the default is that an overloaded operator symbol refers to the function on integers. Any identifier can be bound to them. They can be arguments or return values of other functions.

Functions Functions of several parameters In SML, functions only have one parameter, and one result. How can we implement e.g. the mathematical function max(a, b)? Jean-Noël Monette (UU) Lecture 2: The Basis of SML 33 / 73

Functions Functions of several parameters In SML, functions only have one parameter, and one result. How can we implement e.g. the mathematical function max(a, b)? Two ways: The parameter is a tuple (a pair, here). > fun max (a,b) = if a > b then a else b; Use curried functions. > fun max a b = if a > b then a else b; Does it look the same? Does that small difference matter? Jean-Noël Monette (UU) Lecture 2: The Basis of SML 33 / 73

Functions Functions of several parameters (cont.) > fun max1 (a,b) = if a > b then a else b; val max1 = fn: int int > int >val max1 = fn (a,b) => if a > b then a else b; val max1 = fn: int int > int > fun max2 a b = if a > b then a else b; val max2 = fn: int > int > int > val max2 = fn a => fn b => if a > b then a else b; val max2 = fn: int > int > int > val posorzero = max2 0; val posorzero = fn: int > int > posorzero 3; val it = 3: int > posorzero 3; val it = 0: int Jean-Noël Monette (UU) Lecture 2: The Basis of SML 34 / 73

Functions Currying There is equivalence of the types of the following functions: f : A B C g : A (B C) H.B. Curry (1958): f (a, b) = g a b Currying = passing from the first form to the second form Let a be an object of type A, and b an object of type B f (a, b) is an object of type C, the application of the function f to the pair (a, b) g a is an object of type B C: g a is thus a function, the result of a function can thus also be a function! (g a) b is an object of type C, the application of the function g a to b Attention: f (a, b) is different from f a b Jean-Noël Monette (UU) Lecture 2: The Basis of SML 35 / 73

Functions Currying (cont.) Every function on a Cartesian product can be curried: g : A 1 A 2 A n C g : A 1 (A 2 (A n C)) g : A 1 A 2 A n C The symbol associates to the right. Usefulness of currying: The rice tastes better... Partial application of a function for getting other functions Easier design and usage of higher-order functions (functions with functional arguments) Jean-Noël Monette (UU) Lecture 2: The Basis of SML 36 / 73

Currying, examples Functions > fun greet word name = word ˆ, ˆ name ˆ! ; val greet = fn: string > string > string > val greeteng = greet Hello ; val greeteng = fn: string > string > val greetswe = greet Hej ; val greetswe = fn: string > string > greeteng Tjark ; val it = Hello, Tjark! : string > greetswe Kjell ; val it = Hej, Kjell! : string > greet Salut Jean Noel ; val it = Salut, Jean Noel! : string Jean-Noël Monette (UU) Lecture 2: The Basis of SML 37 / 73

Functions More on functions Functions can return tuples when several results are needed. Functions can take or return the unit argument: fun bof () = (); The type of functions can be polymorphic: > fun id x = x; val id = fn: a > a The type variable a can be instantiated to any type: > id 5; val it = 5: int > id 3.5; val it = 3.5: real Jean-Noël Monette (UU) Lecture 2: The Basis of SML 38 / 73

Polymorphism limitations Functions When an arithmetic operator is encountered, if the type is not determined by another mean, the operator refers to integers. > fun sqr x = x x; val sqr = fn: int > int > fun sqr x = (x: real ) x; val sqr = fn: real > real; > fun sqr (x: real ) = x x; val sqr = fn: real > real; > fun sqr x: real = x x; ( (sqr x): real ) val sqr = fn: real > real; > fun sqr x = x:real x; Error Type constructor (x) has not been declared Found near x : real x Jean-Noël Monette (UU) Lecture 2: The Basis of SML 39 / 73

Functions Polymorphism limitations (cont.) There is a complication with type variables. Fortunately the compiler will warn you about it. > fun id x = x; val id = fn: a > a > val iidd = id id ; Warning The type of (iidd) contains a free type variable. Setting it to a unique monotype. val iidd = fn: a > a > iidd 1; Error Type error in function application. Function: iidd : a > a Argument: 1 : int Reason: Can t unify int ( In Basis ) with a ( Constructed from a free type variable. ) ( Different type constructors ) Jean-Noël Monette (UU) Lecture 2: The Basis of SML 40 / 73

Specifications of functions Table of Contents 1 Types and type inference 2 Literals and built-in operators 3 Value declarations 4 Tuples and record 5 Functions 6 Specifications of functions 7 Pattern Matching 8 Local declarations 9 New operators 10 Side Effects 11 Exceptions 12 Modules 13 Comparison with Imperative Programming 14 Exercises Jean-Noël Monette (UU) Lecture 2: The Basis of SML 41 / 73

Specifications of functions Specifying Functions Function name and argument Type of the function: types of the argument and result (can be infered by the compiler). Pre-condition on the argument: If the pre-condition does not hold, then the function may return any result! If the pre-condition does hold, then the function must return a result satisfying the post-condition! Post-condition on the result: its description and meaning Side effects (if any): printing of the result,... Examples and counter-examples (if useful) Jean-Noël Monette (UU) Lecture 2: The Basis of SML 42 / 73

Specifications of functions Specification: Example ( PRE: n >= 0 POST: sum {0 <= i <= n}(i) ) fun triangle n =... Beware: The post-condition and side effects should involve all the components of the argument Jean-Noël Monette (UU) Lecture 2: The Basis of SML 43 / 73

Specifications of functions Role of well-chosen examples and counter-examples In theory,they are redundant with the pre/post-conditions. In practice: They often provide an intuitive understanding that no assertion or definition could achieve They often help eliminate risks of ambiguity in the pre/post-conditions by illustrating delicate issues If they contradict the pre/post-conditions, then we know that something is wrong somewhere! ( PRE: (none) POST: the largest integer m such that m <= n EXAMPLES: floor(23.65) = 23, floor( 23.65) = 24 COUNTER EXAMPLE: floor( 23.65) <> 23 ) fun floor n =... Jean-Noël Monette (UU) Lecture 2: The Basis of SML 44 / 73

Pattern Matching Table of Contents 1 Types and type inference 2 Literals and built-in operators 3 Value declarations 4 Tuples and record 5 Functions 6 Specifications of functions 7 Pattern Matching 8 Local declarations 9 New operators 10 Side Effects 11 Exceptions 12 Modules 13 Comparison with Imperative Programming 14 Exercises Jean-Noël Monette (UU) Lecture 2: The Basis of SML 45 / 73

Pattern Matching Pattern Matching > val x = (18, true ); val x = (18,true ): int bool > val (n,b) = x; val n = 18: int val b = true: bool The left-hand side of a value declaration is called a pattern. The value on the right must respect that pattern. An identifier can match anything. matches anything and has no name. > val (n, ) = x; val n = 18: int > val (18,b) = x; val b = true; > val (17,b) = x; Exception Bind raised Jean-Noël Monette (UU) Lecture 2: The Basis of SML 46 / 73

Pattern Matching Pattern Matching (cont.) Each identifier can occur at most once in a pattern (linearity) as introduces pattern alias for identifiers. > val t = ((3.5, true ), 4); val t = ((3.5, true ), 4): ( real bool) int > val (d as (a,b), c) = t; val a = 3.5: real val b = true: bool val c = 4: int val d = (3.5, true ): real bool > val (d,c) = t; > val ((a,b),c) = t; > val s as (d,c) = t; > val s as u as v = t; > val (t,d) = t; ( t is bound to a different value after this ) Jean-Noël Monette (UU) Lecture 2: The Basis of SML 47 / 73

Pattern or not Pattern Pattern Matching Not every expression can be a pattern: Intuitively, only an irreducible expression can be a pattern. literals, identifiers, constructors Real constants can not be involved in patterns. Function calls can not be involved in patterns. val nil = x; ( OK ) val niil = x; ( OK, but attention ) val y :: ys = x;( OK ) val a+1 = x; ( NOT OK ) val abs y = x; ( NOT OK ) val 0.0 =x; ( NOT OK ) Jean-Noël Monette (UU) Lecture 2: The Basis of SML 48 / 73

Pattern Matching Case analysis The case expression allows to match an expression against several patterns. case Expr of Pat1 => Expr1 Pat2 => Expr2... Patn => Exprn case...of... is an expression. Expr1,..., Exprn must be of the same type. Expr, Pat1,..., Patn must be of the same type. If Pati is selected, then only Expri is evaluated (lazy evaluation). Jean-Noël Monette (UU) Lecture 2: The Basis of SML 49 / 73

Case Analysis (cont.) Pattern Matching > case 17 mod 2 of 0 => even 1 => odd ; Warning Matches are not exhaustive. val it = odd : string > case 17 mod 2 of 0 => even => odd ; val it = odd : string If the patterns are not exhaustive over their type, then there is an ML warning at the declaration. If none of the patterns is applicable during an evaluation, then there is an ML pattern-matching exception. The patterns need not be mutually exclusive: If several patterns are applicable, then ML selects the first applicable pattern. Jean-Noël Monette (UU) Lecture 2: The Basis of SML 50 / 73

Pattern Matching Function with Case Analysis fun fname Pat1 = Expr1 fname Pat2 = Expr2... fname Patn = Exprn fn Pat1 => Expr1 Pat2 => Expr2... Patn => Exprn Jean-Noël Monette (UU) Lecture 2: The Basis of SML 51 / 73

Pattern Matching Exercices How to express if-then-else as a case-of expression? Write a function of two integer arguments that returns the number of arguments that are equal to zero. Jean-Noël Monette (UU) Lecture 2: The Basis of SML 52 / 73

Local declarations Table of Contents 1 Types and type inference 2 Literals and built-in operators 3 Value declarations 4 Tuples and record 5 Functions 6 Specifications of functions 7 Pattern Matching 8 Local declarations 9 New operators 10 Side Effects 11 Exceptions 12 Modules 13 Comparison with Imperative Programming 14 Exercises Jean-Noël Monette (UU) Lecture 2: The Basis of SML 53 / 73

Local declarations Local declarations It is possible to declare variables locally with let... in... end. The variables declared between let and in only exist inside the expression. They hide any other declaration of the same identifier. > val x = 5.5; > val y = let val x = 1 in x + 10 end; > (x,y); val it = (5.5,11): real int ; Jean-Noël Monette (UU) Lecture 2: The Basis of SML 54 / 73

Local declarations Local declarations (cont.) The let value is computed only once. Functions can also be local. > fun discount unitprice quantity = let val price = unitprice real ( quantity) in if price < 100.0 then price else price 0.95 end; > fun leapyear year = let fun isdivisible b = year mod b = 0 in isdivisible 4 andalso (not ( isdivisible 100) orelse isdivisible 400) end; Jean-Noël Monette (UU) Lecture 2: The Basis of SML 55 / 73

New operators Table of Contents 1 Types and type inference 2 Literals and built-in operators 3 Value declarations 4 Tuples and record 5 Functions 6 Specifications of functions 7 Pattern Matching 8 Local declarations 9 New operators 10 Side Effects 11 Exceptions 12 Modules 13 Comparison with Imperative Programming 14 Exercises Jean-Noël Monette (UU) Lecture 2: The Basis of SML 56 / 73

New operators New Infix Operators It is possible to define new operators. infix n id makes id an infix operator with precedence n rinfix n id does the same but with right association. nonfix id makes return to the prefix form. Beware: operators take a pair of argument (no curried form). Still possible to call an infix operator in prefix form with op. > fun x (a,b) = a b; > infix 5 x; > 2 x 4; val it = 8: int > op + (2,4); val it = 6: int Jean-Noël Monette (UU) Lecture 2: The Basis of SML 57 / 73

Side Effects Table of Contents 1 Types and type inference 2 Literals and built-in operators 3 Value declarations 4 Tuples and record 5 Functions 6 Specifications of functions 7 Pattern Matching 8 Local declarations 9 New operators 10 Side Effects 11 Exceptions 12 Modules 13 Comparison with Imperative Programming 14 Exercises Jean-Noël Monette (UU) Lecture 2: The Basis of SML 58 / 73

Side Effects Side Effects Like most functional languages, ML has some functions with side effects: Input / output Variables (in the imperative-programming sense) Explicit references Tables (in the imperative-programming sense) Imperative-programming-style control structures (sequence, iteration,... ) In these lectures we only consider printing. Jean-Noël Monette (UU) Lecture 2: The Basis of SML 59 / 73

The print function Side Effects Type: print string unit Side effect: The argument of print is printed on the screen > fun welcome name = print ( Hello, ˆ name ˆ!\n ) ; val welcome = fn : string > unit > welcome world ; Hello, world! val it = () : unit Jean-Noël Monette (UU) Lecture 2: The Basis of SML 60 / 73

Side Effects Sequential composition Sequential composition is necessary when one wants to print intermediate results. fun relerror a b = let val diff = abs (a b) in ( print (Real. tostring diff ) ; print \n ; diff / a ) end; Sequential composition is an expression of the form ( Expr 1 ; Expr 2 ;... ; Expr n ) The value of this expression is the value of Expr n. Jean-Noël Monette (UU) Lecture 2: The Basis of SML 61 / 73

Exceptions Table of Contents 1 Types and type inference 2 Literals and built-in operators 3 Value declarations 4 Tuples and record 5 Functions 6 Specifications of functions 7 Pattern Matching 8 Local declarations 9 New operators 10 Side Effects 11 Exceptions 12 Modules 13 Comparison with Imperative Programming 14 Exercises Jean-Noël Monette (UU) Lecture 2: The Basis of SML 62 / 73

Exceptions Exceptions Execution can be interrupted immediately upon an error > 1 div 0; Exception Div raised Exceptions can be caught: > 1 div 0 handle Div => 42; val it = 42: int You can declare and throw your own exceptions: exception errordiv; fun safediv a b = if b = 0 then raise errordiv else a div b; Jean-Noël Monette (UU) Lecture 2: The Basis of SML 63 / 73

Modules Table of Contents 1 Types and type inference 2 Literals and built-in operators 3 Value declarations 4 Tuples and record 5 Functions 6 Specifications of functions 7 Pattern Matching 8 Local declarations 9 New operators 10 Side Effects 11 Exceptions 12 Modules 13 Comparison with Imperative Programming 14 Exercises Jean-Noël Monette (UU) Lecture 2: The Basis of SML 64 / 73

Modules Modules Modules group related functionalities together. SML defines a basic library in standard modules. Access a function inside a module by typing the name of the module followed by the name of the function. Some functions are available at the top-level. Int. tostring Int.+ Int.abs Real.Math.sqrt Jean-Noël Monette (UU) Lecture 2: The Basis of SML 65 / 73

Comparison with Imperative Programming Table of Contents 1 Types and type inference 2 Literals and built-in operators 3 Value declarations 4 Tuples and record 5 Functions 6 Specifications of functions 7 Pattern Matching 8 Local declarations 9 New operators 10 Side Effects 11 Exceptions 12 Modules 13 Comparison with Imperative Programming 14 Exercises Jean-Noël Monette (UU) Lecture 2: The Basis of SML 66 / 73

Comparison with Imperative Programming Functional languages vs. imperative languages Example: greatest common divisor of natural numbers We know from Euclid that: gcd(0, n) = n if n > 0 gcd(m, n) = gcd(n mod m, m) if m > 0 Jean-Noël Monette (UU) Lecture 2: The Basis of SML 67 / 73

Comparison with Imperative Programming In an imperative language (C) int gcd(int m, int n) { /* PRE: m, n >= 0 and m+n > 0 POST: the greatest common divisor of m and n */ } int a=m, b=n, preva; /* INVARIANT: gcd(m,n) = gcd(a,b) */ while (a!= 0) { preva = a; a = b % a; b = preva; } return b; Jean-Noël Monette (UU) Lecture 2: The Basis of SML 68 / 73

Comparison with Imperative Programming In a functional language (SML) ( PRE: m,n >= 0 and m+n > 0 POST: the greatest common divisor of m,n ) fun gcd1 (m, n) = if m = 0 then n else gcd1 (n mod m, m) fun gcd2 (0, n) = n gcd2 (m, n) = gcd2 (n mod m, m) Jean-Noël Monette (UU) Lecture 2: The Basis of SML 69 / 73

Comparison with Imperative Programming Features of imperative programs Close to the hardware Sequence of instructions Modification of variables (memory cells) Test of variables (memory cells) Transformation of states (automata) Construction of programs Describe what has to be computed Organise the sequence of computations into steps Organise the variables Correctness Specifications by pre/post-conditions Loop invariants Symbolic execution Expressions: f(z) + x / 2 can be different from x / 2 + f(z) namely when f modifies the value of x (by side effect) Variables: The assignment x = x + 1 modifies a memory cell as a side effect Jean-Noël Monette (UU) Lecture 2: The Basis of SML 70 / 73

Comparison with Imperative Programming Features of functional programs Execution by evaluation of expressions Basic tools: expressions and recursion Handling of values (rather than states) The expression e 1 + e 2 always has the same value as e 2 + e 1 Identifiers Value via a declaration No assignment, no modification Recursion: series of values from recursive calls Functions are first-class, they can be arguments to other functions. Jean-Noël Monette (UU) Lecture 2: The Basis of SML 71 / 73

Exercises Table of Contents 1 Types and type inference 2 Literals and built-in operators 3 Value declarations 4 Tuples and record 5 Functions 6 Specifications of functions 7 Pattern Matching 8 Local declarations 9 New operators 10 Side Effects 11 Exceptions 12 Modules 13 Comparison with Imperative Programming 14 Exercises Jean-Noël Monette (UU) Lecture 2: The Basis of SML 72 / 73

Exercices Exercises Write a function h that takes a time as a pair (hour, minutes) and returns the number of minutes elapsed since midnight. Raise an exception if the pair does not represent a legit time. Make this function infix to be able to call it like 16 h 40 (should return 1000). Write a function that returns a boolean telling if a date (year, month, day) exists or not. Write a function that takes an integer between 1 and 7 and returns the day of the week (1 is Monday, 7 is Sunday). Write a function of an integer that returns 0, -1 or 1 if the argument is respectively equal to, smaller or larger than zero. Use this to reimplement abs. Write a function surround tag content, whose result is <tag>content</tag>, with the parameters names replaced. Use this function to create the functions makeparagraph content (<p> in html), and makeheader n content (<h1>...<h6> in html). Jean-Noël Monette (UU) Lecture 2: The Basis of SML 73 / 73