On Monday 21 May 2007 11:18:59 dmitry grebeniuk wrote:
> Shalom, Richard.
>
> >> I learned revised syntax when tried to learn camlp4.
> >> I wanted to use camlp4 for fixing some unsafe issues in
> >> original syntax, but I've found that revised syntax already
> >> fixed these issues.
>
> RJ> What are these 'unsafe issues' in the original syntax?
>
> I'll cite from
> http://caml.inria.fr/pub/docs/tutorial-camlp4/tutorial005.html
>
> ============================================================
> The declaration of a global variable is introduced by the
> keyword ``value'', ``let'' being reserved to the
> construction ``let..in'':
>
> OCaml Revised
> let x = 23;; value x = 23;
> let x = 23 in x + 7;; let x = 23 in x + 7;
> ============================================================
>
> In revised syntax if I write "value x = 23;" I sure that
> I can never add " in ..." at the end and this binding won't
> be hidden by construction like
> "let x = 23 in x + 7".
This is a bad idea, IMHO. OCaml has no notion of "global" scope, just a
progression from outer to levels of nested scope.
F# has a better "#light" syntax that uses indentation to replace the "in"
keyword, allowing you to move code with adding or replacing keywords:
let () =
let n = 1000
for i=0 to n
...
done
to:
let n = 1000
let () =
for i=0 to n
...
done
The variable "n" is now visible in the outer scope.
Moreover, you can evaluate parts of a function body in the outer-scope of a
top-level during testing, allowing you to follow the flow of execution.
> From computational point of view, the difference between
> top-level values and other values is great: top-level values
> will be computed when program runs, but values in "let ..
> in" will be computed only when program needs them.
That is not true. Currying of functions and functors delays evaluation
arbitrarily but the simplest counter-example is the (very common):
let () =
let n = 1000 in
...
that I just used. The value of "n" is computed immediately even though in
appears inside a "let ... in" rather than an outer "let".
> So, "value () = print_string "qwen";" will output string
> once and independent of another functions, but
> "value f x = let () = print_string "qwen" in x;" will
> output string only when "f x" is computed. So I have
> guarantee that "value x = expr;" will be computed always
> (if program don't quit before "value x = expr;", of course)
Yes. The evaluation semantics will never be trivial and introducing new
keywords unnecessarily does not make things better, IMHO.
> List constructor ("[h::t]") is bracketed, so I always know
> where it ends without need to remember priority of
> operators.
Superfluous parentheses.
> Most of constructions are closed:
More superfluous parentheses.
> match ... with
> case1 ->
> match ... with
> case11 -> ...
>
> | case12 -> ...
> |
> | case2 -> ...
>
> is wrongly interpreted:
Not if indentation is used (F#).
OCaml offers incredible brevity precisely because these constructs are not
closed:
http://www.ffconsultancy.com/languages/ray_tracer/
otherwise it would be Standard ML.
> to obtain what you want, you need to
> use parentheses or begin..end to close the internal match
> construct. There is a same problem with the if construct,
> because of the optional else (see further).
Again, this is improves the language for smart people who know precedence.
> 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 currified:
>
> OCaml Revised
> type t = C of t1 * t2;; type t = [ C of t1 and t2 ];
> C (x, y);; C x y;
This might be a good idea but I don't mind writing a constructor in curried
for:
let c x y = C(x, y)
> I think it's good to have strong distinction between
> type t = C of t1 * t2
> and
> type t = C of (t1 * t2)
I think it would be better to optimise this away transparently.
> Motivation for the currified syntax for constructors
>
> This reflects the actual semantics. There are indeed two
> cases, and the values in the two cases are implemented
> differently. The arity of constructors are more clear.
>
> In normal syntax, it is difficult to understand (and to
> explain) why if C is a constructor with two parameters, this
> is accepted:
>
> fun C (x, y) -> (x, y)
>
> but not that:
>
> fun C x -> x
>
> In revised syntax you have to write:
>
> fun [ C x y -> (x, y) ]
>
> The revised syntax reflects the fact that the two parameters
> of the constructor C cannot be considered as a tuple.
This logic is upside-down, IMHO. Constructor arguments should be available as
a tuple if they are written as a tuple.
Also, what happens with polymorphic variants in revised syntax, where the
arguments really are a tuple?
fun (`C x : [`C of 'a * 'a]) -> x;;
> The ``else'' is mandatory in the ``if'' statement:
>
> OCaml Revised
> if a then b if a then b else ()
More unnecessary verbosity.
> I think there is no need to explain why mandatory "else"
> is more safe than optional "else".
Diverging from all mainstream programming languages and bloating the language
requires a lot of justification, IMHO. Given that I have never had a problem
with a dangling "if" in OCaml, I can see absolutely no justification for
worsening the syntax of the whole language.
If you really want to improve this, tweak the compiler so that it checks that
the indentation of the code agrees with the interpretation.
> At first glance, I cited the features that are most
> important for safe ocaml programming in revised syntax.
I completely disagree. The revised syntax is very old and is deliberately not
used by the majority of OCaml programmers because it simply isn't
significantly better. I don't know of a single significant project that uses
the revised syntax outside of camlp4. Indeed, there is even a project to
allow you to use ordinary syntax inside camlp4.
I think F# does a vastly better job of addressing the serious concerns, like
operator overloading. If anyone implemented an F# front end for OCaml then I
would switch to it immediately.
--
Dr Jon D Harrop, Flying Frog Consultancy Ltd.
The F#.NET Journal
http://www.ffconsult