(Part of the Throwing Pots series.)
Source code for this project can be found here.
A very tiny project to get started. There are some very interesting small and useful websites out there which start small, but become very useful. One of these it Wheel of Names. It’s grown a bit, but at its core it is:
- User puts in a list of options.
- Web site selects one at random.
- There are graphics and sound effects.
It’s a nice, simple, project to try and reproduce. No clever logic, so can focus on the code.
Preparation
I decided to write this in OCaml, for a few different reasons:
- It’s little known, but has a long heritage from 1996 (and roots in ML language from earlier.)
- It’s recently gained a bit of coverage recently from multiple coders who are praising it as a simple, productive, secure, fun language.
- It’s functional, strongly typed, but has taken a different approach to Haskell.
- It’s been influential recently as the original implementation of Rust. When I’ve dipped into before there are multiple features that Rust has borrowed.
- It’s little known, but it is supported and developing. There’s a lot of recent buzz about the new release which more easily supports asynchronous workflows.
What Did I Do?
I managed most of what I set out to do, but no graphical magic.
- A small OCaml project which implements a data structure which allows random selection from a specified list of options.
- Sane project layout into libraries, tests, a command line executable and a web server.
- Very, very simple web UI to interact with the project.
The data structure I implemented was direct, fairly efficient using two lists. It’s essentially a zipper supporting add/peek/pop at the location, and a random shift in direction.
The web UI is a very bare bones html that I put on top, mainly to get to play with the Dream library. One thing that I did but didn’t like was that the ‘Next’ buttons in the UI are pure links, and hence route via GET – despite potentially modifying the internal data structure by removing a value. Next time round, with a proper UI I’d like to use the appropriate verbs here.
What Did I Think?
OCaml is a well designed language and ecosystem. The REPL (called utop) is one of the most complete I’ve seen, offering completion suggestions in a command line app. Dune (the build system) is similarly a very clean system, and opam the package integrates very nicely. It’s extremely easy to set up a project, with a specific Ocaml release, define dependencies and run. The build system, compared to Rust, is fast, I’m guessing because it’s not relying on LLVM. Although this wasn’t a good project to test performance I had no complaints in that area.
If I had to sum up the language in a word, it would be pragmatic. The type system is simple and easy to use. The shortcuts for locally including modules, adding record fields with the right names, and more – it all feels like a well travelled path which people have smoothed over time.
The acceptance of side effects will definitely be appreciated by many. The strict Haskell approach has its advantages but does incur a big shift in thinking before it feels natural. There are a few things that I miss about Haskell, type classes are one example. Type based polymorphism is a shame to lose – no esoteric abstract statements here. Similarly a lot of the higher order type system magic isn’t available, but there are advantages to avoiding magic. Arguably having a Monad as a pattern, rather than a core language feature makes it much more approachable.
OCaml has a concept of Functors
(transformations on modules) which is an alternative approach to extending types, and gives a lot of power. OCaml does push the module concept further than many other languages I’ve used. In OCaml the module isn’t just a code organization bucket, but a meaningful structure which can be used, transformed, and passed around. I do need some time to get my head around it properly.
Although an advanced topic, you can’t get far with libraries without bumping into preprocessors and specifically PPXs (Pre-Processor-eXtensions). They’re introduced by symbols @
or %
and transform the code during compilation. They’re more advanced than C macros in that they work on the AST not the raw text of the code. They’re more complicated than Lisp macros in that the AST form is not directly represented by the OCaml code. As a result they’re extremely powerful, easy to use – e.g. automatically derive pretty printers or json parsers with a simple PPX decoration – but complicated to write. Complicated enough that you probably wouldn’t write ad-hoc macros as you would in Lisp. It’s probably the best you can do with any language which is divorced from its AST, and Rust has a similar macro system. Some will argue that making macro type constructs harder to reach for is often a good thing.
A big plus for OCaml is the incorporation, in multiple ways, of javascript. There are multiple backends, aided by the OCaml bytecode approach. Melange is new and promising, and has a focus on readable javascript and integration with the normal OCaml build chain. A slight negative is some fragmentation around the ecosystem here. There’s Reason (an alternative syntax for OCaml). There’s BuckleScript, which becomes ReScript, which for multiple reasons provides it’s own parsing. I’m not too excited by projects which are ‘new syntax’1 so I’ve ignored Reason so far. Despite the fragmentation, the projects appear to be playing together nicely, so it’s not an existential worry. There’s a fairly new working group looking into WASM support, however it’s in very early stages. Rust remains the poster child for WASM integration in my opinion.
For an outsider coming to OCaml the eco-system comes across as small focussed. There are a small number of highly influential players. There’s Jane Street – influential enough that many of the de-facto libraries are owned and maintained by them. There’s Facebook – influential enough to build BuckleScript/ReScript, although I think it has some level of independence.
Finally, the documentation is bizarrely scarce. I don’t know if it’s because of users being already part of large communities (Facebook, Jane Street, INRIA). Perhaps it’s better to say that OCaml doesn’t feel evangelical. If I look on Safari – a huge library – there is not a single book on OCaml itself. There’s the odd chapter in generic programming books, and one book on ReasonML. Only the other hand there are multiple books on Rust, Haskell, Lisp, Elixir,… . There’s even one dedicated to Prolog. Going via the Ocaml website there are some books, but they do feel sparse compared with other niche languages – I don’t know why this is. I do hope it’s a situation that will change as more people start to discover and talk about the language. Interestingly, although maybe not surprisingly, there are multiple non-english texts which is nice to see.
Several of the books that do exist are very good however. I largely worked from OCaml Programming: Correct + Efficient + Beautiful – it’s a good text. It does show it’s background as a computer science course by having lots of exercises, and heavy emphasis on how the type system works. Generally it’s clearly written however, and introduces ideas in a logical order. Real World OCaml is also an excellent text, although a bit more advanced (and less academic). They are focussed on ‘language overview’ however, and take a similar direction starting with core types and language concepts at the REPL and taking a relatively even journey through the core language. The smaller literature set means that there aren’t texts which focus on specific areas – websites, scientific computing, practical projects, or just something different – that I can find for e.g. Common Lisp. The information is there, but you’ll have to dig it out yourself. I wanted to find information on setting up and deploying a project, but both of the books mentioned leave that information to later chapters. It’s something to be aware of, that if you want your own learning path, you’ll mostly need to assemble it yourself.
What Next?
A couple of specific things that I’d like to extend on:
- Use a different front end framework, maybe Svelte. For more complex web applications, this seems to be the way forward rather than relying completely on templating.
- Try compilation to JS via Melange. It would be useful to be able to keep any detailed logic in OCaml, and keep the JS side purely for presentation.
- Try websockets. This is a more general aim, but seems essential for user interactivity which involves the server.
- I’ve just been stung by ‘better syntax’ projects. Usually it means making things look more like C, for familiarity, rather than doing anything interesting with language concepts. Often they lose momentum. But I’ll repeat – I haven’t looked into Reason. It may have good motivation. โฉ๏ธ
One response to “A Chooser in OCAML (Pot 1)”
[…] Pot 1 – A random chooser. (OCaml, Text web front end.) […]