
An OCaml manifesto – Problems and what's needed for widespread adoption - e_d_g_a_r
https://github.com/fxfactorial/an-ocaml-adoption-manifesto
======
toolslive
I've been using OCaml for system's programming for 6+ years, and it's better
than most other things we've tried. I guess any (mostly) functional language
with a static type system based on Hindley-Milner would give the same
advantage. This advantage is basically: the compiler acts like a neo nazi and
slaps you mercilessly on the head whenever you do something stupid. So in the
end, you can often get to the "if it compiles, it works" promised land.

The situation improved drastically over the last years with opam which allows
easy installation of most packages.

What's still missing, however is

\- decent multi core

\- resource management for things other than memory. For example, bigarrays
don't cause enough gc pressure, and can therefore leak space. Thus people tend
to manage that manually (acquire, release) which is even worse than what a C++
dev can use (unique_ptr)

\- decent profiling (yes I can leverage strace and callgrind, but they don't
understand lwt)

\- decent runtime inspection. (what are all theses values in my heap?)

~~~
paxcoder
That comparison makes no sense.

~~~
dang
Maybe not, but a comment like this helps no one. If you know enough to make
such a claim then you know enough to show _what_ the problems are, and that
would make a much better comment. We'd all learn something.

~~~
paxcoder
It might be considered poor form not to spell the problem out, however I
honestly think it is crystal clear

But what's interesting is that I was being upvoted until I've rephrased the
comment. It used to be "That's an unfortunate comparison you've made". In the
same time it sounded more moderate and more personal. I've edited it because
moderation came at the cost of authenticity/honesty, and I thought addressing
the comment risked automatic rejection of the underlying message on the OC's
part. I did think that the actual sentiment could sound worse to others, but
it would be hypocritical of me not to have gone with it. The underlying
message is precisely "don't conform on account of genuineness".

Hope this cleared something up after all

------
muraiki
A few weeks ago I started learning OCaml via Real World OCaml. However, I
became concerned when I discovered that there are multiple competing "standard
libraries" and that there are also two different competing async frameworks.
It looks like work is being done to ensure that the async frameworks are
interoperable, but the existence of various standard libraries is worrisome to
me.

