Version franēaise
Home     About     Download     Resources     Contact us    

This site is updated infrequently. For up-to-date information, please visit the new OCaml website at

Browse thread
Locally-polymorphic exceptions [was: folding over a file]
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: 2007-10-04 (02:18)
From: oleg@p...
Subject: Re: Locally-polymorphic exceptions [was: folding over a file]

> Could you be more specific regarding the continuations' performance impact?
> Would it matter in practice? Would you recommend using this function in a
> general-purpose library instead of the imperative-style implementation that
> was suggested?

For use in practice (including ocamlopt -- the case delimcc does not
yet support: I should really fix that) one should probably `inline'
the implementation of abort into the code of fold_file. The result
will _literally_ be the following:

exception Done (* could be hidden in a module *)

let fold_file (file: in_channel)
              (read_func: in_channel->'a)
              (elem_func: 'a->'b->'b)
              (seed: 'b) =
  let result = ref None in
  let rec loop prev_val =
     let input =
       try read_func file
       with End_of_file -> result := Some prev_val; raise Done
       let combined_val = elem_func input prev_val in
       loop combined_val
     try loop seed with Done -> (match !result with Some x -> x
	                              | _ -> failwith "impossible!")

val fold_file :
  in_channel -> (in_channel -> 'a) -> ('a -> 'b -> 'b) -> 'b -> 'b = <fun>

let line_count filename =
   let f = open_in filename in
   let counter _ count = count + 1 in
   fold_file f input_line counter 0;;
(* val line_count : string -> int = <fun> *)

let test = line_count "/etc/motd";;
(* val test : int = 24 *)

It should be noted the differences from the previous imperative
solutions: the reference cell result is written only once and read
only once in the whole folding -- namely, at the very end. The
reference cell is written to, and then immediately read from. The bulk
of the iteration is functional and tail recursive. The use of mutable
cell is the trick behind typing of multi-prompt delimited
continuations. One may even say that if a type system supports
reference cells, it shall support multi-prompt delimited continuations
-- *and vice versa*.

> Also, is there a good manual on delimited continuations for a beginner with
> minimum of external references?

Perhaps the most comprehensive and self-contained paper on delimited
continuations is

        A static simulation of dynamic delimited control
        by Chung-chieh Shan

I have heard some people have found the introduction section of
helpful. Please note Christopher Strachey's quote on the above
page. It was said back in 1974!

Here's another quote from the same Strachey and Wadsworth's paper:

  Those of us who have worked with continuations for some time have soon
  learned to think of them as natural and in fact often simpler than the
  earlier methods.
Christopher Strachey and Christopher P. Wadsworth, 1974.