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

Similar documents
CMSC 330: Organization of Programming Languages. OCaml Imperative Programming

CMSC 330: Organization of Programming Languages

CMSC 330: Organization of Programming Languages. OCaml Imperative Programming

CMSC 330: Organization of Programming Languages. Basic OCaml Modules

CMSC 330: Organization of Programming Languages. OCaml Data Types

CMSC 631. Functional Programming with OCaml

OCaml Language Choices CMSC 330: Organization of Programming Languages

COMP 150-AVS Fall OCaml and Functional Programming

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

CMSC 430 Introduction to Compilers. Fall Everything (else) you always wanted to know about OCaml (but were afraid to ask)

Background. CMSC 330: Organization of Programming Languages. Useful Information on OCaml language. Dialects of ML. ML (Meta Language) Standard ML

Tuples. CMSC 330: Organization of Programming Languages. Examples With Tuples. Another Example

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

CMSC 330: Organization of Programming Languages

COSE212: Programming Languages. Lecture 3 Functional Programming in OCaml

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

CMSC 330: Organization of Programming Languages. Lets, Tuples, Records

CS 11 Ocaml track: lecture 3

Some Advanced ML Features

Object Oriented Programming in C#

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

Topics Covered Thus Far CMSC 330: Organization of Programming Languages

CMSC 330, Fall 2013, Practice Problem 3 Solutions

CS558 Programming Languages

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

QUIZ. What is wrong with this code that uses default arguments?

CMSC 330, Fall 2013, Practice Problems 3

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

CSCI-GA Scripting Languages

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

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

Ruby: Introduction, Basics

Inductive Data Types

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

CSC324 Principles of Programming Languages

Mutation. COS 326 David Walker Princeton University

Introduction to Typed Racket. The plan: Racket Crash Course Typed Racket and PL Racket Differences with the text Some PL Racket Examples

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

Topic 7: Algebraic Data Types

MARKING KEY The University of British Columbia MARKING KEY Computer Science 260 Midterm #2 Examination 12:30 noon, Thursday, March 15, 2012

CS 11 Ocaml track: lecture 2

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

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

Chapter 1 Getting Started

CMSC330. Objects, Functional Programming, and lambda calculus

Pace University. Fundamental Concepts of CS121 1

Metaprogramming assignment 3

An introduction introduction to functional functional programming programming using usin Haskell

CMSC 330: Organization of Programming Languages. Objects and Abstract Data Types

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

CSE 374 Programming Concepts & Tools

INF 212 ANALYSIS OF PROG. LANGS FUNCTION COMPOSITION. Instructors: Crista Lopes Copyright Instructors.

CS558 Programming Languages

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

Programming Languages and Techniques (CIS120)

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

CS 11 Ocaml track: lecture 4. Today: modules

CSC 533: Organization of Programming Languages. Spring 2005

CSci 4223 Lecture 12 March 4, 2013 Topics: Lexical scope, dynamic scope, closures

Welcome Back. CSCI 262 Data Structures. Hello, Let s Review. Hello, Let s Review. How to Review 8/19/ Review. Here s a simple C++ program:

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

Recap: Functions as first-class values

COSC 2P95. Procedural Abstraction. Week 3. Brock University. Brock University (Week 3) Procedural Abstraction 1 / 26

Project 6 Due 11:59:59pm Thu, Dec 10, 2015

Java Object Oriented Design. CSC207 Fall 2014

CSE413: Programming Languages and Implementation Racket structs Implementing languages with interpreters Implementing closures

Typed Racket: Racket with Static Types

Welcome Back. CSCI 262 Data Structures. Hello, Let s Review. Hello, Let s Review. How to Review 1/9/ Review. Here s a simple C++ program:

Begin at the beginning

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

ADTs & Classes. An introduction

CS 360: Programming Languages Lecture 10: Introduction to Haskell

Type Checking and Type Equality

Chapter 6 Introduction to Defining Classes

CSCI 2041: Functions, Mutation, and Arrays

CS 360: Programming Languages Lecture 12: More Haskell

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

Thinking Induc,vely. COS 326 David Walker Princeton University

Introduction to Objective Caml

UMBC CMSC 331 Final Exam

Lecture 16: Static Semantics Overview 1

These are notes for the third lecture; if statements and loops.

1 Inheritance (8 minutes, 9 points)

C++ without Classes. CMSC433, Fall 2001 Programming Language Technology and Paradigms. More C++ without Classes. Project 1. new/delete.

Exceptions and Design

CMSC 330: Organization of Programming Languages. Rust Basics