In particular, while the one used in RWO (Core) seems very nice, it looks like
its use of named parameters is via some kind of syntax extension (edit: not
the case; see LeonidasXIV's reply). This seems to be a pretty large difference
in approach, and while I can appreciate the reasons behind using named
parameters in Core, it makes me worried about writing code that might have to
interact across different stdlibs.

As such, I've decided to hold off on learning OCaml for now until resolutions
to these community issues can be made more clear. But perhaps I just prefer
the Python approach, and that may not be the same objective as those in OCaml.

Edit: Actually, the nail in the coffin was probably when I found a web
framework that I wanted to use, but then the author explained why he was
removing support for both of the async frameworks and going with only one of
them (the one that RWO doesn't use). And then the other main web framework I
found also used non-RWO async... :(

~~~
LeonidasXIV
> it looks like its use of named parameters is via some kind of syntax
> extension

No worries, OCaml natively supports named (and optional) parameters. What Core
does, though, is reshuffle many function signatures to be more useful when
using those parameters.

I suppose you're talking about this[0] blog post, his reasons are pretty
clear: hardly anybody uses Async apart from Jane Street, whereas Lwt is much
more popular, used by standalone projects, many bindings, as well as Mirage.

The reason RWO used Async is that it is basically a companion to Core and one
of the authors of the book is also the author of both Core and Async.

[0]: [http://rgrinberg.com/blog/2014/12/11/abandoning-
async/](http://rgrinberg.com/blog/2014/12/11/abandoning-async/)

~~~
muraiki
I'm sorry for misunderstanding OCaml's built in support for named/optional
params.

The problem with Async is that what seems to be the best resource for learning
OCaml in 2016 teaches Async, not Lwt. I was excited to use it until I
discovered that many things I was interested in use Lwt instead. It's not hard
to learn Lwt, but this discovery made me think about the problems I've had as
a professional Perl programmer in dealing with Perl 5's multiple competing
event loops.

~~~
LeonidasXIV
I can completely understand your worries and I agree that it is rather
inconvenient, esp. since Lwt does not have a great introduction to start with.

The upside is that with the hopefully soon upcoming algebraic effects that are
supposed to appear in OCaml sooner or later, Lwt and Async might end up being
obsoleted or subsumed into a compatible set of Async primitives.

------
mercurial
I'm wary of the term "ORM" and in particular the idea that you'd get your SQL
defined at compile, which is exactly what something like PGOcaml does, and
which is a bad idea if it's the only game in town. As someone who gets to
write SQL fairly regularly, I'm a lot more interested in composability than
anything else (I'll even trade type safety for composability if I have to pick
one).

I'd rather have a system to generate composable queries (hopefully in a
typesafe manner) and able to use modern SQL syntax (eg, window functions),
without the stuff you typically find in an ORM (identity map, magic setters,
etc)

~~~
snuxoll
This is something that really bugs me about OCaml in general. There's really
no _good_ option to do database access that doesn't involve writing raw, non-
composable SQL queries. I don't need a full blown ORM, but something that
makes writing type-safe (and injection-resistant) SQL queries like JOOQ would
be absolutely amazing. For now I'm just sticking with Python and SQLAlchemy,
as much as I love OCaml and F#.

~~~
insulanian
F# doesn't fit into the rest of your comment. There are type providers and
Entity Framework, both of which are very good options for DB access.

~~~
snuxoll
IFF you are using Microsoft SQL Server, sure. Any other RDBMS is a crapshoot,
I've been using FsSql which works but I have to devolve into manually
manipulating SQL Query strings to do anything sufficiently advanced.

Technically there is SQLProvider, but it's ugly as sin (I also don't care for
type providers in general, I don't need automatic code generation, I have no
problem specifying my schema and not needing access to a database server just
to compile my code).

~~~
insulanian
I'm using PostgreSQL with Entity Framework and running my code on Mono. It all
works in production on an AWS Ubuntu instance with DB in RDS. Very happy.

Edit: Forgot to mention that no Visual Studio or Windows is used in the
process.

~~~
snuxoll
Entity Framework is extremely heavy and not really what I am looking for. I
really just want a lightweight layer over SQL that makes query generation
safe, not a full blown ORM (think JOOQ, SQLAlchemy).

~~~
daxfohl
I use Dapper with F# both on Mono/Linux (test/prod) and on Windows
(dev/build/test) and it works great and I've never had an OS porting issue in
three years. There are extensions that make it more composable, but haven't
needed them yet.

Type safe solutions, in terms of using code expressions that get translated
into SQL, exist too. However everywhere I look people complain about how
horribly inefficient and frequently buggy the generated SQL is. This is true
in LINQ, EF, Scala's SQL generator, etc. Stackoverflow obviously created
Dapper for a reason. So I've thus far avoided these "too clever by half"
solutions; Dapper is perfectly fine.

------
systems
kinda sorta, the reason why people still thing of ocaml is because janestreet
use them, and janestreet makes a lot of money .. and we all want to make
money, so somewhere vaguely some people can/may link ocaml with money

i love ocaml, i love ml languages, and i think ocaml is a very good ml

but, i think its kinda too late for it, i think people who want to program
with types today most likely will go to rust, scala or f#

ocaml is very niche

~~~
pcwalton
Which is a shame really, because OCaml is a very nice language. Everyone who
is interested in "worse is better" design should really study it (and I mean
"worse is better" in the most genuinely approving sense). I don't think I've
ever seen a language other than SML and OCaml that sits in such a "sweet spot"
on the simplicity-vs-power tradeoff for general-purpose programming (not
counting the module system of SML and the object system of OCaml). I honestly
think that OCaml's type system is simpler than a lot of other type systems
that people think of when they think of "simple type systems". ( _Including_
its support for generics—OCaml is proof that generics can be an extremely
simple feature that add basically no complexity to a type system, contrary to
popular belief.)

I think the biggest issue with OCaml for mainstream adoption is the syntax,
honestly.

~~~
virtualwhys
> I think the biggest issue with OCaml for mainstream adoption is the syntax,
> honestly.

Indeed, a barrier in itself, after working through RWO I was impressed with
the language, clearly very powerful, but some aspects of the language are
syntactically unpleasant.

Yes, yes, semantics, not syntax, but new comers will come in all forms,
including those who will just say no based on the general "look" of the
language. IMO, if OCaml had the same power but looked more like SML it would
have much greater adoption.

Anyway, modular implicits and multi-core will certainly help OCaml to grain
traction, syntax notwithstanding.

~~~
daxfohl
In layman programmer terms, what are modular implicits? Are they like (please
no) Scala's implicits? (Or is there some way Scala's implicits are less scary
than years past?)

~~~
whateveracct
Scala implicits are really one of the "killer apps" of its type system. No
language I know of really has anything quite like it.

Scala "implicits" mean two different things:

1) implicit conversions. e.g. If there is an implicit def f(x: Int): String =
x.toString in scope, then any time you try to use an Int where a String is
expected, Int::toString will be called automatically. Using implicit
conversions like this is generally frowned upon and also where the "please no"
probably comes from.

