COSE212: Programming Languages. Lecture 3 Functional Programming in OCaml

Similar documents
COSE212: Programming Languages. Lecture 4 Recursive and Higher-Order Programming

Homework 3 COSE212, Fall 2018

Introduction to ML. Mooly Sagiv. Cornell CS 3110 Data Structures and Functional Programming

CS558 Programming Languages

CS558 Programming Languages

CS558 Programming Languages

CSCI-GA Scripting Languages

Introduction to ML. Mooly Sagiv. Cornell CS 3110 Data Structures and Functional Programming

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

Introduction to ML. Mooly Sagiv. Cornell CS 3110 Data Structures and Functional Programming

CMSC 330: Organization of Programming Languages

Lecture: Functional Programming

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

A Fourth Look At ML. Chapter Eleven Modern Programming Languages, 2nd ed. 1

Overloading, Type Classes, and Algebraic Datatypes

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

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

CS 11 Ocaml track: lecture 2

Topic 7: Algebraic Data Types

CSCE 314 Programming Languages

Programming Languages Fall 2013

CMSC 330: Organization of Programming Languages. OCaml Data Types

According to Larry Wall (designer of PERL): a language by geniuses! for geniuses. Lecture 7: Haskell. Haskell 98. Haskell (cont) - Type-safe!

Software System Design and Implementation

Functional Programming. Pure Functional Programming

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

Chapter 15. Functional Programming. Topics. Currying. Currying: example. Currying: example. Reduction

Lists. Michael P. Fourman. February 2, 2010

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

Functional Programming. Lecture 2: Algebra

Introduction to Objective Caml

CMSC 330: Organization of Programming Languages

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

Data Types The ML Type System

CSE 3302 Programming Languages Lecture 8: Functional Programming

Type Checking and Type Inference

Introduction to OCaml

Haskell 98 in short! CPSC 449 Principles of Programming Languages

G Programming Languages - Fall 2012

Lecture 12: Data Types (and Some Leftover ML)

Closures. Mooly Sagiv. Michael Clarkson, Cornell CS 3110 Data Structures and Functional Programming

Lecture #23: Conversion and Type Inference

Introduction to Functional Programming

CS558 Programming Languages

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

CSC312 Principles of Programming Languages : Functional Programming Language. Copyright 2006 The McGraw-Hill Companies, Inc.

A First Look at ML. Chapter Five 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.

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

Programming Languages

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

CS 320: Concepts of Programming Languages

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

CSE 341 Section 5. Winter 2018

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

COP4020 Programming Assignment 1 - Spring 2011

Programming Languages Lecture 14: Sum, Product, Recursive Types

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

CMSC 330, Fall 2013, Practice Problems 3

PROGRAMMING IN HASKELL. Chapter 2 - First Steps

So what does studying PL buy me?

Programming in Haskell Aug-Nov 2015

SML A F unctional Functional Language Language Lecture 19

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

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

COSE212: Programming Languages. Lecture 0 Course Overview

Lecture 19: Functions, Types and Data Structures in Haskell

CMSC 330: Organization of Programming Languages. Rust Basics

Chapter 1. Fundamentals of Higher Order Programming

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

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

Functional Programming and Haskell

Case by Case. Chapter 3

Tail Calls. CMSC 330: Organization of Programming Languages. Tail Recursion. Tail Recursion (cont d) Names and Binding. Tail Recursion (cont d)

Programming Languages

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

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

CS 11 Haskell track: lecture 1

More Lambda Calculus and Intro to Type Systems

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

Closures. Mooly Sagiv. Michael Clarkson, Cornell CS 3110 Data Structures and Functional Programming

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

CPS 506 Comparative Programming Languages. Programming Language Paradigm

CSc 372 Comparative Programming Languages. 4 : Haskell Basics

