13 comments

[ 5.6 ms ] story [ 16.6 ms ] thread
The title should be edited to say that it is from 2007.
Yawn ... The syntax of OCaml is tremendously regular once you understand it (and the examples he gives there are using the toplevel which indicates he's not used it very much).

Compare the syntax of OCaml (and ML in general) for:

(1) defining functions

(2) defining ordinary variables

(3) static variables

(4) variables scoped to two functions

with the same for your favourite imperative/OO language.

Here's the OCaml syntax:

(1)

    let f x = ...
(2)

    let v = ...
(3)

    let f =
      let v = ... in
      let f () = ... in
      f
(4)

    let f, g =
      let v = ... in
      let f () = ... in
      let g () = ... in
      f, g
(comment deleted)
The author of the article only spent about 5 minutes with the language, not enough time to find out about delimited overloading (http://pa-do.forge.ocamlcore.org/).

Update: Ignore the above, pa_do is from 2008. Nevertheless focusing on a single feature of the language is a good reason to reject the entire thing? Even when it's like that for solid performance reasons -- ie. you want to know what integer type you are using because it greatly affects how fast your program will run.

Doesn't sound like you read the article IMHO.
The article is from 2007, the syntax extension you mention is from GSoC 2008. And I think it's legitimate to attack a language's out-of-the box features even if someone somewhere has written an optional parser extension to address the problems.
My preferred alternative to OCaml is definitely F#. The stdlib rocks and it has all the type inferred goodness of OCaml.
To compare, in F# you'd have:

> let add3 x = x + 3 val add3 : int -> int

Plain numeric literals are int (32-bit integer). To make it generic:

> let inline add3 x = - let one = LanguagePrimitives.GenericOne in x + one + one + one;; val inline add3 : ^a -> ^e when ( ^a or ^b) : (static member ( + ) : ^a * ^b -> ^c) and ^b : (static member get_One : -> ^b) and ( ^c or ^b) : (static member ( + ) : ^c * ^b -> ^d) and ( ^d or ^b) : (static member ( + ) : ^d * ^b -> ^e)

Perhaps not pretty, but inlining provides a quick way around some limitations on generics.

While strings are not arrays, they are sequences (IEnumerable in .NET). Sequences can be infinite, so there's no Seq.reverse. But:

> "hello" |> Seq.toArray |> Array.rev ;; val it : char [] = [|'o'; 'l'; 'l'; 'e'; 'h'|]

From the comments:

> If you want an easy-to-use dynamic programming language, there are plenty better choices than Lisp

Huh, is there some new dynamic language that has completely slipped under my radar?

Why do I care about why someone did not like a certain language 4 years ago?
Caml didn't change much in the last 4 years, so it could potentially interesting blog post.

Its not, though.