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
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.
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.
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'|]
13 comments
[ 5.6 ms ] story [ 16.6 ms ] threadCompare 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)
(2) (3) (4)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.
> 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'|]
> 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?
Its not, though.