
OCaml: what you gain - edwintorok
http://roscidus.com/blog/blog/2014/02/13/ocaml-what-you-gain/
======
nathell
I have very fond memories of OCaml. It was OCaml that introduced me to
functional programming, way back in 2000 in my freshman year at the uni. I'm a
Lisper/Clojurian these days, but I think warmly of OCaml's type system, the
speed, the self-containedness of the distribution, and the fact that getting
the code to compile tends to mean getting it to actually work.

My #1 gripe with OCaml is the fact that its strings are composed of single-
byte characters. I know there's Camomile, but not having it as part of the
language core creates a sense of disintegration akin to PHP and Python 2.

There's also this: [http://www.podval.org/~sds/ocaml-
sucks.html](http://www.podval.org/~sds/ocaml-sucks.html) which I mostly agree
with.

But, all in all, OCaml rocks.

~~~
fzltrp
> I know there's Camomile

Camomille is great, but it exhaustively covers the _whole_ UTF standard, which
you might not need for more casual uses. There are other libraries bringing
lighter support for UTF strings (ocamlnet for instance I believe).
Nevertheless, Camomille does a pretty good job if you're concerned by
compliance.

> There's also this: [http://www.podval.org/~sds/ocaml-
> sucks.html](http://www.podval.org/~sds/ocaml-sucks.html) which I mostly
> agree with.

It's a pretty old page. I'm not sure its content is still accurate. I'll have
to look into that.

~~~
agumonkey
> created: 2007-01-31 > updated: 2013-02-11

not that old, even though ocaml metabolic rate increased a lot in the recent
years

~~~
fzltrp
Well, I don't know. The "No polymorphism" section is misleading (though
polymorphism doesn't carry the same meaning from one language to the next):
There's this comment on higher order functions not being supported which
surprises me. See the section 7.13[1] and 7.14 of the OCaml documentation.
These features are availabe since ver 3.12 of the distribution.

[1]: [http://caml.inria.fr/pub/docs/manual-
ocaml-4.01/extn.html#se...](http://caml.inria.fr/pub/docs/manual-
ocaml-4.01/extn.html#sec227)

------
p4bl0
If you program in OCaml be sure to checkout Batteries [1], it is an extension
(which also replaces some stuff) to the standard library which eliminate most
of the criticisms I had against OCaml. Also, don't try to avoid opam [2], I
didn't really want to use it at first because I always prefer to use my
system's package manager (using Debian), but it makes your life so much
easier.

[1]
[http://batteries.forge.ocamlcore.org/](http://batteries.forge.ocamlcore.org/)

[2] [https://opam.ocaml.org/](https://opam.ocaml.org/)

~~~
amirmc
Do people try to avoid using package managers? Why? On my system I regularly
use homebrew and opam but also have occasional need for pip, cabal and more
recently npm. Not everything is packaged upstream (nor would I expect it to
be).

I can't imagine how the OCaml ecosystem worked before opam as it's rapidly
become a fundamental tool.

~~~
p4bl0
I don't know, my instinct tells me that I should avoid having many independent
package managers in order to keep everything in the same place and avoid
conflicts. But I don't really have any reasons to think that those are better
ways to do things.

~~~
tommorris
My instinct agrees with you, but for one small matter. Ubuntu only just
started packaging Ruby 1.9.3 - a version that came out years ago and which is
to be deprecated next year - in the latest version.

I don't know about OCaml but trying to do Ruby or Python development without
using pip or gems (not to mention virtualenvs or RVM gemsets etc.) seems like
an exercise in futility and perpetual brokenness.

I'd like it if system package managers could actually keep up with the needs
of developers, but they seem to have failed. Until they can get their shit
together, we now have the irritation of managing all these many, many
language-specific package managers rather than just using apt-get like sane
people. If the system level package manager were able to talk to the language
level package managers, that'd be a big improvement.

The number of times I've typed `sudo gem install nokogiri` and then had to
fumble around and work out exactly which variant of libxml-dev-0 or whatever
is needed before I can install a RubyGem with a native dependency shows we've
got some brokenness that needs fixing.

~~~
technomancy
> I'd like it if system package managers could actually keep up with the needs
> of developers, but they seem to have failed.

I would argue that they fail at this because it's a goal that's in direct
conflict with their primary goal: to serve end users. The needs of developers
are dramatically different. Having multiple versions of a package is a must
for developers, but would just cause weird unpredictable issues for end users.
(Unless you are very clever and do something like Nix, of course.)

I wrote more about this topic here:
[http://technomancy.us/151](http://technomancy.us/151)

------
srean
If I may repeat an old comment of mine, lightly edited for freshness (I dont
mean to hijack this thread. It is not often that I get an opportunity to
interact with people on HN who are fond of OCaML or are likely to have an
interest in it. This is the exact demographics who might appreciate Felix)

    
    
        --
    

For the early adopters and experimenters amongst you, you might like Felix
[http://felix-lang.org/share/src/web/tut/tutorial.fdoc](http://felix-
lang.org/share/src/web/tut/tutorial.fdoc)

The site is undergoing a major reorganization right now, so some links will
break.

It is a whole program optimized, strongly typed, polymorphic, ML like language
that can interact effortlessly with C and C++ and has coroutines baked in. 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.

Its own demo webserver is based on coroutines, this is the same webserver that
serves the language tutorials. 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.

With inaccuracies in analogies assumed, Felix is to C++ what F# is to C# or to
some extent Scala is to Java.

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](http://felix-
lang.org/share/src/web/ref/tools.fdoc)

The author likes to call it a scripting language but it really is a
fullfledged statically compiled language with a single push button build-and-
execute command. [http://felix-lang.org/](http://felix-lang.org/) The
"fastest" claim is a bit playful and tongue in cheek, but it is indeed quite
fast and not hard to beat or meet C with.

    
    
      --
    

Removing comment and putting it here to conserve real estate.

@zem I think you just blew your cover :) As I said its been mostly a one man
effort, so there are areas that need work. Its an exciting language, welcome
aboard.

@jnbiche Oh no! I am by no means the creator, just someone who finds it
exciting.

~~~
scott_s
Please respond to comments directly rather than trying to "preserve real
estate". It makes it much more difficult to follow conversations.

~~~
srean
Noted.

I had participated in a rather contentious thread today and there the nesting
had gone way out of hand. That and I did not want my comment to be the
dominant conversation on this post.

I got downvoted here, so its likely that my within-post conversation annoyed
some. Yes, I know you didn't downvote. Its also possible I came across as a
conversation hijacker. That was certainly not my intent. Have to say the blog
posts are strikingly well written. In fact quite surprised how a Python
aficionado takes to OcaML like duck to water so quickly. (Duck typing pun
narrowly avoided)

------
rjzzleep
You might like F# even more(well except that clr is not as good outside of
windows, but still pretty decent)

As my coworker at the time put it. If Ocaml and python had a baby together it
would be f#

~~~
doorhammer
I'm a big fan of F# as well. I haven't tried it outside of windows, on mono.
I've always wondered how well supported mono was and what the library
ecosystem was like (I could just google that, and probably will)

Any personal experience with it?

Right now I'm diving into haskell, partly because I want a static, type-
inferred, functional language on linux (my home platform of choice) and partly
because I like the idea of using a language that has really pure (functionally
and generally) ideas it's trying to implement. Digging it a lot so far as
well.

~~~
balakk
F# has a huge following on macs. The Xamarin guys drive it, and practically
every major open source .Net library is available for mono.

I haven't tested it on linux, but I've found it works pretty well on macs.

~~~
latkin
The Seattle F# user group just had an event last night, and the first talk was
1 hour on how to create iOS apps with F# using Xamarin/Mac. If anyone is
interested, a recording is at
[http://www.youtube.com/watch?v=MriHEnq5MR4](http://www.youtube.com/watch?v=MriHEnq5MR4)

------
Buttons840
OCaml looks really good, I've heard good things about it for awhile now. I'd
like to learn more but and currently learning Haskell and want to focus on
learning that for awhile.

Does anyone know why OCaml gets compared to Haskell so often? It sounds like
OCaml doesn't force a purely functional paradigm on you, so how is it any more
functional that a number of good scripting languages (Python, Ruby, Peal,
etc)?

~~~
tel
OCaml has a similar type system to Haskell's. It has algebraic data types. It
also has all the normal higher order functions and combinators "done right".
It also commits strongly to using first class modules as an organizational
component atop the functional core.

I don't think "functional" means a whole lot. Many languages with lightweight,
first-class lambdas like to jump on that bandwagon by implementing
map/fold/scan/take combinators on lists, sometimes even lazy ones, but that
whole game is just a sideshow to the real meat of what makes Hindley-Milner
typed languages with ADTs quite fun to work in.

~~~
seanmcdirmid
Hindley-Milner is fun until you need nominal subtyping or mutable assignment,
then the whole "semi-unification is undecidable in general" comes up to bite
you.

~~~
tel
How does HM get in the way of mutable assignment?

~~~
emillon
Polymorphism (more precisely, generalization of unknown types) is incompatible
with references. For example:

    
    
        let r = ref []
    

Here r has type 'a list ref (reference to a list of 'a where 'a is unknown).

    
    
        r := ["hello"]
    

r has type 'a list ref, := has type 'a ref -> 'a -> unit, and ["hello"] has
type string list, so it works (if we instantiate 'a with string).

    
    
        let n = 1 + (List.head !r)
    

1 has type int, + has type int -> int -> int, and we can type (List.head !r)
as int since we can type !r as int list since we can type r as int ref list
(this time instantiating 'a by int).

So, we just added an int and a string and the program will probably crash.
What's wrong is that every line is correct but because of the mutable store,
the program as a whole is incorrectly typed.

The solution is to generalize only a subset of all syntactic constructs. The
historic solution in Ocaml is to never generalize expressions that may
allocate memory (that's the "value restriction") . For example, a function
application (like f x, or ref []) may allocate, but a variable or a constant
(like x or 1 or []) can not. That's why [] has type 'a list but ref [] has
type '_a list ref ('_a can be unified only once, so in the above example an
error would occur at the "let n").

~~~
tel
Ahh, that's sort of obvious in retrospect, but I was blinded thinking in terms
of Haskell where IO protects against such generalization.

~~~
emillon
The equivalent Haskell program is

    
    
        import Data.IORef
    
        main :: IO ()
        main = do
            r <- newIORef []
            writeIORef r ["Hello"]
            x <- readIORef r
            print $ x + 1
            return () 
    

The reference is bound by "r <-", ie a lambda (as this desugars to ">>= \ r
->"), and lambdas are never generalized (even in ocaml).

I think that the reason why it works is that because there is no way to let-
bind r except with a toplevel unsafePerformIO.

~~~
tel
Yup, that's precisely what I forgot to think about.

------
raphinou
I'm planning to learn ocaml in the coming weeks, as I want to try ocsigen
([http://ocsigen.org/](http://ocsigen.org/)). Seems to me there is good
activity in the Ocaml community lately (eg new books came out recently)

~~~
p4bl0
I like OCaml but really, Ocisgen is crap. People making it have no idea how
today's web works.

Some parts of it (lwt, js_of_ocaml) are nice and maybe useful piece of code,
but you don't want to use the framework as a whole to develop a webapp.

The problem with Ocsigen is that it reinvents the meaning of everything, even
the HTTP verbs, to suit its internal needs. For example, it is not possible
(or it must be very painful) to make an API for your Ocsigen app so that other
apps can interact with yours. First, you have to forget PUTs, HEADs, and
DELETEs, but also GETs and POSTs are used incoherently by the resulting code
to update parts of the webpage, submit forms, etc.

If you want to make a site/webapp that only focus on itself and never have to
interact with anything else than its visitors, then Ocsigen might be a
suitable tool for the job, otherwise I wouldn't use it.

Disclaimer: I only used Ocsigen for one day, it was at JFLO, which expansion
in French would translate to French Ocsigen Lectures Day. I get what I know of
it and what I'm saying here by the day-long courses and hands-on tutorials
given by Ocsigen developers and by discussing these problems with them
afterwards.

------
mercurial
> Another example is the Config object. When I started the Python code back in
> 2005, I was very excited about using the idea of dependency injection for
> connecting together software modules (this is the basis of how 0install runs
> programs). Yet, for some reason I can’t explain, it didn’t occur to me to
> use a dependency injection style within the code. Instead, I made a load of
> singleton objects. Later, in an attempt to make things more testable, I
> moved all the singletons to a Config object and passed that around
> everywhere. I wasn’t proud of this design even at the time, but it was the
> simplest way forward.

That's called a "god object", unless I'm mistaken. It's an abomination in any
language. I have the misfortune of maintaining a codebase with this "feature".
Never, ever, do anything like this.

~~~
raphinou
Never used or inherited such a design, but I'm curious about what practical
problem you encoutered. Care to illustrate?

~~~
mercurial
Once you have implemented this design pervasively, you can forget about
reusing your code in another context. Because it is impossible to tell which
part of the god object is needed in a given part of the code, you have to
initialize everything in the god object. With a bit of luck, you're working in
Java and mixing this anti-pattern with some Spring dependency injection, in
order to make this mess really impossible to untangle.

And obviously it encourages mixing up layers. Why have modularity when you can
access your data access components from anywhere?

And in general, circular dependencies are a code smell. Whenever I thought I
needed to use them, I came to realize it was the wrong decision.

------
swah
OCaml is a great language, but IIRC the creators didn't talk much to the
community, about where they were going, etc. Contrast with Clojure, Golang,
Python... So many people steer away and go bet on something else.

~~~
avsm
The conversation between the OCaml creators and the community is a lot more
focussed. Back in 2005 when we were developing the Xen toolstack using OCaml
[1], I subscribed Xensource to the Caml Consortium [2]. This let us meet with
the main team once a year, and air our concerns in a structured way. This is
so much easier to handle than a firehose of e-mails. Nowadays I still attend
the annual Consortium meeting, but more in a capacity of reporting on our
activities at OCaml Labs and there are still a healthy set of industrial users
who like this mode of interaction.

[1] [http://anil.recoil.org/papers/2010-icfp-
xen.pdf](http://anil.recoil.org/papers/2010-icfp-xen.pdf) [2]
[http://caml.inria.fr/consortium/](http://caml.inria.fr/consortium/)

------
supercoder
But what you lose seems to be readability if going by this code sample

let menu = GMenu.menu () in let explain = GMenu.menu_item ~packing:menu#add
~label:"Explain this decision" () in explain#connect#activate ~callback:(fun
() -> show_explanation impl) |> ignore; menu#popup ~button:(B.button bev)
~time:(B.time bev);

~~~
fzltrp
I don't know how other similar languages deal with GUI. It's always sort of
hairy, obscure code when you look at it closely. Mainstream languages (like
Java) usually give you GUI building tools which generate all the boilerplate
stuff, but if you look at that generated code, it doesn't look so appealing
either imho.

If you know the GUI libraries inside out, then the code becomes much easier to
grasp though. The lablgtk library (which provides gtk support) is quite well
written, providing both a modular interface and objects, but indeed there's a
learning curve.

Lastly, you might find it more palatable with a little bit of formatting:

    
    
      let menu = GMenu.menu () in 
      let explain = GMenu.menu_item ~packing:menu#add ~label:"Explain this decision" () in
      let callback () = show_explanation impl in
      explain#connect#activate ~callback |> ignore; 
      menu#popup ~button:(B.button bev) ~time:(B.time bev)

~~~
Eiwatah4
> I don't know how other similar languages deal with GUI. It's always sort of
> hairy, obscure code when you look at it closely.

The best languages for GUIs I've seen are specialized declarative DSLs. Things
like QML, XAML, JavaFX FXML, XUL, and even HTML. Anything else very much
sucks, in my experience.

~~~
danieldk
And Qt pre-QML. The user interface is declaratively described in XML (which
can be edited visually with Qt Designer). You then use a utility (uic) to
generate e.g. C++ class which you can use through composition and inheritance.
UI events are wired to code through Qt's signal/slot system.

------
thebiglebrewski
Title made me think of this
[http://www.youtube.com/watch?v=B9MgWFU3JhM](http://www.youtube.com/watch?v=B9MgWFU3JhM)

