Go to file
2021-12-18 20:45:09 +11:00
lib separate numerical operations into int and float folders, changing names of exposed functions from stdlib 2021-12-18 20:20:30 +11:00
README.md int and float info on readme 2021-12-18 20:45:09 +11:00

OCaml Standard Library

This repository contains my custom OCaml standard library and build system.

Disclaimer:

This is very bespoke for my requirements, and only something I do/use when I am writing code to be read and used by myself. In general, I do not recommend doing something like this, but this repository is here to show off how one can effectively compile an OCaml project without the standard library but still expose the few functions they may need, and in case my implementations of data structures and algorithms may be useful to people learning functional programming.

Modules

This library includes the following custom modules:

  • Int (exposure of basic integer arithmetic functions)
  • Float (exposure of basic float arithmetic functions)
  • List (functional list data structure)
  • Queue (functional queue implemented as two lists)
  • Set (functional set implemented as a red-black tree)
  • Stack (functional stack data structure)
  • Tree (functional generic tree type with some general functions to manipulate it)
  • Map (functional map implemented as a red-black tree)

Exposure of Functions from Standard Library

With respect to the exposed parts of the standard library, these are all handled in the FromStdlib module, which redefines some definitions directly from the standard library so that this file can be safely included separately, exposing only the desired functions. As such, it is recommended that this file is opened in the code that uses this library, while others are not, and referenced from the module level instead (with one additional exception of Types, mentioned in the following section).

All files are compiled with -nopervasives except FromStdlib (to avoid the headaches in exposing functions like printf which have many dependencies). Linking is also done without -nopervasives so that fromStdlib.cmx can find the corresponding functions. Hence any new files added to the project are recommended to be compiled separately with nopervasives and then linked via the .cmx file.

Type Declarations

In order to prevent duplicate definitions of common types like collections, but still allow things like list literals to work, and to prevent the need of a type annotation at the module level, a Types module is provided to be opened in code files which exposes types like 'a queue and other collections.

Build Process

Since I wanted to compile with some aspects of the Standard library (or import the source files separately), the build process is a little complicated. A makefile is included with the following commands set up:

  • make build to build all files, including main.
  • make clean which removes all auto-generated files, leaving only source code behind.
  • make mostlyclean which remaves all auto-generated files except the main executable, also leaving source code behind.
  • make run which runs the executable created by make build.
  • make install which runs the equivalent of make build, make mostlyclean and make run in sequence.

Note that incremental builds are not set up, and that some .mli files are autogenerated but most are not, and therefore if attempting to edit the standard library code for your own purposes, I recommend running make clean first, so you don't attempt to add code to .mli files that will be autogenerated and overwritten.

Also take note of the fact that I typically compile everything with -S and -O3 for assembly code files and flambda optimization correspondingly, and this can obviously be changed depending on requirements, as can the use of ocamlopt instead of ocamlc but if that is changed the final linking will need to be done with .cmo instead of .cmx files.

The Core Library

One of the unfortunate consequences of the way OCaml's compilation works, is that there is a library called the core library, documented here, which contains some definitions for types and exceptions, yet does not include the code from the stdlib that uses them. When compiling with the -nopervasives flag, this is still included but without the standard library. While this makes sense from the perspective of having some fundamental exceptions always available, having types like list included makes it very annoying when implemented a custom standard library. This quirk is why my library has no type definition for list, bool, option, etc. but still uses these types.