ITT8060: Advanced Programming (in F#)

Typed Racket: Racket with Static Types

Whereweare. CS-XXX: Graduate Programming Languages. Lecture 7 Lambda Calculus. Adding data structures. Data + Code. What about functions

Programming Languages

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

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

Types, Type Inference and Unification

COP4020 Programming Languages. Functional Programming Prof. Robert van Engelen

CMSC 330, Fall 2013, Practice Problem 3 Solutions

CSCE 314 Programming Languages

Programming Paradigms and Languages Introduction to Haskell. dr Robert Kowalczyk WMiI UŁ

LECTURE 16. Functional Programming

Introduction to OCaml

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

CS321 Languages and Compiler Design I Winter 2012 Lecture 13

CSE 505: Concepts of Programming Languages

Transcription:

COSE212: Programming Languages Lecture 3 Functional Programming in OCaml Hakjoo Oh 2017 Fall Hakjoo Oh COSE212 2017 Fall, Lecture 3 September 18, 2017 1 / 44

Why learn ML? Learning ML is a good way of experiencing modern language features: functional programming: scala, java8, haskell, python, JavaScript, etc static type system: scala, java, haskell, etc automatic type inference: scala, haskell, etc pattern matching: scala, etc algebraic data types, module system, etc Hakjoo Oh COSE212 2017 Fall, Lecture 3 September 18, 2017 2 / 44

Basics of the Language Expressions Names Functions Pattern matching Type inference Tuples and lists Data types Exceptions Write and run all examples in the slides by yourself! Hakjoo Oh COSE212 2017 Fall, Lecture 3 September 18, 2017 3 / 44

An OCaml Program is an Expression Statement and expressions: A statement does something. An expression evaluates to a value. Programming languages can be classified into statement-oriented: C, C++, Java, Python, JavaScript, etc often called imperative languages expression-oriented: ML, Haskell, Scala, Lisp, etc often called functional languages Hakjoo Oh COSE212 2017 Fall, Lecture 3 September 18, 2017 4 / 44

Arithmetic Expressions Arithmetic expressions evaluate to numbers: e.g., 1+2*3, 1+5, 7 Try to evaluate expressions in the REPL: # 1+2*3;; - : int = 7 Arithmetic operators on integers: a + b a - b a * b a / b a mod b addition subtraction multiplication divide a by b, returning the whole part divide a by b, returning the remaining part Hakjoo Oh COSE212 2017 Fall, Lecture 3 September 18, 2017 5 / 44

Boolean Expressions Boolean expressions evaluate to boolean values (i.e., true, false). Try to evaluate boolean expressions: # true;; - : bool = true # true;; - : bool = true # 1 > 2;; - : bool = false Comparison operators produces boolean values: a = b a <> b a < b a <= b a > b a >= b true if a and b are equal true if a and b are not equal true if a is less than b true if a is less than or equal to b true if a is greater than b true if a is greater than or equal to b Hakjoo Oh COSE212 2017 Fall, Lecture 3 September 18, 2017 6 / 44

Boolean Operators Boolean expressions are combined by boolean operators: # true && false;; - : bool = false # true false;; - : bool = true # (2 > 1) && (3 > 2);; - : bool = true Hakjoo Oh COSE212 2017 Fall, Lecture 3 September 18, 2017 7 / 44

ML is a Statically Typed Language If you try to evaluate an expression that does not make sense, OCaml rejects and does not evaluate the program: e.g., # 1 + true;; Error: This expression has type bool but an expression was expected of type int Hakjoo Oh COSE212 2017 Fall, Lecture 3 September 18, 2017 8 / 44

cf) Static Types and Dynamic Types Programming languages are classified into: Statically typed languages: type checking is done at compile-time. type errors are detected before program executions C, C++, Java, ML, Scala, etc Dynamically typed languages: type checking is done at run-time. type errors are detected during program executions Python, JavaScript, Ruby, Lisp, etc Statically typed languages are further classified into: Type-safe languages guarantee that compiled programs do not have type errors at run-time. All type errors are detected at compile time. Compiled programs do not stuck. ML, Haskell, Scala Unsafe languages do not provide such a guarantee. Some type errors remain at run-time. C, C++ Hakjoo Oh COSE212 2017 Fall, Lecture 3 September 18, 2017 9 / 44

Which one is better? Statically typed languages: (+) Type errors are caught early in the development cycle. (+) Program execution is efficient by omitting runtime checks. ( ) Less flexible than dynamic languages. Dynamically typed languages: ( ) Type errors appear at run-time, often unexpectedly. (+) Provide more flexible language features. (+) Easy and fast prototyping. Hakjoo Oh COSE212 2017 Fall, Lecture 3 September 18, 2017 10 / 44

