CSCI 2041

ADVANCED PROGRAMMING PRINCIPLES

Mutability II

Arrays

let a = [| 1; 2; 3 |]
let b = Array.map string_of_int a
b.(1) <- "two" ;;
let c = Array.of_list [31;42;17]
c.(0);;
let d = Array.make 5 true
d.(4);;

Type rules:

ar : 'a array, i : intar.(i) : 'a

ar : 'a array, i : int, e : 'aar.(i) <- e : unit

Runtime errors:

a.(i) raises Invalid_argument "index out of bounds" if i >= Array.length a

Identity:

let a1 = Array.make 3 (ref 4)
let a2 = a1
let a3 = Array.copy a2
a2.(2) <- ref 5
a1.(1) := 17
Array.iter print_endline b
Array.fold_left (^) "" b
let ( ~* ) a b =
  if Array.length b <> Array.length a then
    invalid_arg "dot"
  else Array.fold_left (+.) 0.
       (Array.map2 (fun ai bi -> ai *. bi) a b)
let all_less a b =
  Array.for_all (Fun.id) (Array.map2 (<) a b)
let s = Array.init 1000 (fun n -> (59*n+509) mod 2039)
Array.sort compare s

Bytes

Bytes

Strings are not mutable, but bytes are:

let s = Bytes.of_string "long string that I just made up"
Bytes.set s 0 's'
Bytes.to_string s
let s2 = s
Bytes.fill s2 2 2 'o'
Bytes.blit_string "some" 0 s 0 4

Buffers

let sb = Buffer.create 1024 in
  Buffer.add_string sb "long" ;
  Buffer.add_string sb " string" ;
  Buffer.add_string sb " I just" ;
  Buffer.add_string sb " made up" ;
  Buffer.contents sb

Other mutable data structures

Hash Tables

let create_table n = Array.create n []
let hmod k t =
  (Hashtbl.hash k) mod (Array.length t)
let add k v t =
  let i = hmod k t in t.(i) <- (k,v)::t.(i)
let find k t = List.assoc k t.(hmod k t)
let mem k t = List.mem_assoc k t.(hmod k t)
let remove k t =
  let i = hmod k t in
  t.(i) <- List.remove_assoc k t.(i)
let update k v t =
  let i = hmod k t in
  t.(i) <- (k,v)::(List.remove_assoc k t.(i))

(OCaml Hashtbl module has a more robust implementation)

Integer sets

let empty max = Array.make max false
let is_empty a = Array.for_all not a
let add i a = a.(i) <- true
let mem i a = a.(i)
let union s1 s2 = Array.map2 (||) s1 s2
let inter s1 s2 = Array.map2 (&&) s1 s2
let length s = Array.fold_left (fun a b -> if b then a+1 else a) 0 s
let fold_left f a s = snd (Array.fold_left
  (fun (i,a) b -> (i+1, if b then (f a i) else a)) (0,a) s)

cs2041.org

// reveal.js plugins