From: Brian H. <bri...@ql...> - 2003-04-17 16:25:51
|
Something just occured to me, and I don't know if this is a good idea or not. But we were talking about reading a file and tail recursion over in Ocaml beginners just now. And I whipped up a quick example of reading a file into a list of strings, using the standard List.rev trick. Now, that's "correct" for Ocaml beginners, but not what you really want to do. What you really want to do is use setcdr to construct the list forwards, instead of backwards. But setcdr is dangerous, and not something I want to blithely recommend beginners play around with. What I thought would be neat would be to be able to allow the user to define their own enumeration. Define a function like: let next chan () = (* partially apply to define chan *) try input_line chan with End_of_file -> raise No_more_elements ;; You then pass this next function to list_of_enum and it uses setcdr in a safe way to create your list of the lines of a file. This allows us to have safe setcdr-based list building in a generic way- *without* having to discuss the dangers of setcdr with beginners. Enumerations are a simple enough idea- Java and C++ both have their iterators. Here's the problem: you don't know, ahead of time, how many lines are in the file. So there's no sane way to implement a count function. The count function, if meaningful, can be usefull- for example, Xarray could make sure only one reallocation is necessary to add an entire enumeration. But it's not *necessary*. So I propose that count be allowed to return -1 to indicate "length unknown". Throwing an exception might also be an idea. Enum users who depend upon count should be prepared to handle unknown length enumerations (possibly at reduced efficiency- Xarray, for example, might need to reallocate multiple times instead of just once). This would allow you to read an entire file into a list using setcdr just by let readfile chan = let next () = try input_line chan with End_of_file -> raise No_more_elements and count () = -1 (* or raise Length_unknown *) in List.of_enum (Enum.make ~next:next ~count:count) ;; Thoughts? Comments? Brian |