Conversion between Different Types In OCaml, different types of values are distinguished: # 3 + 2.0;; Error: This expression has type float but an expression was expected of type int Types must be explicitly converted: # 3 + int_of_float 2.0;; - : int = 5 Operators for floating point numbers: # 1.2 +. 2.3;; - : float = 3.5 # 1.5 *. 2.0;; - : float = 3. # float_of_int 1 +. 2.2;; - : float = 3.2 Hakjoo Oh COSE212 2017 Fall, Lecture 3 September 18, 2017 11 / 44

Other Primitive Values OCaml provides six primitive values: integers, booleans, floating point numbers, characters, strings, and unit. # c ;; - : char = c # "cose212";; - : string = "cose212" # ();; - : unit = () Hakjoo Oh COSE212 2017 Fall, Lecture 3 September 18, 2017 12 / 44

Conditional Expressions if be then e 1 else e 2 If be is true, the value of the conditional expression is the value of e 1. If be is false, the value of the expression is the value of e 2. # if 2 > 1 then 0 else 1;; - : int = 0 # if 2 < 1 then 0 else 1;; - : int = 1 be must be a boolean expression. types of e 1 and e 2 must be equivalent. # if 1 then 1 else 2;; Error:... # if true then 1 else true;; Error:... # if true then true else false;; - : bool = true Hakjoo Oh COSE212 2017 Fall, Lecture 3 September 18, 2017 13 / 44

Names and Functions Create a global variable with the let keyword: # let x = 3 + 4;; val x : int = 7 We say a variable x is bound to value 7. # let y = x + x;; val y : int = 14 Create a local variable with let... let x = e 1 in e 2 in... construct: x is bound to the value of e1 the scope of x is e2 the value of e2 becomes the value of the entire expression Hakjoo Oh COSE212 2017 Fall, Lecture 3 September 18, 2017 14 / 44

Examples # let a = 1 in a;; - : int = 1 # let a = 1 in a * 2;; - : int = 2 # let a = 1 in let b = a + a in let c = b + b in c + c;; - : int = 8 # let d = let a = 1 in let b = a + a in let c = b + b in c + c;; val d : int = 8 Hakjoo Oh COSE212 2017 Fall, Lecture 3 September 18, 2017 15 / 44

Functions Define a function with let: # let square x = x * x;; val square : int -> int = <fun> Apply the function: # square 2;; - : int = 4 # square (2 + 5);; - : int = 49 # square (square 2);; - : int = 16 The body can be any expression: # let neg x = if x < 0 then true else false;; val neg : int -> bool = <fun> # neg 1;; - : bool = false # neg (-1);; - : bool = true Hakjoo Oh COSE212 2017 Fall, Lecture 3 September 18, 2017 16 / 44

Functions Functions with multiple arguments: # let sum_of_squares x y = (square x) + (square y);; val sum_of_squares : int -> int -> int = <fun> # sum_of_squares 3 4;; - : int = 25 Recursive functions are defined with let rec construct: # let rec factorial a = if a = 1 then 1 else a * factorial (a - 1);; val factorial : int -> int = <fun> # factorial 5;; - : int = 120 Hakjoo Oh COSE212 2017 Fall, Lecture 3 September 18, 2017 17 / 44

Nameless Functions Many modern programming languages provide nameless functions, e.g., ML, Scala, Java8, JavaScript, Python, etc. In OCaml, a function can be defined without names: # fun x -> x * x;; - : int -> int = <fun> Called nameless or anonymous functions. Apply nameless function as usual: # (fun x -> x * x) 2;; - : int = 4 A variable can be bound to functions: # let square = fun x -> x * x;; val square : int -> int = <fun> The followings are equivalent: let square = fun x -> x * x let square x = x * x Hakjoo Oh COSE212 2017 Fall, Lecture 3 September 18, 2017 18 / 44

