The Revised syntax

Previous Up Next
Chapter 6 The Revised syntax
The revised syntax is an alternative syntax for OCaml. Its purpose is to be simpler, more regular, more logical than the normal syntax, and fix some problems which sometimes result in bugs not always easy to find. This syntax was named ``righteous'' instead of ``revised'' in previous versions.

This chapter presents the changes from OCaml to this syntax.

6.1 Phrases
  • A simple semicolon ends the sentences, in structures and in signatures. The double semicolon is not a token. There is no ambiguity with the sequence, which has a special construction (see 6.2).

  • The declaration of a global variable is introduced by the keyword ``value'', ``let'' being reserved to the construction ``let..in'':
    OCamlRevised
    let x = 23;;value x = 23;
    let x = 23 in x + 7;;let x = 23 in x + 7;


  • In interfaces, one must use ``value'', too, instead of ``val''.
    OCamlRevised
    val x : int;;value x : int;
6.2 Imperative constructions
  • The sequence is introduced by the keyword ``do'' followed by ``{'' and terminated by ``}'' (it is possible to put a semicolon after the last expression):
    OCamlRevised
    e1; e2; e3; e4do { e1; e2; e3; e4 }


  • The body of ``for'' and ``while'' has the same syntax:
    OCamlRevised
    while e1 dowhile e1 do {
    e2; e3; e4 e2; e3; e4
    done}
6.3 Tuples and lists
  • Parentheses are mandatory in tuples:
    OCamlRevised
    1, "hello", World(1, "hello", World)


  • Lists are always enclosed with ``['' and ``]''. Their syntax is:
    list ::= [ elem-list opt-cons ]
    elem-list ::= expression ; elem-list | expression
    opt-cons ::= :: expression | (*empty*)
    A list is a sequence of expressions separated by semicolons, optionally ended by a ``::'' and an expression, the whole being enclosed by brackets. Examples:
    OCamlRevised
    x::y[x::y]
    [x; y; z][x; y; z]
    x::y::z::t[x::[y::[z::t]]]
    x::y::z::t[x; y; z :: t]
    Note the two ways to write the last case.
6.4 Irrefutable patterns

There is a notion of ``irrefutable patterns'' used by some syntactic constructions. Matching against these patterns never fails. An ``irrefutable pattern'' is either:
  • A variable.
  • The wildcard ``_''.
  • The constructor ``()''.
  • A tuple with irrefutable patterns.
  • A record with irrefutable patterns.
  • An irrefutable pattern with a type constraint.
Note that the term ``irrefutable'' does not apply to all patterns which never fail: constructors alone in their type declarations, except ``()'', are not said ``irrefutable''.

