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 TAA23513 for caml-redistribution; Tue, 31 Aug 1999 19:14:32 +0200 (MET DST) Received: from nez-perce.inria.fr (nez-perce.inria.fr [192.93.2.78]) by pauillac.inria.fr (8.7.6/8.7.3) with ESMTP id CAA28931 for ; Tue, 31 Aug 1999 02:12:38 +0200 (MET DST) Received: from isil.maya.com (isil.maya.com [192.70.254.5]) by nez-perce.inria.fr (8.8.7/8.8.7) with ESMTP id CAA08240; Tue, 31 Aug 1999 02:12:37 +0200 (MET DST) Received: (from prevost@localhost) by isil.maya.com (8.9.3/8.9.3) id UAA23074; Mon, 30 Aug 1999 20:14:12 -0400 Sender: weis To: Pierre Weis Cc: skaller@maxtal.com.au (John Skaller), caml-list@inria.fr Subject: Re: convincing management to switch to Ocaml References: <199908300802.KAA15269@pauillac.inria.fr> From: John Prevost Date: 30 Aug 1999 20:13:57 -0400 In-Reply-To: Pierre Weis's message of "Mon, 30 Aug 1999 10:02:52 +0200 (MET DST)" Message-ID: User-Agent: Gnus/5.070095 (Pterodactyl Gnus v0.95) Emacs/20.4 MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Pierre Weis writes: > I don't want to start a flamewar on syntax, but as a computer science > teacher and Caml implementor and designer, I'm interested at those > facts you mentioned about the syntax of the language, since I just > think the opposite way: I find the Caml precedence rules pretty > convenient, easy to teach, and fairly easy to remember since > absolutely intuitive and natural (provided they have been explained to > you and you have understood the design ideas). > > So, there is something interesting to understand here, could you > elaborate a bit on your difficulties on precedences and especially > about ``all the brackets'' that make the code hard to read and hard to > write ? I had a similar problem with SML and Caml until I realized the one important rule that makes things clear: The juxtaposition (application) operator has the highest precedence. There are two places this can hurt you, if you don't understand it yet: let f_of_sum = f x + y vs let f_of_sum = f (x + y) This one's actually pretty simple to figure out--it doesn't take long, though people tend to feel unsure and write: let sum_of_f = (f x) + (f y) constructions when they don't have to. (And of course, C programmers get bitten by wanting function application to look like f(arg), rather than f arg. It doesn't help that oftentimes intro material takes this tack, then moves away from it, leaving lingering uncertainties about f(x) in the student's mind.) The other problem, which is more significant (although it causes more problems in SML) is constructors. When I first learned ML, it wasn't made obvious to me that the application of a value constructor is exactly the same as any other function. In fact, it seemed that it shouldn't be, since you can do pattern matching on one and not on the other. The painful part of this shows up mainly in patterns like the following: let f = fun (Foo x) (Bar y) (Baz z) -> ... It's not so much of a problem in Caml, since the above sort of pattern is rarely useful, but in SML, where using multiple cases and multiple patterns at the same time is possible, it makes for confusing behavior: fun f (Int a) (Int b) = Int (a + b) | f (Int a) (Flt b) = Flt (float a + b) | f (Flt a) (Int b) = Flt (a + float b) | f (Flt a) (Flt b) = Flt (a + b) When I first tried to do something like the above, my first mistake was to try something like this: fun f Int(a) Int(b) = Int (a + b) But this doesn't work, of course. I then tried various things, until I got: fun f (Int a) (Int b) = Int (a + b) At this point, I decided "Oh, I'll just write everything I can like Lisp!" and tried to do the following for consistency: fun f (Int a) (Int b) = (Int a + b) Which of course, doesn't work. Summary: It's important for introductory material to point out that " " is an operator, similar to others, and how it works precedence-wise. It's also important to point out that constructor application in both expressions and patterns acts exactly the same as function application. This makes things much clearer. You can then also point out useful things like the fact that , binds less tightly than anything else, so you can say (long expression, long expression) to form a tuple., and that similar rules apply to other things. Juxtaposition as application is in some ways the most foreign bit of syntax for a C-style language programmer. John.