Example: Square Roots with Newton s Method We implement the function sqrt : float > float using Newton s method. To compute sqrt(x), ex) Start with an initial guess y for the value of the square root of x (pick y = 1). Repeatedly improve the estimate by taking the mean of y and x/y. Estimation Quotient Mean 1 2/1 = 2 1.5 1.5 2/1.5 = 1.3333 1.4167 1.4167 2/1.4167 = 1.4118 1.4142 1.4142...... Hakjoo Oh COSE212 2017 Fall, Lecture 3 September 18, 2017 19 / 44

Example: Square Roots with Newton s Method let is_good_enough guess x = abs_float (guess *. guess -. x) < 0.001 let improve guess x = (guess +. x /. guess) /. 2.0 let rec sqrt_iter guess x = if is_good_enough guess x then guess else sqrt_iter (improve guess x) x let sqrt x = sqrt_iter 1.0 x Hakjoo Oh COSE212 2017 Fall, Lecture 3 September 18, 2017 20 / 44

Example: Square Roots with Newton s Method # #use "sqrt.ml";; val is_good_enough : float -> float -> bool = <fun> val improve : float -> float -> float = <fun> val sqrt_iter : float -> float -> float = <fun> val sqrt : float -> float = <fun> # sqrt 9.0;; - : float = 3.00009155413138 # sqrt (sqrt 2.0 +. sqrt 3.0);; - : float = 1.77392790232078923 # sqrt 1000.0 *. sqrt 1000.0;; - : float = 1000.00036992436605 Hakjoo Oh COSE212 2017 Fall, Lecture 3 September 18, 2017 21 / 44

Functions are First-Class in OCaml In programming languages, a value is first-class, if the value can be stored in a variable, passed as an argument of a function, and returned from other functions. A language is often called functional, if functions are first class values, e.g., ML, Scala, Java8, JavaScript, Python, Lisp, etc. Hakjoo Oh COSE212 2017 Fall, Lecture 3 September 18, 2017 22 / 44

Functions are First-Class in OCaml Functions can be stored in variables: # let square = fun x -> x * x;; # square 2;; - : int = 4 Functions can be passed to other functions: # let sum_if_true test first second = (if test first then first else 0) + (if test second then second else 0);; val sum_if_true : (int -> bool) -> int -> int -> int = <fun> # let even x = x mod 2 = 0;; val even : int -> bool = <fun> # sum_if_true even 3 4;; - : int = 4 # sum_if_true even 2 4;; - : int = 6 Hakjoo Oh COSE212 2017 Fall, Lecture 3 September 18, 2017 23 / 44

Functions are First-Class in OCaml Functions can be also returned from a procedure: # let plus_a a = fun b -> a + b;; val plus_a : int -> int -> int = <fun> # let f = plus_a 3;; val f : int -> int = <fun> # f 1;; - : int = 4 # f 2;; - : int = 5 Functions that manipulate functions are called higher-order functions. i.e., functions that take as argument functions or return functions greatly increase the expressiveness of the language Hakjoo Oh COSE212 2017 Fall, Lecture 3 September 18, 2017 24 / 44

Pattern Matching An elegant way of doing case analysis. E.g., using pattern-matching, the factorial function let rec factorial a = if a = 1 then 1 else a * factorial (a - 1) can be written as follows: let factorial a = match a with 1 -> 1 _ -> a * factorial (a - 1) Hakjoo Oh COSE212 2017 Fall, Lecture 3 September 18, 2017 25 / 44

Pattern Matching The nested if-then-else expression let isabc c = if c = a then true else if c = b then true else if c = c then true else false can be written using pattern matching: let isabc c = match c with a -> true b -> true c -> true _ -> false or simply, let isabc c = match c with a b c -> true _ -> false Hakjoo Oh COSE212 2017 Fall, Lecture 3 September 18, 2017 26 / 44

Type Inference In C or Java, types must be annotated: public static int f(int n) { int a = 2; return a * n; } In OCaml, type annotations are not mandatory: # let f n = let a = 2 in a * n;; val f : int -> int = <fun> Hakjoo Oh COSE212 2017 Fall, Lecture 3 September 18, 2017 27 / 44