6.5 Constructions with matching
  • The keyword ``function'' no longer exists. One must use only ``fun''.

  • The pattern matchings, in constructions with ``fun'', ``match'' and ``try'' are closed with brackets: an open bracket ``['' before the first case, and a close bracket ``]'' after the last one:
    OCamlRevised
    match e withmatch e with
    p1 -> e1[ p1 -> e1
    | p2 -> e2;;| p2 -> e2 ];
    fun x -> x;;fun [x -> x];
    But if there is only one case and if the pattern is irrefutable, the brackets are not mandatory. These examples work identically in OCaml and in revised syntax:
    OCamlRevised
    fun x -> xfun x -> x
    fun {foo=(y, _)} -> yfun {foo=(y, _)} -> y
    The curryfied pattern matching can be done with ``fun'', but only with irrefutable patterns:
    OCamlRevised
    fun x (y, z) -> tfun x (y, z) -> t
    fun x y (C z) -> tfun x y -> fun [C z -> t]


  • It is possible to write the empty function, raising the exception ``Match_failure'' whichever parameter is applied, the empty ``match'', raising ``Match_failure'' after having evaluated its expression, and the empty ``try'', equivalent to its expression without try:
     fun []
     match e with []
     try e with []
    


  • The patterns after ``let'' and ``value'' must be irrefutable. The following OCaml expression:
     let f (x::y) = ...
    
    must be written in Revised:
     let f = fun [ [x::y] -> ...
    


  • The construction ``where'' is back, but one can write only one bind: e where x = y but not: e where x = y and z = t
6.6 Mutables and assignment
  • The instruction ``<-'' is written ``:='':
    OCamlRevised
    x.f <- yx.f := y


  • The ``ref'' type is declared as a record type with one field named ``val'', instead of ``contents''. The operator ``!'' does not exist any more, and references are assigned like the other mutables:
    OCamlRevised
    x := !x + yx.val := x.val + y
6.7 Types
  • The type constructors are before their type parameters, which are curryfied:
    OCamlRevised
    int listlist int
    ('a, bool) Hashtbl.tHashtbl.t 'a bool
    type 'a foo =type foo 'a =
    'a list list;; list (list 'a);


  • The abstract types are represented by a unbound type variable:
    OCamlRevised
    type 'a foo;;type foo 'a = 'b;
    type bar;;type bar = 'a;


  • Parentheses are mandatory in tuples of types:
    OCamlRevised
    int * bool(int * bool)


  • In declaration of a concrete type, brackets must enclose the constructor declarations:
    OCamlRevised
    type t = A of i | B;;type t = [ A of i | B ];


  • It is possible to make the empty type, without constructor:
     type foo = [];
    


  • There is a syntax difference between data constructors with several parameters and data constructors with one parameter of type tuple.

    The declaration of a data constructor with several parameters is done by separating the types with ``and''. In expressions and patterns, this constructor parameters must be curryfied:
    OCamlRevised
    type t = C of t1 * t2;;type t = [ C of t1 and t2 ];
    C (x, y);;C x y;


    The declaration of a data constructor with one parameter of type tuple is done by using a tuple type. In expressions and patterns, the parameter has not to be curryfied, since it is alone:
    OCamlRevised
    type t = D of (t1 * t2);;type t = [ D of (t1 * t2) ];
    D (x, y);;D (x, y);


  • The predefined constructors ``True'' and ``False'' start with an uppercase letter.

  • In record types, the keyword ``mutable'' must appear after the colon:
    OCamlRevised
    type t = {mutable x : t1};;type t = {x : mutable t1};
6.8 Modules

Modules application uses curryfication:
OCamlRevised
type t = Set.Make(M).t;;type t = (Set.Make M).t;


6.9 Objects

The objects also have a revised syntax. To see it, the simplest way is to write examples in normal syntax and to convert them into revised syntax using the command:
 camlp4o pr_r.cmo file.ml
6.10 Miscellaneous
  • The ``else'' is mandatory in the ``if'' instruction:
    OCamlRevised
    if a then bif a then b else ()


  • The boolean operations ``or'' and ``and'' must be only written with ``||'' and ``&&'':
    OCamlRevised
    a or b & ca || b && c
    a || b && ca || b && c


  • No more ``begin end'' construction. One must use parentheses.

  • The operators as functions are written with an backslash:
    OCamlRevised
    (+)\+
    (mod)\mod
  • The operators with special characters are not automatically infix. To define infixes, use the syntax extensions (chapter 5).

  • It is possible to group together several declarations either in an interface or in an implementation by enclosing them between ``declare'' and ``end''. Example in an interface:
     declare
     type foo = [ Foo of int | Bar ];
     value f : foo -> int;
     end;
    
    This can be useful when extending the language structure or signature items with a construction generating several items.
6.11 Streams and parsers
  • The streams and the stream patterns are bracketed with ``[:'' and ``:]'' instead of ``[<'' and ``>]''.

  • The stream component ``terminal'' is written with a backquote instead of a quote:
    OCamlRevised
    [< '1; '2; s; '3>][: `1; `2; s; `3 :]


  • The cases of parsers are bracketed with ``['' and ``]'', like for ``fun'', ``match'' and ``try''. If there is one case, the brackets are not mandatory:
    OCamlRevised
    parserparser
    [< 'Foo>] -> e[ [: `Foo :] -> e
    | [< p = f>] -> f| [: p = f :] -> f ]
    parser [< 'x>] -> xparser [ [: `x :] -> x ]
    parser [< 'x>] -> xparser [: `x :] -> x


  • It is possible to write the empty parser raising the exception ``Stream.Failure'' whichever parameter is applied, and the empty stream matching always raising ``Stream.Failure'':
     parser []
     match e with parser []
    


Previous Up Next

AltStyle によって変換されたページ (->オリジナル) /