Xavier Leroy (the creator of OCaml) and his team at INRIA didn't think this was a big deal because when they were writing this stuff, processors were single core and had been since the beginning. Sure there were multiprocessor machines (not the same as multicore as there are multiple die), but those were only meant for servers/workstations. OCaml seemed very promising around 2006, the peak and end of the single core era with the Intel Pentium 4. What made OCaml so impressive was not only was it this beautifully simple, high-level functional language, but that the native compiler produced very fast code that was comparable to C/C++ performance. However, as multicore processors were introduced (Intel Core, Core 2), not having this capability made writing new code in OCaml less appealing. There are solutions like MPI, but that's lame. The same excuses you hear in the Python world about having true multithreading you hear in the OCaml world. Microsoft was able to do it with F#, which is essentially a clone of Caml by targeting their .NET CLR. Haskell is able to do it with GHC.
I still think OCaml is a wonderful language -- not having true multithreading doesn't make it useless. However, to me it has become more like a statically-typed Python which I can use for scripting. Having to use hacks like MPI to do multicore processing is a huge turn off in a multicore world. This is again nothing against the language, but the standard implementation needs a concurrent garbage collector and kernel threads. Otherwise I think OCaml may be doomed to irrelevance in the long run, which would be truly sad.
That being said you can still use multiple cores by using multiple processes, and that doesn't necesarelly imply MPI. OCamlNet (and probably some other libraries) provide a way to communicate between multiple OCaml processes.
The advantage of kernel threads is that they have way less overhead than a process (both in context size as well as more efficient memory caching at processor and OS level)...though more than a user-level thread. If there isn't any sort of message passing between two processes, the only mechanism I can think of of sharing data is shared memory (i.e and mmap) which is just as efficient as threads sharing the same process heap...but awkward (yes there are sockets, file IO, signals, queues, etc, but not as efficient). Even if OCaml provides a way to abstract that to be more palatable + safe -- my argument is that in a multicore world, kernel threads must be a first class citizen and the programmer shouldn't have to resort to tricks to harness it -- otherwise it's a major flaw that is going to prevent future adaptation. Also, as the number of cores increase, this is going to matter more and more...so hopefully this stuff gets out in the wild soon.
I'll update the post once this traffic calms down a bit :)
However I do think that from the ML family, F# might be the one getting more widespread.
If you don't have a particular goal in mind (ie, "I work at Jane Street and need to be compatible with our existing code"), there are a number of other factors in the OCaml vs. Haskell discussion that are far more important.
> JS is the only realistic way to write web apps
Javascript is the only realistic way to write the front-end of webapps. But that doesn't mean you're wedded to it for your backend technology. And I don't think either OCaml or Haskell have sufficiently advanced DOM bindings, etc. that I'd recommend using either one for client-side work in the browser.
[0] I'm not sure if this is a flamewar topic for car nerds - my point is to pick two high-end luxury cars that are both well-respected and each have their own merits.
Having a solid implementation for your target platform is very good reason to pick a language.
> Having a solid implementation for your target platform is very good reason to pick a language.
I'm not sure where you got that out of my comment; it was exactly the opposite.
My point was that neither OCaml nor Haskell have particularly strong implementations in this area (to my knowledge). Last time I checked, the ability to write Javascript using both languages was of experimental and/or novelty use only (hence the "cupholders").
And that still doesn't change the fact that a web app can be written in any language - the only part that needs to run in Javascript is the client-side. Depending on how you architect your app, this may not be much at all. (There are very few webapps that actually need much logic in Javascript - if you want to avoid JS[0] while writing complex webapps, it's actually very easy to do so in many cases.)
[0] or anything else that is translated into JS
I'm also looking at whether TyXML can be used with js_of_ocaml for statically typed goodness: http://ocsigen.org/tyxml/
It is a mature yet actively developed whole program optimized, strongly typed, polymorphic, ML like language that can interact effortlessly with C and C++ and has coroutines and threads baked in, although use of threads is somewhat discouraged. It has type-classes as well as modules. Functions written in it may be exported as a CPython module. This might be useful if one wants to gradually transition from a Python based src tree.
It uses a mix of lazy and eager evaluation for performance and compiles down to C++. Execution speed is comparable to hand written C++, mostly better. Its grammar is programmable in the sense that it is loaded as a library. So in the same way that languages may acquire libraries, Felix may acquire domain specific syntax.
It is also mostly a one man effort but with a feverish pace of development so it comes with its associated advantages and disadvantages.
Tooling info is here http://felix-lang.org/share/src/web/ref/tools.fdoc
The author likes to call it a scripting language but it really is a full-fledged statically compiled language with a single push button build-and-execute command. http://felix-lang.org/ The "fastest" claim is a bit playful and tongue in cheek, but it is indeed remarkably fast.
With this two styles the boundary between Felix and C++ can be very fluid. It does not incur the typical efficiency hit of a dynamically loaded FFI, although it does allow dynamically loading shared libraries too.
If you dont want to use C++ libraries and classes from Felix, you dont need to know C++ to use Felix.
There was a presentation at the FP eXchange in London last Friday about mirage and many a mind was blown!
Haskell is an Ivory Tower. The features that generally draw one to the language also tend to be the things that eventually push one away. Haskell has grown a lot over the years however as the language evolves to allow general programming within a pure framework.
OCaml on the other hand tends to make a compromise, acknowledging that the programmer occasionally needs a different tool for the job. OCaml allows the programmer to opt into things like mutability and objected oriented code when the need arises. These compromises can also be seen as the languages downside however.
I find it interesting that the driver for the author into OCaml is JavsScript... but it's nice to see OCaml come up a bit more often. :)
So for the very same reasons you give---Haskell has made fewer tradeoffs for "practical" programming---Haskell has become something valuable and interesting. On those tides the community has grown.
The rise of OcamlPro and Ocaml Labs does give me hope for the future of the language. There is already renewed momentum behind fixing packaging and handling multicore.
Now if someone would just figure out ad-hoc polymorphism (just pick one of the dozens of propasals) and maybe even document camlp4/5....
Having used CMUCL/SBCL for a while, I always found ocaml's "well, you can compile your code, but then you can't run it in the REPL" to be off-putting. (For my purposes the CLR JIT compiler for F# is good enough.)
- both Kotlin and ClojureScript don't compile code written in their "native" language (java) to JavaScript, limiting the ability to leverage existing libraries. - ScalaJS is still experimental. - Haskell looked promising, I asked a haskell programmer to run that evaluation for me, but fay/haste aren't complete enough for serious (non-ui) JavaScript work and GHCJS generates 5mb JS files. - OCaml had a viable project in about half the time I estimated it would take.
And on a personal note, Scala seemed great at first but after SML/OCaml I find the number of times that I have to tell the type checker what I'm doing immensely frustrating :)
I have three issues with Scala:
- Having to wrap free functions in objects
- I feel Haskell type system is easier to understand than Scala's
- The concept of open and closed case classes for sum types feel wrong
So in the end I actually enjoy more using F# in general, and Clojure when targeting the JVM.
Now back to reading "Real World OCaml". :)
The only real reason that I can see to choose OCaml over Haskell is that if you learn OCaml, you might be able to work at Jane Street. Is there a strong argument for abandoning my Haskell-ing for OCaml?
That's easily fixed: only the toplevel requires ;; (to commence evaluation of the phrases you've typed in). Just don't use it in normal code and everything will parse fine.
That's an exaggeration. There are circumstances in files where it's necessary. I didn't realize this, which hung me up for a long time.
Does anyone have any insight into why OCaml rose to (relative) prominence and not SML?
Edit: A more lengthy comparison: http://adam.chlipala.net/mlcomp/
OCaml has been moving forward; GADTs were added recently, multicore support is coming, and who knows what else is on the horizon.
Technically, yes, it's a statically typed system. But its use of structural typing instead of nominative typing effectively means it takes half the compiler assistance you can get out of static type checking and chucks it out the window. Using structural typing means that a type is nothing more than the sum of its parts; nominative typing makes it possible to add further specificity to types by naming them. This is huge. A language that doesn't do this is a language that can't be taught to understand the difference between 12 meters and 12 Newtons.
module M =
struct
type newtons = int
let inc some_newtons = some_newtons + 1
end :
sig
type newtons = int
val inc : newtons -> newtons
end
M.inc 1 (* this works *)
module M =
struct
type newtons = int
let inc some_newtons = some_newtons + 1
let in_newtons x = x
end :
sig
type newtons
val inc : newtons -> newtons
val in_newtons : int -> newtons
end
M.inc 1 (* type error *)
M.inc (in_newtons 1) (* this works *)
The use of hidden types in OCaml gives far better control over encapsulation and implementation hiding than any over language I've used.In general, it is easy to get nominative behaviour out of a structural system. It is much harder to get structural behaviour out of a nominative system.
# type meters = I of int;;
type meters = I of int
# let meters i = I i;;
val meters : int -> meters = <fun>
# type newtons = I of int;;
type newtons = I of int
# let newtons i = I i;;
val newtons : int -> newtons = <fun>
# let f b = if b then newtons 12 else meters 12;;
Characters 36-45:
let f b = if b then newtons 12 else meters 12;;
^^^^^^^^^
Error: This expression has type meters but an expression was expected of type
newtonsIt is quite rare for people to use objects in ocaml anyways, so it doesn't matter much.
>A language that doesn't do this is a language that can't be taught to understand the difference between 12 meters and 12 Newtons.
Sure it can. Make a type for meters and a type for newtons. Haskell won't think there is a difference between those if you make them both an int either.
I know things like typescript or dart have special versions of the framworks, but i'm curious to know how the ocaml to js tools behave ( since i've searched for a decent strongly typed server side technology for years, that would be an argument for me to try that language).
Most other AltJS languages I've seen are primarily based around FFI declarations, where all interaction with JS is done via functions declared in the native language as external and implemented in JS.