Comments are almost like C++

CS 11 Haskell track: lecture 1

THE CONCEPT OF OBJECT

PIC 10A Objects/Classes

CSE 333 Midterm Exam 7/29/13

OCaml Style Guide Fall 2017

CS112 Lecture: Working with Numbers

Types II. Hwansoo Han

Semantic Analysis. Outline. The role of semantic analysis in a compiler. Scope. Types. Where we are. The Compiler Front-End

The role of semantic analysis in a compiler

Outline. Java Models for variables Types and type checking, type safety Interpretation vs. compilation. Reasoning about code. CSCI 2600 Spring

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

10. Functions (Part 2)

Lists. Michael P. Fourman. February 2, 2010

Transcription:

OCaml Data : Organization of Programming Languages OCaml 4 Data Types & Modules So far, we ve seen the following kinds of data Basic types (int, float, char, string) Lists Ø One kind of data structure Ø A list is either [ ] or h::t, deconstructed with pattern matching Tuples Ø Let you collect data together in fixed-size pieces Functions 1 How can we build other data structures? Building everything from lists and tuples is awkward 2 User Defined Types Variation: Shapes in Java type can be used to create new names for types Useful for combinations of lists and tuples public interface Shape { public double area(); How to achieve this in Ocaml? Examples type my_type = int * (int list) ((3, [1; 2]) : my_type) type my_type2 = int * char * (int * float) ((3, a, (5, 3.0)) : my_type2) 3 class Rect implements Shape { private double width, length; Rect (double width, double length) { this.width = width; this.length = length; double area() { return width * length; class Circle implements Shape { private double radius; Circle (double radius) { this.radius = radius; double area() { return radius * radius * 3.14159; 4 1

Data Types type can also be used to create variant types Equivalent to C-style unions type shape = Rect of float * float (* width*length *) Circle of float (* radius *) Rect and Circle are value constructors Here a shape is either a Rect or a Circle Constructors must begin with uppercase letter Data Types (cont.) Unlike classes in Java, shape let area s = functions are separate from shape match s with data will later examine tradeoffs Rect (w, l) -> w *. l Circle r -> r *. r *. 3.14 area (Rect (3.0, 4.0)) area (Circle 3.0) Use pattern matching to deconstruct values s is a shape Do different things for s depending on its constructor 5 6 Data Types (cont.) type shape = Rect of float * float (* width*length *) Circle of float (* radius *) let lst = [Rect (3.0, 4.0) ; Circle 3.0] What's the type of lst? shape list What's the type of lst's first element? shape 7 Option Type type optional_int = None Some of int let add_with_default a x = match x with None -> a + 42 Some n -> a + n add_with_default 3 None (* 45 *) add_with_default 3 (Some 4) (* 7 *) This option type can work with any kind of data In fact, this option type is built into Ocaml Specify as: int option, char option, etc... 8 2

Recursive Data Types We can build up lists with variant types type 'a list = Nil Cons of 'a * 'a list let rec len = function Nil -> 0 Cons (_, t) -> 1 + (len t) len (Cons (10, Cons (20, Cons (30, Nil)))) Data Type Representations Values in a data type are stored 1. Directly as integers 2. As pointers to blocks in the heap type t = A of int B C of int * int D Won t have nice [1; 2; 3] syntax for this kind of list 9 10 Exercise: A Binary Tree Data Type Write type bin_tree for binary trees over int Trees should be ordered (binary search tree) Implement the following empty : bin_tree is_empty : bin_tree -> bool member : int -> bin_tree -> bool insert : int -> bin_tree -> bin_tree remove: int -> bin_tree -> bin_tree equal : bin_tree -> bin_tree -> bool fold : (int -> 'a -> 'a) -> bin_tree -> 'a -> 'a Modules So far, most everything we ve defined has been at the top-level of OCaml This is not good software engineering practice A better idea: Use modules to group associated types, functions, and data together Avoid polluting the top-level with unnecessary stuff For lots of sample modules, see the OCaml standard library 11 12 3

Creating A Module In OCaml module Shapes = struct type shape = Rect of float * float (* wid*len *) Circle of float (* radius *) let area = function Rect (w, l) -> w *. l Circle r -> r *. r *. 3.14 let unit_circle = Circle 1.0 end;; Creating A Module In OCaml (cont.) module Shapes = struct type shape = let area = let unit_circle = end;; unit_circle;; (* not defined *) Shapes.unit_circle;; Shapes.area (Shapes.Rect (3.0, 4.0));; open Shapes;; (* import names into curr scope *) unit_circle;; (* now defined *) 13 14 Modularity And Abstraction Another reason for creating a module is so we can hide details Ex: Binary tree module May not want to expose exact representation of binary trees This is also good software engineering practice Prevents clients from relying on details that may change Hides unimportant information Promotes local understanding (clients can t inject arbitrary data structures, only ones our functions create) Module Signatures Entry in signature Supply function types module type FOO = sig val add : int -> int -> int end;; module Foo : FOO = Give type to module struct let add x y = x + y let mult x y = x * y end;; Foo.add 3 4;; (* OK *) Foo.mult 3 4;; (* not accessible *) 15 16 4

Module Signatures (cont.) Convention: Signature names in all-caps This isn't a strict requirement, though Items can be omitted from a module signature This provides the ability to hide values The default signature for a module hides nothing You ll notice this is what OCaml gives you if you just type in a module with no signature at the top-level Abstract Types In Signatures module type SHAPES = sig type shape val area : shape -> float val unit_circle : shape val make_circle : float -> shape val make_rect : float -> float -> shape end;; module Shapes : SHAPES = struct... let make_circle r = Circle r let make_rect x y = Rect (x, y) end Now definition of shape is hidden 17 18 Abstract Types In Signatures # Shapes.unit_circl e - : Shapes.shape = <abstr> (* OCaml won t show impl *) # Shapes.Circle 1.0 Unbound Constructor Shapes.Circle # Shapes.area (Shapes.make_circ le 3.0) - : float = 29.5788 # open Shapes;; # (* doesn t make anything abstract accessible *) How does this compare to modularity in... C? C++? Java? Modules In Java Java classes are like modules Provides implementations for a group of functions But classes can also Ø Instantiate objects Ø Inherit attributes from other classes Java interfaces are like module signatures Defines a group of functions that may be used Implementation is hidden 19 20 5

Modules In C.c files are like modules Provides implementations for a group of functions.h files are like module signatures Defines a group of functions that may be used Implementation is hidden Usage is not enforced by C language Can put C code in.h file Module In Ruby Ruby explicitly supports modules Modules defined by module end Modules cannot Ø Instantiate objects Ø Derive subclasses puts Math.sqrt(4) # 2 puts Math::PI # 3.1416 include Math # open Math puts Sqrt(4) # 2 puts PI # 3.1416 21 22 OCaml Exceptions Exceptions (cont.) exception My_exception of int let f n = if n > 0 then raise (My_exception n) else raise (Failure "foo") let bar n = try f n with My_exception n -> Printf.printf "Caught %d\n" n Failure s -> Printf.printf "Caught %s\n" s Exceptions are declared with exception They may appear in the signature as well Exceptions may take arguments Just like type constructors May also have no arguments Catch exceptions with try...with... Pattern-matching can be used in with If an exception is uncaught Ø Current function exits immediately Ø Control transfers up the call chain Ø Until the exception is caught, or until it reaches the top level 23 24 6

OCaml Exceptions (cont.) Exceptions may be thrown by I/O statements Common way to detect end of file Need to decide how to handle exception Example try (input_char stdin) (* reads 1 char *) with End_of_file -> 0 (* return 0? *) try read_line () (* reads 1 line *) with End_of_file -> (* return? *) So Far, Only Functional Programming We haven t given you any way so far to change something in memory All you can do is create new values from old This actually makes programming easier in some ways Don t care whether data is shared in memory Ø Aliasing is irrelevant Provides strong support for compositional reasoning and abstraction Ø Ex: Calling a function f with argument x always produces the same result 25 26 Imperative OCaml There are three basic operations on memory: ref : 'a -> 'a ref Ø Allocate an updatable reference! : 'a ref -> 'a Ø Read the value stored in reference := : 'a ref -> 'a -> unit Ø Write to a reference let x = ref 3 (* x : int ref *) let y =!x x := 4 Comparison To L- and R-values Recall that in C/C++/Java, there s a strong distinction between l- and r-values An r-value refers to just a value, like an integer An l-value refers to a location that can be written l-value y = x; r-value A variable's meaning depends on where it appears On the right-hand side, it s an r-value, and it refers to the contents of the variable On the left-hand side of an assignment, it s an l-value, and it refers to the location the variable is stored in 27 28 7

L-Values and R-Values In C Comparison To OCaml Store 3 in location x int x, y; x = 3; y = x; Read contents of x and store in location y int x; Int y; x = 3; C let x = ref 0;; let y = ref 0;; x := 3;; (* x : int ref *) OCaml Makes no sense 3 = x; y = x; y := (!x);; 3 = x; 3 := x;; (* 3 : int; error *) Notice that x, y, and 3 all have type int In OCaml, an updatable location and the contents of the location have different types The location has a ref type 29 30 Capturing A Ref In A Closure We can use refs to make things like counters that produce a fresh number everywhere let next = let count = ref 0 in function () -> let temp =!count in count := (!count) + 1; temp;; Semicolon Needed For Side Effects Now that we can update memory, we have a use for ; and () : unit e1; e2 means evaluate e1, throw away the result, and then evaluate e2, and return the value of e2 () means no interesting result here It s only interesting to throw away values or use () if computation does something besides return a result # next ();; - : int = 0 # next ();; - : int = 1 A side effect is a visible state change Modifying memory Printing to output Writing to disk 31 32 8

Examples Semicolon ;; versus ; Definition e1 ; e2 (* evaluate e1, evaluate e2, return e2) 1 ; 2 ;; (* 2 value of 2 nd expression is returned *) (1 + 2) ; 4 ;; (* 4 value of 2 nd expression is returned *) 1 + (2 ; 4) ;; (* 5 value of 2 nd expression is returned to 1 + *) 1 + 2 ; 4 ;; (* 4 because + has higher precedence than ; *) 33 ;; ends an expression in the top-level of OCaml Use it to say: Give me the value of this expression Not used in the body of a function Not needed after each function definition Ø Though for now it won t hurt if used there e1; e2 evaluates e1 and then e2, and returns e2 let print_both (s, t) = print_string s; print_string t; "Printed s and t" notice no ; at end it s a separator, not a terminator print_both ( Colorless green ", ideas sleep") Prints Colorless green ideas sleep", and returns "Printed s and t" 34 Grouping With Begin...End If you re not sure about the scoping rules, use begin...end to group together statements with semicolons The Trade-Off Of Side Effects Side effects are absolutely necessary That s usually why we run software! We want something to happen that we can observe let x = ref 0 let f () = begin print_string "hello"; x := (!x) + 1 end They also make reasoning harder Order of evaluation now matters Calling the same function in different places may produce different results Aliasing (two references to same object) is an issue Ø If we call a function with refs r1 and r2, it might do strange things if r1 and r2 are aliased 35 36 9

Structural Vs. Physical Equality In OCaml, the = operator compares objects structurally [1;2;3] = [1;2;3] (* true *) (1,2) = (1,2) (* true *) The = operator is used for pattern matching The == operator compares objects physically [1;2;3] == [1;2;3] (* false *) Mostly you want to use the first one But it s a problem with cyclic data structures Cyclic Data Structures Possible With Ref type 'a reflist = Nil Cons of 'a * ('a reflist ref) let newcell x y = Cons(x,ref y);; let updnext (Cons (_,r)) y = r := y;; let x = newcell 1 Nil;; updnext x x;; (* makes cycle *) x == x;; (* true *) x = x;; (* hangs *) 37 38 OCaml Language Choices OCaml Programming Tips Implicit or explicit declarations? Explicit variables must be introduced with let before use But you don t need to specify types Static or dynamic types? Static but you don t need to state types OCaml does type inference to figure out types for you Good: less work to write programs Bad: easier to make mistakes, harder to find errors Compile your program often, after small changes The OCaml parser often produces inscrutable error messages It s easier to figure out what s wrong if you ve only changed a few things since the last compile If you re getting strange type error messages, add in type declarations Try writing down types of arguments For any expression e, can write (e:t) to assert e has type t 39 40 10

OCaml Programming Tips (cont.) Watch out for precedence and function application let mult x y = x*y mult 2 2+3 (* returns 7 *) (* parsed as (mult 2 2)+3 *) OCaml Programming Tips (cont.) All branches of a pattern match must return the same type match x with... -> -1 (* branch returns int *)... -> () (* uh-oh, branch returns unit *)... -> print_string foo (* also returns unit *) mult 2 (2+3) (* returns 10 *) 41 42 OCaml Programming Tips (cont.) OCaml Programming Tips (cont.) You cannot assign to ordinary variables! # let x = 42;; val x : int = 42 # x = x + 1;; (* this is a comparison *) -: bool = false # x := 3;; Error: This expression has type int but is here used with type 'a ref Again: You cannot assign to ordinary variables! # let x = 42;; val x : int = 42 # let f y = y + x;; (* captures x = 42*) val f : int -> int = <fun> # let x = 0;; (* shadows binding of x *) val x : int = 0 # f 10;; (* but f still refers to x=42 *) - : int = 52 43 44 11