Type Inference OCaml can infer types, no matter how complex the program is: # let sum_if_true test first second = (if test first then first else 0) + (if test second then second else 0);; val sum_if_true : (int -> bool) -> int -> int -> int = <fun> OCaml compiler infers the type through the following reasoning steps: 1 the types of first and second must be int, because both branches of a conditional expression must have the same type, 2 the type of test is a function type α β, because test is used as a function, 3 α must be of int, because test is applied to first, a value of int, 4 β must be of bool, because conditions must be boolean expressions, 5 the return value of the function has type int, because the two conditional expressions are of int and their addition gives int. Hakjoo Oh COSE212 2017 Fall, Lecture 3 September 18, 2017 28 / 44

Type Annotation Explicit type annotations are possible: # let sum_if_true (test : int -> bool) (x : int) (y : int) : int = (if test x then x else 0) + (if test y then y else 0);; val sum_if_true : (int -> bool) -> int -> int -> int = <fun> If the annotation is wrong, OCaml finds the error and report it: # let sum_if_true (test : int -> int) (x : int) (y : int) : int = (if test x then x else 0) + (if test y then y else 0);; Error: The expression (test x) has type int but an expression was expected of type bool Hakjoo Oh COSE212 2017 Fall, Lecture 3 September 18, 2017 29 / 44

Polymorphic Types What is the type of the program? let id x = x See how OCaml infers its type: # let id x = x;; val id : a -> a = <fun> The function works for values of any type: # id 1;; - : int = 1 # id "abc";; - : string = "abc" # id true;; - : bool = true Such a function is called polymorphic and a is a type variable. Hakjoo Oh COSE212 2017 Fall, Lecture 3 September 18, 2017 30 / 44

Polymorphic Types Quiz) What is the type of the function? let first_if_true test x y = if test x then x else y Hakjoo Oh COSE212 2017 Fall, Lecture 3 September 18, 2017 31 / 44

Tuples An ordered collection of values, each of which can be a different types, e.g., # let x = (1, "one");; val x : int * string = (1, "one") # let y = (2, "two", true);; val y : int * string * bool = (2, "two", true) Extract each component using pattern-matching: # let fst p = match p with (x,_) -> x;; val fst : a * b -> a = <fun> # let snd p = match p with (_,x) -> x;; val snd : a * b -> b = <fun> or equivalently, # let fst (x,_) = x;; val fst : a * b -> a = <fun> # let snd (_,x) = x;; val snd : a * b -> b = <fun> Hakjoo Oh COSE212 2017 Fall, Lecture 3 September 18, 2017 32 / 44

Tuples Patterns can be used in let: # let p = (1, true);; val p : int * bool = (1, true) # let (x,y) = p;; val x : int = 1 val y : bool = true Hakjoo Oh COSE212 2017 Fall, Lecture 3 September 18, 2017 33 / 44

Lists A finite sequence of elements, each of which has the same type, e.g., is a list of integers: [1; 2; 3] # [1; 2; 3];; - : int list = [1; 2; 3] Note that all elements must have the same type, e.g., [1; true; 2] is not a list, the elements are ordered, e.g., [1; 2; 3] [2; 3; 1], and the first element is called head, the rest tail. []: the empty list, i.e., nil. What are head and tail of []? [5]: a list with a single element. What are head and tail of [5]? Hakjoo Oh COSE212 2017 Fall, Lecture 3 September 18, 2017 34 / 44

List Examples # [1;2;3;4;5];; - : int list = [1; 2; 3; 4; 5] # ["OCaml"; "Java"; "C"];; - : string list = ["OCaml"; "Java"; "C"] # [(1,"one"); (2,"two"); (3,"three")];; - : (int * string) list = [(1, "one"); (2, "two"); (3, "three")] # [[1;2;3];[2;3;4];[4;5;6]];; - : int list list = [[1; 2; 3]; [2; 3; 4]; [4; 5; 6]] # [1;"OCaml";3] ;; Error: This expression has type string but an expression was expected of type int Hakjoo Oh COSE212 2017 Fall, Lecture 3 September 18, 2017 35 / 44

