From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.1.3 (2006-06-01) on yquem.inria.fr X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=disabled version=3.1.3 X-Original-To: caml-list@yquem.inria.fr Delivered-To: caml-list@yquem.inria.fr Received: from concorde.inria.fr (concorde.inria.fr [192.93.2.39]) by yquem.inria.fr (Postfix) with ESMTP id B5E74BC69 for ; Tue, 21 Aug 2007 10:05:33 +0200 (CEST) Received: from anchor-post-31.mail.demon.net (anchor-post-31.mail.demon.net [194.217.242.89]) by concorde.inria.fr (8.13.6/8.13.6) with ESMTP id l7L85XAB029456 for ; Tue, 21 Aug 2007 10:05:33 +0200 Received: from orion.metastack.com ([80.177.38.218]) by anchor-post-31.mail.demon.net with esmtp (Exim 4.42) id 1INOk1-0003Bf-3S for caml-list@inria.fr; Tue, 21 Aug 2007 08:05:33 +0000 Received: from treble (cpc2-cmbg6-0-0-cust535.cmbg.cable.ntl.com [81.107.34.24]) (authenticated bits=0) by orion.metastack.com (8.13.4/8.13.3) with ESMTP id l7L7oLMg017992 (version=TLSv1/SSLv3 cipher=RC4-MD5 bits=128 verify=NO) for ; Tue, 21 Aug 2007 08:50:22 +0100 From: "David Allsopp" To: "'Caml-list List'" References: <56864F61-40F3-4F03-9823-6D510AD5320B@epfl.ch><200708191443.l7JEhEQ8007374@psi-phi.mit.edu> <20070819170704.GA10089@furbychan.cocan.org> Subject: RE: [Caml-list] If OCaml were a car Date: Tue, 21 Aug 2007 09:05:33 +0100 Organization: MetaStack Solutions Ltd. Message-ID: <005a01c7e3ca$0ce14fa0$6a7ba8c0@treble> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit X-Mailer: Microsoft Office Outlook 11 X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.3138 Thread-Index: Acfigc4cx0KFwcStROqMsi2sKCiMuQBReA2w In-Reply-To: <20070819170704.GA10089@furbychan.cocan.org> X-Miltered: at concorde with ID 46CA9CCD.000 by Joe's j-chkmail (http://j-chkmail . ensmp . fr)! X-Spam: no; 0.00; ocaml:01 syntax:01 syntax:01 foo:01 compiler:01 makefile:01 dependencies:01 cmi:01 cmi:01 o'caml:01 toplevel:01 foo:01 beginners:01 clearer:01 caml-list:01 > It's not likely that the syntax can be changed (how is the revised > syntax doing lately?) but there is one error message which could be > fixed. When I worked at Merjis a colleague got frustrated to the > point of virtually giving up the language at the error message "Foo > makes inconsistent assumptions over Bar"[1]. It is literally useless: > it does not describe what it means, what files are involved which are > inconsistent, what their MD5 sums are or should be, and lastly it > doesn't say how to fix the problem (which generally involves > recompiling libraries). I'm not sure I'd classify this as the "worst" message the compiler gives - when I see that it tells me that my Makefile dependencies are broken (if Bar.cmi is part of my project) or that I've updated a library (if Bar.cmi is from something else) and either way that make clean; make will fix it for now! The error message on a missing "in" in a "let...in" block on the other hand is the one that drives me up the wall... (* first function *) let f x = (* definition of f *) in let g x = (* definition of g *) (* etc, etc *) (* next function *) let h x = (* definition of *) Here, O'Caml helpfully tells me that there's a syntax error on line 7 which is of course complete rubbish!! It may be easy to spot here, but I've absent-mindedly missed the final part of a bigger function mid-development (or after having to leave the code and come back to it) and had to spend *ages* trying to find where the error is in larger ML files... in this situation I'd really like a "the let on line 4 may be un-matched" guess similar to that for mismatched parenthesis :o) > I tell beginners that most code they write should be within a toplevel > statement: > > let _ = > ... > > or (better): > > let () = > ... I'd go one further - and recommend that all top level statements are function definitions (there's so rarely a need to use global "variables"... it usually comes back to bite you at some point later). Then define a function main () to do the "top level" part of your program (the concept of "main" is generally clearer to someone coming to ML from a more mainstream language) and finish the whole thing to give code like: type t = Foo let foo f = f () let bar _ = Foo let main () = foo bar (* One top-level statement to run the program *) let _ = main (); () While I wouldn't bet my life on it, I've never found a need for ";;" at all when coding this way and ";" always binds as you expect it to. David