
Introduction to Functional Programming in OCaml - melling
https://www.fun-mooc.fr/courses/course-v1:parisdiderot+56002+session03/about
======
k__
Can anyone explain why OCaml seems easier for people from non-FP backgrounds
than Haskell?

I tried Haskell and PureScript and didn't understand a thing.

I tried OCaml and Reason and it felt rather easy to learn.

~~~
andrepd
There are two major differences between OCaml and Haskell.

First: Haskell is a pure functional language, meaning that side effects, IO,
keeping state, all that must be dealt with inside the type system, which while
undoubtly clean and powerful, it makes it often cumbersome to do things that
should be quick and simple. OCaml, on the other hand, is pragmatic. It
promotes and facilitates functional programming _but_ it also let's you easily
"drop down" (so to speak) to an imperative way to write code. You have mutable
variables, imperative loops, you can perform side effects anywhere, etc. As a
rule of thumb, you can write fully functional code, yet sometimes when the
best way to write a certain thing is imperatively, you can do so with no
hassle.

Second: Haskell is lazy, and OCaml is strict. This makes it _much_ easier to
reason about performance and makes for much more predictable code. At the same
time, it has first-class support for laziness when you do need it, but you
have to explicitly "opt in", so to speak. Haskell also lets you force strict
evaluation, but you will find it's much easier to build laziness in a strict
language than the other way around.

There are also other important differences (like typeclasses vs functors) but
I feel these two are the biggest ones.

~~~
arunix
Why does laziness hinder reasoning and predictability?

~~~
atombender
Laziness disassociates the execution of a function from its call site. A
classic novice mistake is to accidentally read a file after closing it --
something that can happen even if the "read" function is called before the
"close" function in the code. It happens because the read function isn't
actually called until its return value is used, and that can very well happen
after the close call.

So you have an implicit dependency graph of evaluation that doesn't exactly
match the chain of function call. You may find that some slow code gets
deferred until in the middle of some time-sensitive code, for example. You
could also have something blow up that's completely unrelated to the calling
code, again because of the laziness.

The opposite of lazy is strict, and Haskell does let you "opt in" to
strictness when you require it.

------
a0
For everyone interested in learning OCaml, there's a very active Discord
community where you can ask questions:
[https://discord.gg/ZBgYuvR](https://discord.gg/ZBgYuvR)

Join and say "hi"! :)

------
funfunfun
Does anybody else think functional programming is just one end of the
either/or fallacy? Maybe a trap for contemplative people?

The ultimate goal of software is to build something useful. The "functional
programming tutorial:real world uses" and "claims of superiority:adoption"
ratios are suspiciously high.

~~~
hellofunk
I've been primarily a professional Clojure developer for several years, that's
how I earn my living, and thus I have used the language in many contexts. In
the beginning I was in love with it, in hindsight at least part of this love
was the thrill of doing something new. But my appreciation for that style of
programming has gradually declined over the last 5 years.

FP is great for many little things you might have to do. But for larger
architectural considerations, I still find notable advantages to creating
custom classes that have their own public API, private internal
implementation, and that manage their state internally. In the absence of
this, you have lots of functions that are basically sitting alone with their
pure inputs and outputs, and to manage state requires more effort, not less,
in a lot of situations. Each of these functions has to receive the thing they
are acting on, and a separate group of functions manages the actual mutation,
acting as "controllers" between these more pure functions and the actual
stored state. The result is a less elegant program structure sometimes.

FP enthusiasts like to say that "it's better for many functions to operate on
common data structures than it is to have many custom data structures with
their own functions." The problem in my experience is that often, these pure
functions are only serving one purpose geared for a particular data layout,
and thus they might as well be coupled to it; the lack of a backbone in larger
FP architectures can be frustrating. In Clojure, you have maps, and all maps
behave the same. Great. But not all maps are actually the same. Each map
ultimately has its own structure, and these functions that operate on a
particular map are really operating on a particular structure a lot of the
time. So you end up with increased verbosity and more difficult-to-follow code
structure than if you just combined the data and its functions in one place: a
class. The record-protocol idea attempts to alleviate this, but I don't feel
it really gets to the heart of the issue.

