From mboxrd@z Thu Jan 1 00:00:00 1970 Received: (from weis@localhost) by pauillac.inria.fr (8.7.6/8.7.3) id XAA07905 for caml-redist@pauillac.inria.fr; Sun, 14 May 2000 23:16:40 +0200 (MET DST) Resent-Message-Id: <200005142116.XAA07905@pauillac.inria.fr> Received: from concorde.inria.fr (concorde.inria.fr [192.93.2.39]) by pauillac.inria.fr (8.7.6/8.7.3) with ESMTP id OAA26534 for ; Sat, 13 May 2000 14:09:34 +0200 (MET DST) Received: from mail.ngi.de ([195.243.0.227]) by concorde.inria.fr (8.10.0/8.10.0) with ESMTP id e4DC9X121696 for ; Sat, 13 May 2000 14:09:33 +0200 (MET DST) Received: from ice.darmstadt.netsurf.de (p3E9E0EDC.dip0.t-ipconnect.de [62.158.14.220]) by mail.ngi.de (8.9.3/8.9.3) with ESMTP id OAA89988; Sat, 13 May 2000 14:06:01 +0200 (CEST) Received: from localhost (localhost [[UNIX: localhost]]) by ice.darmstadt.netsurf.de (8.9.3/8.9.3) id OAA02497; Sat, 13 May 2000 14:08:43 +0200 From: Gerd Stolpmann Reply-To: gerd@gerd-stolpmann.de Organization: privat To: Amit Dubey , caml-list@inria.fr Subject: Re: The Unix module & records Date: Sat, 13 May 2000 13:30:07 +0200 X-Mailer: KMail [version 1.0.28] Content-Type: text/plain References: <200005121655.MAA03138@hopper.math.uwaterloo.ca> In-Reply-To: <200005121655.MAA03138@hopper.math.uwaterloo.ca> MIME-Version: 1.0 Message-Id: <00051314084308.11187@ice> Content-Transfer-Encoding: 8bit Resent-From: weis@pauillac.inria.fr Resent-Date: Sun, 14 May 2000 23:16:40 +0200 Resent-To: caml-redist@pauillac.inria.fr 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 > > >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 ----------------------------------------------------------------------------