A picture is worth a thousand words, so before I continue, here are a few examples of it in action:
Overall, getting LablGtk to work was fairly straightforward, although the documentation was a bit lacking (although the same might be said of Gtk itself).
I was able to piece together the correct uses of most of the API calls by relying on either the examples from the repository or by translating snippets of code from online back into LablGtk.
As for deploying it as an application, I found the AppImage & LinuxDeploy toolchain to work well with the resulting binary (admittedly I’ve only tested it with two devices so far), and it meant that I could publish the program without having to ask people to setup the full OCaml & Opam toolchain, which would probably be a large ask.
As for the implementation, I think it was fairly elegant (if I say so myself ), although I may have gone overboard with functors (see this higher-order functor in the GUI interface: gui.mli · master · Kiran Gopinathan / libre-ref · GitLab) and some aspects of the separation of concerns weren’t so well established.
Ah, sorry, my bad, I should have clarified the terminology. By digital referencing, I’m referring to the process of gathering and viewing a collection of reference images (i.e for inspiration/reference when making artwork).
Somewhat - Zotero/Bibtex does similar things, but one of the key features is being able to search and retrieve individual papers from your entire database of references at a later point.
In contrast, when collating image references, you’re not building a single database of all the images you’ve seen, just a small collection of visually interesting pictures that can serve as inspiration - for that to work, you need to be able to see all the images at the same time/zoom in to particular images as they catch your eye - you produce a collage of images as your digital reference.
For example, in 3D modelling, before starting to build their model, an artist may collate a collection of real-world images of the object they are trying to model, to serve as inspiration or act as a guide during the modelling process.
Thanks for the advice - yes, that would probably be a good idea - I had planned some kind of nicer landing page for the application, but haven’t yet had the time to get round to writing the web page - hopefully I should be able to get round to it soon.
I’m not sure if I can give that unbiased of an opinion on choosing OCaml - OCaml is pretty much my main programming language at this point, so there was little chance I was going to write it another language.
If anything, the main insight I gained from this was completing my transformation from a Haskell programmer to an OCaml one by finally fully embracing mutability.
When starting out this project, during the exploratory phase while I was figuring out the GTK and Cairo API, I used a few global references to allow quickly iterating on various designs and determining exactly what kind of state I would need to maintain.
Once I had converged on a single design, I then started gradually refactoring the core parts of my implementation into a pure functional form, using the type system to avoid breaking the code.
Having originally come to OCaml from Haskell, I’ve only recently started embracing the mutable parts of OCaml, but now I’m regretting not considering it earlier - making careful use of mutability can make certain parts of the programming process go through a lot faster. In some ways, one of the greatest benefits of a type-system is the ease of refactoring, so not making use of impure constructs on principle when it would be helpful is just throwing away one of the benefits of the language.
That’s a great insight. I find that particularly in applications that maintain state over time (and therefore need to mutate it rather than recreate it), impurity is important if not essential for performance. It’s a bit of a struggle to decide which part of the state stays immutable and is recreated functionally and which part is mutated. Also there are some algorithms that are just much simpler when expressed with mutability.