
Functional Programming in OCaml - gstipi
https://www.cs.cornell.edu/courses/cs3110/2020sp/textbook/
======
melling
ReasonML is Facebook’s OCaml for JavaScript.

[https://reasonml.github.io/](https://reasonml.github.io/)

They have used it extensively:

[https://reasonml.github.io/blog/2017/09/08/messenger-50-reas...](https://reasonml.github.io/blog/2017/09/08/messenger-50-reason.html)

With impressive results:

“ Messenger used to receive bugs reports on a daily basis; since the
introduction of Reason, there have been a total of 10 bugs (that's during the
whole year, not per week)! *”

~~~
emmanueloga_
If I get it right (from posts I've seen before and the docs on the project
[1]) Reason is not really "OCaml for JavaScript" but just a parser for a more
appealing, mostly compatible, syntax for the OCaml. So one should be able to
compile to the same targets as with traditional OCaml.

Re: Mostly compatible: I remember there were certain things that were not
easily expressible with Reason (but available in the OCaml syntax) a few years
ago, not sure if it is still the case.

Subjective: OCaml syntax is definitely on the weird side, although I would not
call it ugly. This coming from someone who enjoys writing clojure and xslt, go
figure :-p.

1:
[https://github.com/facebook/reason/blob/master/src/README.md...](https://github.com/facebook/reason/blob/master/src/README.md#repo-
walkthrough)

~~~
adamcanady
Js_of_ocaml [1] is a good alternative to BuckleScript for standard OCaml (non-
Reason).

For example, it works well with Core_kernel [2] and Async_kernel [3] to
provide high-level functionality that is cross compatible between Unix
applications and browser applications.

[1]
[https://github.com/ocsigen/js_of_ocaml](https://github.com/ocsigen/js_of_ocaml)

[2]
[https://github.com/janestreet/core_kernel](https://github.com/janestreet/core_kernel)

[3]
[https://github.com/janestreet/async_kernel](https://github.com/janestreet/async_kernel)

~~~
abathologist
To be clear, Bucklescript also works with standard OCaml (because Reason is
just an alternative surface syntax).

------
a-nikolaev
Very nice practical and modern textbook for OCaml. I were using it last year
to teach this subject at my school. Here are my additional notes and
exercises, if you are interested:
[https://a-nikolaev.github.io/fp/](https://a-nikolaev.github.io/fp/)

------
thelazydogsback
I don't know why they felt they had to mess with OCaml's syntax - one of the
nicest around AFAIC. With F#, even MS didn't feel like they had to add extra
braces and other baggage and change keywords ("match" to "switch ()", etc.) to
make C# programmers have an easier first ten minutes of transition time.

~~~
jolux
I think F# cleaned up a lot of OCaml’s syntactic oddities nicely, though I
could do without the off-side rule.

~~~
pjmlp
F# supports OCaml syntax as well, via a compiler pragma.

~~~
nikofeyn
f# has diverged away from ocaml enough that the small fact that a tiny subset
of it is compatible with ocaml is just a trivia fact.

------
kernoble
An great course and a very good professor. I'm glad they've compiled the
course into an ebook. It's the only way I can think of FP, so I'm glad I can
know point people to the same source I learned it from.

It would be quite awesome if they made it fully interactive; in the vein of
several other textbooks that have been shared on HN recently.

~~~
danb232
which textbooks are interactive like that?

~~~
afiori
Two that I know are SICP[0] and Eloquent Javascript[1]

[0] [https://sicp.comp.nus.edu.sg/](https://sicp.comp.nus.edu.sg/) [1]
[https://eloquentjavascript.net/](https://eloquentjavascript.net/)

------
nikivi
HN thread on 2019 edition:
[https://news.ycombinator.com/item?id=19292067](https://news.ycombinator.com/item?id=19292067)

------
willtim
> Java didn't have generics until version 5 in 2004; the ML family had it in
> 1990.

I thought Standard ML had it in the 70's (!)

~~~
noelwelsh
Yes, 1975 IIRC. Standard ML was published in 1990, so that is probably the
source of the confusion.

It's a bit sad that the foundations of modern programming languages were
basically known by 1975 (either via Standard ML or Scheme) but the majority of
languages in common use (mostly of a 1990s vintage) didn't learn those
lessons. Thankfully that seems to be changing with more recent languages (Go
being the exception).

~~~
pjmlp
And CLU.

Having researched a bit in the 60's and 70's systems programming languages, I
would assert that the same issues with Go apply to C (language design vs
existing competition), and they only got lucky because Bell Labs was forbidden
to profit from UNIX.

------
wing328hk
If you want to access RESTful APIs via OCaml, you may consider using OpenAPI
Generator to generate the OCaml client automatically instead of manually
creating one. Here are 3 simple steps to do so:

1\. Download the OpenAPI Generator CLI Java JAR
([https://repo1.maven.org/maven2/org/openapitools/openapi-
gene...](https://repo1.maven.org/maven2/org/openapitools/openapi-generator-
cli/4.2.3/openapi-generator-cli-4.2.3.jar))

2\. Rename the JAR as "openapi-generator-cli.jar"

3\. Run the following command to generate an OCaml API client for the Petstore
API ([https://raw.githubusercontent.com/OpenAPITools/openapi-
gener...](https://raw.githubusercontent.com/OpenAPITools/openapi-
generator/master/modules/openapi-
generator/src/test/resources/2_0/petstore.yaml)):

Mac/Linux:

$ java -jar openapi-generator-cli.jar generate -g ocaml -i
[https://raw.githubusercontent.com/OpenAPITools/openapi-
gener...](https://raw.githubusercontent.com/OpenAPITools/openapi-
generator/master/modules/openapi-
generator/src/test/resources/2_0/petstore.yaml) -o /var/tmp/ocaml/

Windows:

$ java -jar openapi-generator-cli.jar generate -g ocaml -i
[https://raw.githubusercontent.com/OpenAPITools/openapi-
gener...](https://raw.githubusercontent.com/OpenAPITools/openapi-
generator/master/modules/openapi-
generator/src/test/resources/2_0/petstore.yaml) -o C:\tmp\ocaml

If you've any feedback or question, please let us know via
[https://github.com/OpenAPITools/openapi-
generator/issues/new](https://github.com/OpenAPITools/openapi-
generator/issues/new)

------
amatecha
As I don't have a lot of time to investigate at this moment - is this intended
to be a generally-standalone guide that one could use to learn OCaml? I'm
guessing not, since it doesn't seem to dive in too deep into any subject, just
giving a very broad overview.

~~~
jdeisenberg
If you want something more in-depth about OCaml itself,
[http://dev.realworldocaml.org/](http://dev.realworldocaml.org/) is a good
resource.

~~~
pjmlp
Any news on how the 2nd edition is going on?

~~~
acjohnson55
It's totally usable and preferable in its beta format to the first edition.
The first edition is pretty out of date with current practice.

~~~
pjmlp
Thanks!

------
devmunchies
I haven't used OCaml in a couple of years. has the stdlib story been
improved/standardized? is there still the whole async vs jwt problem or did
jwt finally win out?

I think i remember that there wasn't a good web framework, and that the
existing popular one had a memory leak.

I was learning from a book (Real World OCaml, i think) and it kept pushing
jane street libs like Async and Core.

~~~
abhijat
Do you mean LWT?

~~~
devmunchies
Ah. Yes.

------
crimsonalucard
How does OCaml compare with haskell?

~~~
wyager
Ocaml does not make any effort to control impure code or mutability. The type
system is not as powerful, but the powerful module system takes up some of the
slack. Lots of things that are really convenient in Haskell (like point-free
function composition) work poorly or not at all in OCaml due to constraints
imposed by the existence of impure mutable references. The OCaml runtime is
pretty primitive compared to Haskell’s, especially around stuff like
concurrency. GHC has a world-class concurrency story and OCaml barely has
support for multiple OS-level threads. OCaml uses tagged pointers for boxing,
which means you have weird stuff like integers being 63 bits instead of 64.
Haskell uses bitmasks on heap objects to avoid that.

Subjectively, I think OCaml is a huge improvement over, say, Java, but if
you’re deciding between learning one of OCaml or Haskell in 2020 I think
Haskell is the better option for most people.

~~~
smabie
I don't consider OCaml and Haskell to be really comparable. I love statically
typed FP and have professional experience with OCaml, Haskell, and Scala and
Haskell is significantly different than the other two (also much different
than F#). I've personally never found Haskell's encoding of mutability or
impurity into the type system to be of any real benefit. Most of the time your
impurity is coming from logging, networking, or interacting with files or a
db; in which case, it's entirely obvious what's going on. Other times, you
have a pure function that's implementation is unpure, which is also obvious on
what's going on. In any case, if you're programming in good FP-style all
Haskell is providing is a bunch of headaches around finding the write way to
make all your type annotations match up: it's kind of a annoying experience
when you're just trying to get something done.

I think Haskell's a good way to start learning functional programming because
it really beats the habit of loops and mutability out of you _real_ fast by
making the functional way easier. But if you're already an experienced FP
programmer, less restrictive languages are better.

What makes Haskell interesting is all the crazy optimizations it can do since
the compiler has so much information about the program. It would be really
cool if other languages had a "pure" annotation or keyword that signified the
function has a pure interface. This could dramatically improve the performance
of a lot of Scala/F#/OCaml code.

~~~
wyager
I’ve put thousands of hours into both Haskell and Ocaml, so I feel like I have
a pretty good understanding of how both affect my development process.

> I've personally never found Haskell's encoding of mutability or impurity
> into the type system to be of any real benefit.

I find it completely indispensable for large codebases, especially codebases I
didn’t write.

> Most of the time your impurity is coming from logging, networking, or
> interacting with files or a db; in which case, it's entirely obvious what's
> going on.

Maybe you’re a genius or something, but to me (and most people) it’s not
“entirely obvious what’s going on” when large codebases use impure side-
effectful semantics in a way that’s not clear from the types.

> Other times, you have a pure function that's implementation is unpure, which
> is also obvious on what's going on.

Once again, it is not at all obvious. And a very large fraction of the time,
that “pure function with an impure implementation” isn’t actually so pure
after all, and either leaks mutable semantics or behaves badly (e.g. if used
in a multithreaded way). Haskell actually does have a real solution for this
in the form of the ST monad. You can write impure things and _prove_ (using
the type system) that they have pure semantics. I’m not aware of any other
language offering this.

> In any case, if you're programming in good FP-style all Haskell is providing
> is a bunch of headaches around finding the write way to make all your type
> annotations match up

Not only are type annotations optional (and usually trivial), but you can get
the compiler to write them for you interactively e.g. with holes. In any case,
this is never a problem in practice for “business logic” code. I’ve only
really seen this come up e.g. when writing lenses by hand (i.e. rarely).

> it's kind of a annoying experience when you're just trying to get something
> done.

The point where the cognitive overhead introduced by Haskell’s type system is
worth the payoff compared to, say, Python, is about 1-200 lines in my
experience.

> But if you're already an experienced FP programmer, less restrictive
> languages are better.

The only “improvement” that you’ve cited so far is that “less restrictive
languages” let the programmer be architecturally lazy, which I don’t think is
really an improvement.

> It would be really cool if other languages had a "pure" annotation or
> keyword that signified the function has a pure interface.

If this were preferable, then Haskell programmers could just write everything
in IO and selectively factor things out into pure functions. The fact that no
one does this is, I think, telling.

