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=AWL 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 924F3BC6B for ; Mon, 27 Aug 2007 12:41:21 +0200 (CEST) Received: from einhorn.in-berlin.de (einhorn.in-berlin.de [192.109.42.8]) by concorde.inria.fr (8.13.6/8.13.6) with ESMTP id l7RAfK2F025538 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL) for ; Mon, 27 Aug 2007 12:41:21 +0200 X-Envelope-From: oliver@first.in-berlin.de X-Envelope-To: Received: from einhorn.in-berlin.de (localhost [127.0.0.1]) by einhorn.in-berlin.de (8.13.6/8.13.6/Debian-1) with ESMTP id l7RAfJbb029846 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NOT) for ; Mon, 27 Aug 2007 12:41:19 +0200 Received: (from www-data@localhost) by einhorn.in-berlin.de (8.13.6/8.13.6/Submit) id l7RAfJNI029843 for caml-list@inria.fr; Mon, 27 Aug 2007 12:41:19 +0200 X-Authentication-Warning: einhorn.in-berlin.de: www-data set sender to oliver@first.in-berlin.de using -f Received: from dslb-088-073-070-084.pools.arcor-ip.net (dslb-088-073-070-084.pools.arcor-ip.net [88.73.70.84]) by webmail.in-berlin.de (IMP) with HTTP for ; Mon, 27 Aug 2007 12:41:19 +0200 Message-ID: <1188211279.46d2aa4f77e5b@webmail.in-berlin.de> Date: Mon, 27 Aug 2007 12:41:19 +0200 From: Oliver Bandel To: caml-list@inria.fr Subject: On bashing the OCaml-car... MIME-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 8bit User-Agent: Internet Messaging Program (IMP) 3.2.6 X-Scanned-By: MIMEDefang_at_IN-Berlin_e.V. on 192.109.42.8 X-Miltered: at concorde with ID 46D2AA50.003 by Joe's j-chkmail (http://j-chkmail . ensmp . fr)! X-Spam: no; 0.00; bandel:01 in-berlin:01 ocaml:01 -thread:01 ocaml:01 0200,:01 syntax:01 parser:01 ocaml's:01 syntax:01 expr:01 expr:01 foo:01 baz:01 fixpoint:01 Hello, a while ago, there was the "If OCaml were a car"-thread. Sorry for not answering directly (I'm using a webmailer and the mail I'm answering to, is already saved somewhere else, so I start a new thread on it). I'm answerung to [ Subject: Re: [Caml-list] If OCaml were a car From: skaller Date: Mon, 20 Aug 2007 07:45:41 +1000 Message-Id: <1187559941.6987.40.camel@rosella.wigram> ] > > On Sun, 2007-08-19 at 22:30 +0200, Tom wrote: > > On 19/08/07, John Carr wrote: > > > > OCaml has a badly designed syntax processed by a badly > > implemented > > parser feeding into a backend that generates poor error > > messages. > > All this makes the language hard to use. > > > > I would just like to know, what exactly do you think is badly > > designed, and what would be a better alternative? Mind that I am not > > defending OCaml's syntax here (I have grown accustumed to it, but I do > > not find it superb... probably...), I just think that all criticism > > should be constructive (that is, shut up unless you've got a better > > idea). > > I disagree with that: Most analysis is > and should be destructive. Understanding problems is the > precursor to constructing better solutions. > > Ocaml has lots of syntactic issues. It has too many operators, > so that it is hard to remember their 'precedence'. Learn it once, and then there will be no problem anymore. > Some are > very un-natural, for example: > > if e then e1 else e2 I find this very natural. > > The thing is that 'else' has a different 'precedence' than 'then'. > So you can write: > > if e then e1 else a; b; c > > and a,b,c are all executed if the condition is false, but you > cannot write: > > if e then a; b; c else ... > This is completely logical. In a if-then/if-then-else construct you have ONE expression for the condition, ONE for the then-part and ONE for the else-part. If you can remember the value ONE (one means: 1, type: int), then this is completely logical and very fine. expr1; expr2; expr3 are NOT ONE expression; they are a sequence of expressions. Using these if-then-else constructs can make it very easy to add new if-then-else constructs, when coding this way: if e then e1 else a; b; c it's easy to add new lines (copy/paste; in vi/vim: yy p) if e then e1 else a; if e then e1 else a; if e then e1 else a; if e then e1 else a; b; c and then reedit the expressions "e", "e1", "a" to new vlaues if e then e1 else a; if expr1 then e2 else foo; if expr2 then e3 else bar; if expr3 then e4 else baz; b; c This makes editing fast (adding new if-then-else constructs, without changing the rest of the code/behaviour). And when you can remember "ONE" (1) this should be easy. (To be detailed: maximum is ONE, when unit-value is used, it's ZERO, nut maximum is ONE nevertheless; look below.) > and similarly for let/in. So you need parentheses in the 'then' branch > to write a 'larger' expression, but you need parentheses around the > whole if/else to write a 'smaller' expression in the else > branch .. Yes. And the reason is, that one expression will be used in the if-then-else and not a sequence of expressions, so you have to use paranthesis' or better: begin-else. If it would be done differently, the number of expressions will be different, and THAT would be a mess, IMHO. Where to stop? Possibly you would nevertheless need something that tells you, which code would be used, and in C this would be { and }. > > Furthermore, because of the decision that procedures > return unit, you can write: > > if e then p; > > without the else, but only if p has type unit: the syntax is so > confused it doesn't know if it is functional/expression based Not the syntax is confused. YOU are confused! There is one simple reason, why the else can be omitted, if the type of the expressions is unit: If it's unit type, it's ALWAYS unit type. There is only ONE possibility of unit-values! But if it's of type int, the else-expression can't be forseen. Would the else clause be 0, 1, 2, 3, 4, ... or any other value, that would be of type int? There is no way to find it out, and that's the reason, why you have to use else in any other case than that of using the unit type. if you have unit, there will be only unit, and not unit(1), unit(2), unit.(9) or (3 *. unit) something like that. So, you can ignore the else-expression in this case, because the resulting "value" is obvous. ( For unit-type the type and the value are "the same", possibly one could say for unit-type/unit-value, the value is the fixpoint of the type ). If you are confused by it, you nevretheless can write if e then p else (); Then all is, as you like it. > (in which case the else expression should be mandatory) > or procedural (in which case procedure calls should return void > to prevent the call being used as an argument to an application). > > Felix procedures return void, and it provides > > if e then e1 else e2 endif // an expression > if e do > s1; s2; s3; > elif e1 then // optional > s4; s5; s6; > else // optional > s7; s8; s9; > done; // a statement > This kind of C-ish style IMHO is much more confusing. to know if "s7; s8; s9;" will be evaluated, I have to translate this folded stuff into something plain. If you have bigger constructs, where the conditions are nested, it is not that easy to find out, which conditional really is used. (But even the above one needs some time to decypher.) In OCaml I know that I have to use begin-end in the else-expression and inside it could code more stuff. But instead of such things I would rather use pattern matching like this way: match (a,b,c,d,e) with true, "hello", 47, None, true -> something() false, "world", 11, Some foo , true -> something() | false, _, 0, _, false -> something_possibly_different() | false, _, _, _, _ -> something_completely_different() IMHO that's much better to understand and to change, than using nested if-then-elif-else-...-...-.-...-.-.-.-.-.-.-.----...- When using the nested if-then-else-elif stuff, the whole conditional stuff is folded geometrically. This makes it less good to comprehend and unfold. This is one major reason of semantical errors in C-like languages. OCaml is very clear here: in if-then or if-then-else you have ONE expression, not any possible number of expressions, that will be used. This makes programming much clearer, IMHO. And not to have elif or elsif or how you woud name it, makes programming much clearer. :) Use pattern matching, instead of the nested chaos of if-then-else-elif. > and in both cases the text of the branches can be > transparently swapped around. Which it makes harder to follow the logic. One has to unswap the code, when trying to comprehend it. It's NOT obvious, which code will be evaluated! > The cost is additional syntax > and the mandatory terminator. I thought you want to have LESS additional syntax? So, your argumentation is not clear here. You want less syntactiy issues, and with more you are happy?! [...] > Well it is NOT clear that all these alternatives are actually > a good idea, Maybe thinking about what I wrote above could make it clear now?! > just as it is NOT clear that excess use of camlp4 is > a good idea. In my experience, using the language's raw syntax, > even if it has warts, is more or less mandatory if you want > other people to be able to read your code. > > Can Ocaml syntax be improved? Yes, but not much. Felix has: > > print$ "Hello" + " World"; > > which is stolen from Haskell and gets used a lot. Even if I can > implement that with camplp4 I wouldn't. I'd like to see $ in > the standard language: then I'd use it. You want more syntactic issues? I thought you asked for less! [...] > so I can add just one line without touching the rest > of the code .. this is really cool!! .. so maybe the > weird if/then/else isn't so bad after all ... :) Yes. So, why do you bothering?! Please, no more OCaml-bashing. First read the manual and ask people, what they think about something that you do not understand, instead of blaming/bashing OCaml on that. Thanks. Ciao, Oliver P.S.: For sequences of expressions and if-then-else, please look at section 6.7.2 in http://caml.inria.fr/pub/docs/manual-ocaml/expr.html