14

Looking at an unofficial OCaml grammar in this site the only production where begin appears is:

Expression ::= begin Expression end

and a little further down one sees:

Expression ::= (   Expression  [:Type]   )

That, together with some offhand replacements of begin / end with ( / ) in some trivial code (which didn't affect correctness) might seem to suggest that the begin end keywords are just syntactic sugar. Or am I missing something?

Marcus Junius Brutus
  • 26,087
  • 41
  • 189
  • 331

2 Answers2

31

“Syntactic sugar” suggests a simple but not trivial translation to other constructs. begin .. end is not syntactic sugar, it is redundant with ( .. ), because it does exactly the same thing.

If you are interested, the intention was that programmers can use begin .. end to enclose an imperative expression, executed for its side-effects, and ( .. ) for an expression with a non-unit value. But the compiler does not enforce that, the designers of the language just thought it would look nicer if they were used in this fashion, that's all.

Pascal Cuoq
  • 79,187
  • 7
  • 161
  • 281
  • 4
    Who says that syntactic sugar has to be non-trivial? What does that mean anyway? I would undoubtedly classify begin-end as syntactic sugar. – Andreas Rossberg Mar 28 '12 at 19:50
  • 5
    @AndreasRossberg If the OCaml compiler translated `begin .. end` to `( .. )` internally, the former would be syntactic sugar. The compiler does not do this in any meaningful sense. Instead, both construct are implicitly encoded in the construction of the AST. **One is not translated into the other.** – Pascal Cuoq Mar 28 '12 at 20:11
  • @AndreasRossberg I know about cultural differences and all that, but I find your comments slightly unproductive. Since you are commenting to disagree, could you try to explain your point of view a little better than, for instance, “Why do you say that you cannot separately compile native code in Ocaml? Of course you can.”? I shouldn't, in that particular case, have to tell you to follow the link I have already provided or to repeat what is said there. – Pascal Cuoq Mar 28 '12 at 20:42
  • 4
    I apologise if my reply came across as unproductive. I'm just questioning your definition here because the extra side conditions seem rather arbitrary, and it's the first time I hear somebody making non-triviality a criterium. Likewise, "one is not translated into the other" is an implementation detail, so I don't see how it is important. (Re the separate compilation debate, not sure what to say, except to argue that the link did not back up your actual statement, as others have pointed out as well.) – Andreas Rossberg Mar 28 '12 at 21:29
  • @AndreasRossberg The way this site work, if you disagree with an answer, you post your own explanation as a different answer. Laconic contradictions posted as comments are not considered useful. – Pascal Cuoq Mar 29 '12 at 10:20
  • 5
    Pascal, I'm very sorry, but I have to disagree with you again. Discussing an answer is what comments are there for, right? (Style notwithstanding, which I grant you can make a difference.) Assuming you observe that an answer has mistakes or is plain wrong, would you just let it go uncommented? And who would be helped by that? – Andreas Rossberg Mar 29 '12 at 12:58
10

In fact, there are several uses of parenthesis in the OCaml grammar for different grammatical rules, and not all of them can be used with begin..end. Parenthesis and begin..end can be used as semantics-free expression delimiters for disambiguation purpose (as you said, expr ::= '(' expr ')'). () also represents the constant of type unit and, as a pun, begin end is also allowed there -- but this last one is not specified in the manual, only consistently supported by the implementation.

But parentheses can also be used

  • to delimit patterns: function (_::_)::_ -> ...
  • as syntactic sugar for Array.get and Array.set: t.(i) t.(i) <- e
  • for type annotations (e : t) both in expressions and patterns (this is not a special case of the disambiguating delimiters because it is not valid without parenthesis)
  • for subtyping coercions: (e :> t) and (e : s :> t)
  • to form labelled pattern compounds: fun ~(x:int) .. and fun ?(x=10) ..
  • in various related places (coercions, annotations, etc.) in the module, signature and class/objects parts of the syntax

For none of this use can begin..end used instead, so it would definitely not be valid to replace ( with begin and ) with end systematically (while the converse is correct).

Sorry for the pedantic answer, but the question was itself quite precise. I'm not sure begin..end handling is the most elegant part of OCaml grammar (which has it lots of warts). One could wish that they really were equivalent, but then there is little point in insisting on writing begin x : int end instead of (x : int).

gasche
  • 31,259
  • 3
  • 78
  • 100
  • 1
    Pedantic means precise, with a strong connotation of _overly precise_. Your answer was IMO precise. – Str. Apr 14 '14 at 21:40