implicit conversions are used frequently but almost entirely for extension
methods (there's even sugar for it now: "implicit class")

2) implicit parameters. These are parameters in a functions type signature
keyed by type. You can emulate Haskell typeclasses (sans canonicity) with
these. For instance

def monoidSum[A](as: List[A])(implicit m: Monoid[A]): A =
as.foldLeft(m.zero)(m.append)

is equivalent to the Haskell

monoidSum :: (Monoid a) => [a] -> a

monoidSum as = foldl' mappend mempty

Scala implicit parameters can be defined inductively and depend on other
implicit parameters. You can do this to perform some really cool type-level
computation. The shapeless library is full of stuff like this. Once you
understand implicit parameters, it really is somewhat nice to write functions
that operate on arbitrarily-sized HLists and Coproducts.

Modular implicits are similar to (and inspired by?) Scala implicit parameters.

------
jfaucett
I'm not a big OCaml user, have used it on occasion for a few small projects
and I liked it, but from what I remember, I think a few things are missing
from this list if OCaml wants to obtain widespread adoption.

1\. Really good unicode support

2\. A dead simple high quality package manager i.e. bundler, mix, cargo.

I'd also add built-in concurrency primitives i.e. (Channels in Go, Processes
in Erlang), though this probably isn't a must have currently, but will surely
only become more important as time progresses into the multicore future.

~~~
e_d_g_a_r
1\. There are libraries for that. 2. opam.

~~~
jfaucett
"1\. There are libraries for that."

Yes, but I just think unicode support is so pervasive its not something you
should really leave up to a library in 2016. Still this is just my biased
opinion as a developer who needs it on virtually every project.

"2\. opam."