List Operators :: (cons): add a single element to the front of a list, e.g., # 1::[2;3];; - : int list = [1; 2; 3] # 1::2::3::[];; - : int list = [1; 2; 3] ([1; 2; 3] is a shorthand for 1::2::3::[]) @ (append): combine two lists, e.g., # [1; 2] @ [3; 4; 5];; - : int list = [1; 2; 3; 4; 5] Hakjoo Oh COSE212 2017 Fall, Lecture 3 September 18, 2017 36 / 44

Patterns for Lists Pattern matching is useful for manipulating lists. A function to check if a list is empty: # let isnil l = match l with [] -> true _ -> false;; val isnil : a list -> bool = <fun> # isnil [1];; - : bool = false # isnil [];; - : bool = true Hakjoo Oh COSE212 2017 Fall, Lecture 3 September 18, 2017 37 / 44

Patterns for Lists A function that computes the length of lists: # let rec length l = match l with [] -> 0 h::t -> 1 + length t;; val length : a list -> int = <fun> # length [1;2;3];; - : int = 3 We can replace pattern h by _: let rec length l = match l with [] -> 0 _::t -> 1 + length t;; Hakjoo Oh COSE212 2017 Fall, Lecture 3 September 18, 2017 38 / 44

Data Types If data elements are finite, just enumerate them, e.g., days : # type days = Mon Tue Wed Thu Fri Sat Sun;; type days = Mon Tue Wed Thu Fri Sat Sun Construct values of the type: # Mon;; - : days = Mon # Tue;; - : days = Tue A function that manipulates the defined data: # let nextday d = match d with Mon -> Tue Tue -> Wed Wed -> Thu Thu -> Fri Fri -> Sa Sat -> Sun Sun -> Mon ;; val nextday : days -> days = <fun> # nextday Mon;; - : days = Tue Hakjoo Oh COSE212 2017 Fall, Lecture 3 September 18, 2017 39 / 44

Data Types Constructors can be associated with values, e.g., # type shape = Rect of int * int Circle of int;; type shape = Rect of int * int Circle of int Construct values of the type: # Rect (2,3);; - : shape = Rect (2, 3) # Circle 5;; - : shape = Circle 5 A function that manipulates the data: # let area s = match s with Rect (w,h) -> w * h Circle r -> r * r * 3;; val area : shape -> int = <fun> # area (Rect (2,3));; - : int = 6 # area (Circle 5);; - : int = 75 Hakjoo Oh COSE212 2017 Fall, Lecture 3 September 18, 2017 40 / 44

Data Types Inductive data types, e.g., # type mylist = Nil List of int * mylist;; type mylist = Nil List of int * mylist Construct values of the type: # Nil;; - : mylist = Nil # List (1, Nil);; - : mylist = List (1, Nil) # List (1, List (2, Nil));; - : mylist = List (1, List (2, Nil)) A function that manipulates the data: # let rec mylength l = match l with Nil -> 0 List (_,l ) -> 1 + mylength l ;; val mylength : mylist -> int = <fun> # mylength (List (1, List (2, Nil)));; - : int = 2 Hakjoo Oh COSE212 2017 Fall, Lecture 3 September 18, 2017 41 / 44

Exceptions An exception means a run-time error: e.g., # let div a b = a / b;; val div : int -> int -> int = <fun> # div 10 5;; - : int = 2 # div 10 0;; Exception: Division_by_zero. The exception can be handled with try... # let div a b = try a / b with Division_by_zero -> 0;; val div : int -> int -> int = <fun> # div 10 5;; - : int = 2 # div 10 0;; - : int = 0 with constructs. Hakjoo Oh COSE212 2017 Fall, Lecture 3 September 18, 2017 42 / 44

Exceptions User-defined exceptions: e.g., # exception Problem;; exception Problem # let div a b = if b = 0 then raise Problem else a / b;; val div : int -> int -> int = <fun> # div 10 5;; - : int = 2 # div 10 0;; Exception: Problem. # try div 10 0 with Problem -> 0;; - : int = 0 Hakjoo Oh COSE212 2017 Fall, Lecture 3 September 18, 2017 43 / 44

Summary We ve gone through the basics of OCaml programming: Expressions Names Functions Pattern matching Type inference Tuples and lists Data types Exceptions Hakjoo Oh COSE212 2017 Fall, Lecture 3 September 18, 2017 44 / 44