type intern =
  string -> string

(* When asked to create a new intern, ... *)
let new_intern () : intern =
  (* ... we allocate a new hash table ... *)
  let table = Hashtbl.create 1023 in
  (* ... and we build (and return) a closure which has access
     to this table. This closure is the new intern. *)
  let i (s : string) =
    (* When this intern is called with a string [s], it tests whether
       some string that is logically equal to [s] already appears in
       the table. If so, it returns that string. Otherwise, it adds
       [s] to the table and returns [s]. *)
    try
      Hashtbl.find table s
    with Not_found ->
      Hashtbl.add table s s;
      s
  in
  i

(* Because the table is accessible only via the closure that we have
   constructed, we know that the table can only grow with time. (No
   one can remove entries from the table.) Thus, the property that
   [s1 = s2] implies [i s1 == i s2] holds. *)