On Fri, 12 May 2000, Amit Dubey wrote:
>Hi,
>
> I'm still in the process of learning caml, but I'm considering
>using it for a project that I'm working on. One of the first things
>I need to do is to figure out how to load a file! I've tried the following
>code:
>
>1: let main () =
>2: let file_info : Unix.stats = Unix.stat Sys.argv.(1) in
>3: let fd = Unix.openfile Sys.argv.(1) [ Unix.O_RDONLY ] perm in
>4: let buffer = ref "" in
>5: let bytes_read = Unix.read (fd) (buffer) (file_info.st_size) in
> <snipped>
>
>But it fails with the error "Unbound record field label st_size" on line 5.
>I can't explain why this is happening; looking at the Unix.ml file, I see
>the st_size field in the Unix.stats record. Any suggestions would be
>appreciated.
You must write file_info.Unix.st_size. This is a point where OCaml differs
from other languages where labels are always local to the record; in OCaml
record labels are contained in module namespaces. The reason is that it must
be possible to infer the type of the expression from the label; i.e. if the
compiler sees "st_size" it looks up which (declared) type contains this
label. In the module you wrote it does not find such a type, and so the
compiler stops with an error.
In other languages, variables must be declared, and so it is possible that
the compiler can find out the type of the variable (or expression) before
it looks up the type containing the label. You tried to solve the problem
by giving the type annotation file_info : Unix.stats, but it does work
in OCaml because this "strategy" is not compatible (enough) with type inference
in general; the variable file_info may also be an expression, and it would be
a pain if you had to type-annotate every expression to which you apply a record
label.
The OCaml solution is to look up the label first, and find out the type (at
least another typing constraint) of the variable or expression after that.
Because of this, labels are also members of the modules containing the record
type; otherwise the label lookup would be ambiguous.
Of course, you do not need the annotation file_info : Unix.stats.
Sometimes it would be nice if the compiler could open a module only partially;
for example if I could write
open Unix only record labels
to import only record labels into the current module. Ambigous record labels
have only low impact on the overall type safety, because such labels are often
only used by the functions of the same module, and incorrectly associated
labels will almost always cause type errors.
BTW, there seems to be another error. Unix.read wants a string as second
argument, and the string must already be allocated:
let buffer = String.create n
where n is the maximum number of bytes to read at once.
Hope this helps,
Gerd
-- ---------------------------------------------------------------------------- Gerd Stolpmann Telefon: +49 6151 997705 (privat) Viktoriastr. 100 64293 Darmstadt EMail: gerd@gerd-stolpmann.de Germany ----------------------------------------------------------------------------
This archive was generated by hypermail 2b29 : Sun May 14 2000 - 23:20:20 MET DST