Object Oriented Programming with OCaml - Notes | CMSC 330, Assignments of Programming Languages

Material Type: Assignment; Class: ORGNZTN PROGM LANG; Subject: Computer Science; University: University of Maryland; Term: Fall 2007;

Typology: Assignments

Pre 2010

Uploaded on 07/29/2009

koofers-user-pyt
koofers-user-pyt 🇺🇸

10 documents

1 / 16

Toggle sidebar

This page cannot be seen from the preview

Don't miss anything!

bg1
1
CMSC 330: Organization of
Programming Languages
Object Oriented Programming
with OCaml
CMSC 330 2
Reminders and Review
Homework 2 was posted on Oct. 20
Due on Oct. 30
Project 3 due on Oct. 31
Project 4 will be posted by then
Midterm 2 on Nov. 1
•Closures
•Currying
pf3
pf4
pf5
pf8
pf9
pfa
pfd
pfe
pff

Partial preview of the text

Download Object Oriented Programming with OCaml - Notes | CMSC 330 and more Assignments Programming Languages in PDF only on Docsity!

CMSC 330: Organization of

Programming Languages

Object Oriented Programming

with OCaml

CMSC 330 2

Reminders and Review

• Homework 2 was posted on Oct. 20

– Due on Oct. 30

• Project 3 due on Oct. 31

– Project 4 will be posted by then

• Midterm 2 on Nov. 1

• Closures

• Currying

CMSC 330 3

OCaml Data

• 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

• How can we build other data structures?

– Building everything from lists and tuples is awkward

CMSC 330 4

Data Types

• Rect and Circle are type constructors- here a

shape is either a Rect or a Circle

• Use pattern matching to deconstruct values, and

do different things depending on constructor

type shape = Rect of float * float (* width * length ) | Circle of float ( radius *)

let area s = match s with Rect (w, l) -> w *. l | Circle r -> r *. r *. 3.

area (Rect (3.0, 4.0)) area (Circle 3.0)

CMSC 330 7

Polymorphic Data Types

• This option type can work with any kind of data

– In fact, this option type is built-in to OCaml

type 'a option = None | Some of 'a

let add_with_default a = function None -> a + 42 | Some n -> a + n

add_with_default 3 None (* 45 ) add_with_default 3 (Some 4) ( 7 *)

CMSC 330 8

Recursive Data Types

• Do you get the feeling we can build up lists this

way?

– Note: Don’t have nice [1; 2; 3] syntax for this kind of

list

type 'a list = Nil | Cons of 'a * 'a list

let rec length l = function Nil -> 0 | Cons (_, t) -> 1 + (length t)

length (Cons (10, Cons (20, Cons (30, Nil))))

CMSC 330 9

Data Type Representations

• Values in a data type are stored either directly

as integers or as pointers to blocks in the heap

type t = A of int | B | C of int * int | D

CMSC 330 10

Exercise: A Binary Tree Data Type

• Write type bin_tree for binary trees over int

  • trees should be ordered

• 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

CMSC 330 13

Modularity and Abstraction

• Another reason for creating a module is so we

can hide details

– For example, we can build a binary tree module, but

we may not want to expose our 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)

CMSC 330 14

Module Signatures

module type FOO = sig val add : int -> int -> int end;;

module Foo : FOO = struct let add x y = x + y let mult x y = x * y end;;

Foo.add 3 4;; (* OK *)

Entry in signature Supply function types

Give type to module

CMSC 330 15

Module Signatures (cont’d)

• The convention is for signatures to be all capital

letters

– 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

CMSC 330 16

Abstract Types in Signatures

• Now definition of shape is hidden

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

CMSC 330 19

Example

type shape val area : shape -> float val unit_circle : shape val make_circle : float -> shape val make_rect : float -> float -> shape

type shape = Rect of ... ... let make_circle r = Circle r let make_rect x y = Rect (x, y)

shapes.mli

shapes.ml

% ocamlc shapes.mli # produces shapes.cmi % ocamlc shapes.ml # produces shapes.cmo ocaml

#load "shapes.cmo" (* load Shapes module *)

CMSC 330 20

Functors

• Modules can take other modules as arguments

– Such a module is called a functor

– You’re mostly on your own if you want to use these

• Example: Set in standard library

module type OrderedType = sig type t val compare : t -> t -> int end

module Make(Ord: OrderedType) = struct ... end

module StringSet = Set.Make(String);; (* works because String has type t, implements compare *)

CMSC 330 21

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!

– 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

CMSC 330 22

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

CMSC 330 25

Comparison to OCaml

• In OCaml, an updatable location and the

contents of the location have different types

– The location has a ref type

int x, y;

x = 3;

y = x;

3 = x;

let x = ref 0;; let y = ref 0;;

x := 3;; (* x : int ref *)

y := (!x);;

3 := x;; (* 3 : int; error *)

CMSC 330 26

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;;

next ();;

  • : int = 0

next ();;

  • : int = 1

unit:

this is

how a

function

takes no

argument

CMSC 330 27

Semicolon Revisited; Side Effects

• Now that we can update memory, we have a

real use for ; and () : unit

– e1; e2 means evaluate e1, throw away the result, and

then evaluate e2, and return the value of e

– () means “no interesting result here”

– It’s only interesting to throw away values or use () if

computation does something besides return a result

• A side effect is a visible state change

– Modifying memory

– Printing to output

– Writing to disk

CMSC 330 28

Grouping with begin...end

• If you’re not sure about the scoping rules, use

begin...end to group together statements with

semicolons

let x = ref 0

let f () = begin print_string "hello"; x := (!x) + 1 end

CMSC 330 31

Exceptions (cont’d)

• Exceptions are declared with exception

– They may appear in the signature as well

• Exceptions may take arguments

– Just like type constructors

– May also be nullary

• Catch exceptions with try...with...

– Pattern-matching can be used in with

– If an exception is uncaught, the current function exits

immediately and control transfers up the call chain

until the exception is caught, or until it reaches the

top level

CMSC 330 32

OCaml Language Choices

• 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