see:
[https://opam.ocaml.org/doc/Packaging.html#Publishing](https://opam.ocaml.org/doc/Packaging.html#Publishing),
- basically, I think requiring a PR on github to get a package published is
not "dead simple".

Finally, the title contains "widespread adoption". There is no modern language
on the Tiobe Index top 20 without those two characteristics except for
possibly MATLAB and C# which both don't have good package managers as far as I
know, but I could be wrong since I've never used either one of them.

The List:
([http://www.tiobe.com/tiobe_index](http://www.tiobe.com/tiobe_index))

Anyway, I'd like to see ML get more adoption. I think fixing these things are
more fundamentally important than some others such as web frameworks, etc...

~~~
jlarocco
I agree with you completely on #1. Without built in support, people screw up
Unicode. They either won't use it at all, or they won't use it in all the
places it's needed, and by the time it becomes a problem, it's a big problem.

On #2, I disagree. The effort required to make the pull request is a small
fraction of the effort required to make a library worth adding to Opam. At the
same time, it's enough effort that it should prevent the NPM problem of a
million stupid "libraries" for 2 line functions.

I'm in the same boat as a lot of people here, in that I think OCaml looks
great except for a few big shortcomings that they've ignored for a long time
(unicode, multi-threading, etc.) that end up being deal killers for me. As I
put it in another thread a while back, it's not even that I _need_ the missing
functionality all the time, it's that they refuse to add any of it for as long
as possible.

~~~
edwintorok
OCaml 4.03 will have a minimal UChar type and module, that will allow various
Unicode libraries to agree on a common type:
[https://github.com/ocaml/ocaml/pull/80](https://github.com/ocaml/ocaml/pull/80)

According to the author of one of the Unicode libraries that is the only thing
the compiler should distribute by default, and I agree with that, otherwise
you need everything that comes with Unicode too to make it useful:
normalization, segmentation, etc. If an application needs that it can link
with the unicode library, having it separate from the compiler means features
and updates can be implemented faster.

Also see here on how other languages (Python in this example) got it wrong:
[https://sympa.inria.fr/sympa/arc/caml-
list/2014-07/msg00050....](https://sympa.inria.fr/sympa/arc/caml-
list/2014-07/msg00050.html) [https://sympa.inria.fr/sympa/arc/caml-
list/2014-07/msg00054....](https://sympa.inria.fr/sympa/arc/caml-
list/2014-07/msg00054.html)

The linked introduction to Unicode (for OCaml but not only) is also very
informative:
[http://erratique.ch/software/uucp/doc/Uucp.html#uminimal](http://erratique.ch/software/uucp/doc/Uucp.html#uminimal)

------
pklausler
Sincere question: as a Haskell programmer, why should I also learn/use O'Caml?

~~~
adamwk
One advantage ML has over Haskell is that it's not opinionated on how one
manages effects. How effects are managed in ML is a design decision by a
library author, whether that be monadic or eff-style or sprinkling a printf
here and there.

~~~
lomnakkus
Interestingly, that's _also_ a _dis_ advantage since you cannot control
effects (in the user-supplied code) if you're e.g. writing a library API with
callbacks. On the advantage side you have what you mentioned, namely "benign"
effects -- but I've found that the "sprinkle a few debug printfs" use case is
adequately handled with Debug.Trace... unless you're trying to debug a
terminal application! :)

Logging is another popular example of a "benign" effect, but I personally
don't think is: I mean, your logging library could be doing all kinds of weird
things like shipping logs over TCP to a remote syslog daemon... and I don't
want that to be hidden under the rug (using unsafePerformIO or similar) only
to blow up later when the network happens to be down.

Anyway, having programmed in O'Caml for 3-4 years, I was won over to Haskell
by the compiler-supported (side) effect tracking. I think it's also important
to note the distinction between _side_ effects and plain (desired) _effects_.
Not enough people do this in these sorts of discussions.

------
openplatypus
Great write-up. If I could nitpick a bit I would say...

I am on the fence with ORMs. Yes, they make 80% of cases possible, remaining
19% difficult and last 1% sometime impossible.

Having Slick (Scala) and JOOQ (Java) makes code much more transparent,
explicit and easy to maintain. Debugging nasty stateful session bugs (oh JPA)
can be nightmare.

------
vrotaru
I like OCaml, just.. Has it ever been anything which can be called a
successful manifesto?

I, certainly, do not remember one for JS or Node.

------
jsli
The article mentioned OCaml meetup in Bay Area. Where can I find one?

~~~
LeonidasXIV
Here you go[0] organized by e_d_g_a_r. As far as I've heard the show up rate
is pretty good.

[0]: [http://www.meetup.com/sv-ocaml/](http://www.meetup.com/sv-ocaml/)

~~~
jsli
Great! Thanks.

------
swah
If only OCaml was handled like Go is...

~~~
placeybordeaux
Developed and shepherded by one of the most powerful companies in the world?

~~~
swah
Still more open and closer to the community than OCaml... Or do you see Xavier
Leroy talking to people like @bradfitz?

