caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: Brian Hurt <brian.hurt@qlogic.com>
To: Richard Jones <rich@annexia.org>
Cc: <caml-list@inria.fr>
Subject: Re: [Caml-list] Why do input* and readdir throw End_of_file ... annoying!
Date: Fri, 6 Jun 2003 14:44:57 -0500 (CDT)	[thread overview]
Message-ID: <Pine.LNX.4.33.0306061423220.2857-100000@eagle.ancor.com> (raw)
In-Reply-To: <20030606185111.GA3545@redhat.com>

On Fri, 6 Jun 2003, Richard Jones wrote:

> On Fri, Jun 06, 2003 at 01:49:55PM -0500, Brian Hurt wrote:
> > The problem with try/with is that it's way to easy to break tail recursion 
> > using try/with.  About every other week someone comes to the Ocaml 
> > beginners list where they are doing something like:
> 
> What's a good way to read all the lines of a file into a list? I
> can put it into the OCaml tutorial I'm writing.

The way I'd recommend doing it:

let read_all_lines chan =
    let rec loop accum =
        let line, eof = try (input_line chan), true
                        with End_of_file -> "", false
        in
        if eof then
            accum
        else
            loop (line :: accum)
    in
    List.rev (loop [])

The original poster's idea of a function:
   let my_input_line chan = 
      try Some(input_line chan)
      with End_of_file -> None

has the advantage of enlisting the type checker to make sure you handle 
the eof condition correctly everywhere.

For those seeking best performance, using the ExtLib would allow you to do 
the following:

let read_all_lines chan
    let e = Enum.from (fun () -> try input_line chan
                                 with End_of_file -> 
                                     raise No_more_elements)
    in
    ExtList.of_enum e

This has the effect of eliminating the List.rev.  Although at this point 
you should be very tempted to just keep it an enum, which are in some ways 
easier to work with than lists, and you don't read the data until you need 
it.  For example, to read in all the lines of one file, make them upper 
case, and write them out to another file, you might write:

let cap_all_lines inchan outchan
    let e = Enum.from (fun () -> try input_line inchan
                                 with End_of_file -> 
                                     raise No_more_elements)
    in
    let e' = Enum.map String.capitalize e
    in
    Enum.iter (fun x -> output_string outchan x; output_char '\n') e'

The advatange of this method is that only one line at a time needs to be 
in memory.

Brian


-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners


  parent reply	other threads:[~2003-06-06 19:27 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2003-06-06 17:01 Richard Jones
2003-06-06 17:30 ` Michal Moskal
2003-06-06 18:03 ` Ville-Pertti Keinonen
2003-06-06 18:43   ` Richard Jones
2003-06-07 15:08     ` Eric C. Cooper
2003-06-07 20:27       ` David Brown
2003-06-07 21:46         ` art yerkes
2003-06-09 15:33         ` Brian Hurt
2003-06-09  9:31       ` Fabrice Le Fessant
2003-06-06 18:49   ` Brian Hurt
2003-06-06 18:51     ` Richard Jones
2003-06-06 19:09       ` [Caml-list] " Alan Post
2003-06-06 19:44       ` Brian Hurt [this message]
2003-06-06 23:08     ` [Caml-list] " Lauri Alanko

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=Pine.LNX.4.33.0306061423220.2857-100000@eagle.ancor.com \
    --to=brian.hurt@qlogic.com \
    --cc=caml-list@inria.fr \
    --cc=rich@annexia.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).