I think OO and FP each solve problems in equally meaningful ways and different
tasks are better suited to one or the other. I particularly like languages
that don't force you into a particular model. Java and Clojure are quite
opinionated (in opposite ways) and thus often inflexible for certain tasks. My
favorite language for blending these techniques has become C++ but I don't get
to use it as much. It offers true FP-style programming with constructs like
std::function. I wish Java had gone as far as C++11 did; the Java lambdas and
the requirement that they can only be type defined using a static interface is
not really helping to adopt the paradigm.

~~~
yodsanklai
> FP is great for many little things you might have to do. But for larger
> architectural considerations, I still find notable advantages to creating
> custom classes that have their own public API, private internal
> implementation, and that manage their state internally.

In OCaml, you usually do that with modules. For instance, you can easily write
mutable or immutable datatypes that hide their internal representation.

> My favorite language for blending these techniques has become C++

I also like programming languages that embrace several paradigms. The problem
with C++ is that it's a very complex language. Compared to C++, OCaml is a
piece of cake.

------
hazza1
I started this course but really struggled with their strong accents (although
subtitles are available)

Guess I know how the rest of the world feels now watching American tutorials.

~~~
Tempest1981
Beyond the 2-minute intro video, the audio became very faint, with background
noise like a fan humming. Made it tiring to listen to. (Does it get better
later?)

~~~
dmitriid
If you’re on a Mac, it might be CoreAudio acting up.

Try sudo kill-ing coreaudiod

(disclaimer: I haven’t seen the video in question, but I had a similar problem
with online videos in general)

------
melling
My understanding is that F# is a derivative of OCaml.

[https://stackoverflow.com/questions/179492/f-changes-to-
ocam...](https://stackoverflow.com/questions/179492/f-changes-to-ocaml)

[http://web.archive.org/web/20080410181630/http://research.mi...](http://web.archive.org/web/20080410181630/http://research.microsoft.com/fsharp/manual/ml-
compat.aspx)

How’s F# adoption?

~~~
BeetleB
Sorry to hijack the thread:

I recently was trying to decide which language to pick up next: Lisp, OCaml,
F# or Haskell (I know a bit of Lisp and Haskell already, as well as some
Standard ML).

It came down to two: OCaml and F#. The former has poor support in Windows
(work machine), and the latter has less poor support in Linux (home machine).
So I decided I'll probably go with F#. I've been told the syntax is quite
similar, so how difficult is it to translate an F# program to OCaml. Are all
the patterns the same that one can do a more or less 1:1 translation while
still being canonical?

~~~
nestorD
Going from Ocaml to F# is trivial, most of the time it is only a matter of
adjusting the indentation and getting the correct name from the std. Going
from F# to Ocaml tend to be harder since F# has a number of functionalities
that are often used and do not exist in Ocaml (such as parallelism, sequences,
active pattern, list comprehension, type providers, etc and a much bigger
std). As a user of F# on linux, the experience is good (better than Ocaml on
linux) and getting better every year (some library are still windows only but
it is changing).

~~~
ernst_klim
>Going from F# to Ocaml tend to be harder since F# has a number of
functionalities that are often used and do not exist in Ocaml (such as
parallelism, sequences, active pattern, list comprehension, type providers,
etc and a much bigger std)

The opposite is also true, F# does not have ppx, OCaml's object system, GADTs,
polymorphic variants, functors, first class modules, extendable variants.

