Version française
Home     About     Download     Resources     Contact us    
Browse thread
If OCaml were a car
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
From: David Allsopp <dra-news@m...>
Subject: RE: [Caml-list] If OCaml were a car
> 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