Re: The Unix module & records

From: Gerd Stolpmann (gerd@gerd-stolpmann.de)
Date: Sat May 13 2000 - 13:30:07 MET DST

  • Next message: Daniel Ortmann: "The performance cost of using exceptions?"

    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