------
magpi3
A bit offtopic but: has anyone used SML
([https://www.smlnj.org/](https://www.smlnj.org/)) for anything serious?

I fell in love with this language in University long ago (in the 90s), but I
have never seen anyone use it in the wild.

~~~
zem
ur/web is written in sml:
[http://www.impredicative.com/ur/](http://www.impredicative.com/ur/)

~~~
magpi3
Thank you

------
xvilka
There is a work-in-progress second edition of "Real World OCaml" book [1],
which has many small but vital updates corresponding to the modern state of
OCaml and its infrastructure. Moreover, I recommend checking the Lwt [2] from
the beginning for working with multithreading. OCaml Ctypes [3] library for
creating FFI stubs without a single line of C and Cstruct [4] for working with
C structures. If you want to interact with some Python code or script your
OCaml program with Python - you can use Pyml [5] library. OCaml universe also
has a good library for numbers crunching and scientific computing (including
primitive Machine Learning) - Owl [6]. For writing OCaml instead of
JavaScript, it is possible to use BuckleScript [7]. And if you are starting a
new project in OCaml - I recommend using the most modern buildsystem - dune
[8]. It is very simple to use and with a less overhead than others. I found
also Angrstrom [9] is very useful for implementing binary and text format
parsers.

Utop [10] and ocaml-jupyter [11] are the best choice for experimenting,
browsing the API and testing some small things.

[1]
[https://dev.realworldocaml.org/toc.html](https://dev.realworldocaml.org/toc.html)

[2] [https://ocsigen.org/lwt/manual/](https://ocsigen.org/lwt/manual/)

[3] [https://github.com/ocamllabs/ocaml-
ctypes](https://github.com/ocamllabs/ocaml-ctypes)

[4] [https://github.com/mirage/ocaml-cstruct](https://github.com/mirage/ocaml-
cstruct)

[5] [https://github.com/thierry-martinez/pyml](https://github.com/thierry-
martinez/pyml)

[6] [https://github.com/owlbarn/owl](https://github.com/owlbarn/owl)

[7] [https://bucklescript.github.io/](https://bucklescript.github.io/)

[8] [https://dune.readthedocs.io/en/latest/quick-
start.html](https://dune.readthedocs.io/en/latest/quick-start.html)

[9]
[https://github.com/inhabitedtype/angstrom](https://github.com/inhabitedtype/angstrom)

[10] [http://github.com/ocaml-community/utop](http://github.com/ocaml-
community/utop)

[11] [https://github.com/akabe/ocaml-jupyter](https://github.com/akabe/ocaml-
jupyter)

~~~
devmunchies
You recommend LWT, but the book you recommended teaches Async instead. The
split between with libraries to use (e.g. stdlib vs Base) has been frustrating
as I’ve been learning and needing to look up documentation.

~~~
anuragsoni
If you are following the Real world OCaml book but want to see the exercises
in LWT, you can refer to: [https://github.com/dkim/rwo-
lwt](https://github.com/dkim/rwo-lwt)

------
agentultra
This is a fun course. I completed it the last time it was ran and had a blast.
I was proficient enough by the end to start writing small to medium programs
and libraries in OCaml.

~~~
Xophmeister
While this may no longer apply, could you give an idea of the strictness of
the schedule? I am very interested in this, but I'm going to miss the first
two weeks, as I'll be on leave. If it's simply a case of playing catch up,
then that's fine, but if assessments, etc. are rigidly set on dates, then that
would be a deal breaker for me.

~~~
agentultra
As I recall you can complete the course at your own pace. They have an online
checker you submit your exercises to.

------
nraynaud
I am currently doing some interventions in some Ocaml code written by Big Co.
The world is completely different between you writing your program in your
corner, and stumbling in a codebase with a serious history and a task to do on
it efficiently.

It's not going quickly nor easily, and there is no real help from Jetbrains
IDE.

~~~
toolslive
it should at least offer things like "show-type-of-expression-at-current-
cursor-position"

~~~
nraynaud
It doesn't, it colors some keywords, it tries to follow symbols, but doesn't
know the difference between 'let rec' and 'let', so it's tricky.

~~~
Drup
Maybe JetBrain doesn't, but lot's of editor do, thanks to merlin, including
vscode.

~~~
nraynaud
Thanks, I'll download it, but it's really disruptive to switch IDE. (I do a
lot of langages at the same time hence the jetbrains suscription)

edit: it's a nightmare of dependency hell to install merlin, I'm giving up for
now.

~~~
AlexCoventry
What package manager? `opam install merlin` should just work.

OCaml has a relatively immature ecosystem, but merlin is a great tool.

~~~
nraynaud
It doesn't just work for me, no detailed error message I'm 3 or 4 levels down
(vscode->plugin->homebrew->opam->jbuilder-> doesn't work).

[https://gist.github.com/nraynaud/deeacbb67c88646fd6754edba6e...](https://gist.github.com/nraynaud/deeacbb67c88646fd6754edba6e2196d)

Sorry, I'm a bit abrasive, but I spend a lot of time with crappy tooling of
all kind, sometimes I'm envious of monoproject people (and then I remember
that actually I don't do well in monotony).

~~~
djs55
I think `opam` failed to find `jbuilder` on the `$PATH`, even though
(presumably) `opam` has built it and installed it in it's own `bin/`
directory. Try running `eval $(opam config env)` to update the `$PATH` and
trying the commands again.

------
cmwelsh
OCaml and Reason are beautiful languages. I actually applied to Jane Street
hoping for a chance to use them more, but they weren’t interested in my
resume. Is there a list of OCaml/Haskell/etc companies out there for us
functional programming enthusiasts?

~~~
pbiggar
Dark is written in OCaml (and Elm, which is a similar functional language) and
we're hiring: [https://darklang.com/careers/](https://darklang.com/careers/)

~~~
3rdAccount
Wait...hiring to sell a Lang? I'm curious.

~~~
pbiggar
The business model is fairly easy though: sell infra. It's a lot to build, so
we need a good team. We're currently 5, hiring 3 more engineers atm.

------
stochastic_monk
As an aside, as someone who primarily uses imperative languages, I’ve found
the proliferation of support for functional paradigms in Python and C++ (Fold
expressions, reduce, transform, map, etc) has changed how I write code
immensely.

I’m likely to try this out.

~~~
agumonkey
your opinion is super valuable, do you think they make your code shorter,
cleaner, more modular, safer ? what do you miss from imperative programming ?
or do you consider you would have changed the way you code if you knew about
fp idioms long before ?

~~~
stochastic_monk
1: Cleaner and more concise. Perhaps safer, as the less code there is going to
performing a task, the fewer places I can make a mistake. More importantly, it
directs me to think about my problem from a higher level of abstraction.

2: I do mix both paradigms, so I’m not stuck without imperative features. That
being said, there are times where I feel like my attempts to move a concept
into FP forces me to make some less than ideal choices to fit it into the
paradigm. If those are in inner loops, I forgo functional programming to do
precisely what I need. (For example, managing exceptional cases or
heterogeneous actions can be awkward.)

3: I would have used them more. I’ve always been a fan of comprehensions and
map c/o Python, but my code would have been more efficient and concise had I
started earlier. The additions of cppitertools, range-v3, <algorithm> and
<functional> make functional programming both easy and efficient in C++ in
ways it was not prior to C++1[147]. I think Python made fp accessible by
putting it in an imperative language which is concise and readable.

~~~
agumonkey
about 2, I remember some old lisp book (Queinnec L.I.S.P) said that if mutable
state is entirely contained and invisible, you can forget about purity.

It's cool that cpp is 'flattening' through fp idioms, you can avoid its
complexity without leaving the country entirely.

~~~
kazinator
E.g. a pure function can work internally by mutating some local variables.
Locally constructed new objects such as conses can be mutated before being
returned to the caller. Blackbox testing cannot tell.

------
amelius
Is it possible to enforce purity for parts of an OCaml program? Or is there
always a way around? (Not saying this is bad, because for instance caching
functionality is non-pure but still maintains the external quality of purity).

~~~
bjz_
There is work being done to bring an algebraic effects system to OCaml, but
it's slow going. I think because the people pushing it have a bunch of other
things on their plates too. But it would be super nice to have!

------
agumonkey
Best part of this is the very pragmatic set of problems. I loved the meijer
haskell mooc too, a lot, but it's more about mind bending rather than more day
to day programs.

------
dang
Previously:
[https://news.ycombinator.com/item?id=12423352](https://news.ycombinator.com/item?id=12423352)

------
thangngoc89
OCaml is a very powerful language. I'm still discovering new features/patterns
everyday. But coming from a background with C/Javascript, the syntax is
definitely hard to understand. For this particular problem, I think ReasonML
has done a very good job of introducing OCaml platform to a wider audience.

Shamelessly plug: I'm working sketch.sh [1] as a learning project for
ReasonML. It's a interactive playground (like IPython/Jupyter) for OCaml and
ReasonML. It's provide inline types and evaluated values. Give it a try if
you're learning OCaml/ReasonML.

[1]: [https://sketch.sh](https://sketch.sh)

~~~
erokar
I don't get it. I work day to day with Algol-syntax languages like JavaScript
and Java, but have dabbled in ML languages like Elm and Haskell. One of the
things I really like about those languages is the syntax -- succinct and
clear. What takes time and is hard for me is grasping the semantics and
patterns.

~~~
masklinn
OCaml's syntax is way more verbose and noisy than Haskell's or Elm's. It tends
to have longer keywords, more sigils, … and some of the defaults are
inconvenient (non-recursive lets)

[https://wiki.haskell.org/OCaml](https://wiki.haskell.org/OCaml) has some
trivial examples

------
loxs
"This course will be held in English."

No offence intended, but English, my ass!

Although quite proficient, English is still a second language to me and this
accent makes it quite unintelligible. I hope everything will be available in
written form as well.

