I draw some conclusions here from two developments of division algebras, in Scheme and in Ocaml. Ocaml indeed supports the pattern of my Scheme program in a first class manner.

Ocaml certainly fusses with types. Perhaps the program could be written with less text that describes types. With a modicum of Ocaml learning, however, you may understand the logic of the Ocaml code quicker than the Scheme code as the Ocaml code explains itself by manifesting the shapes of the values whereas they are only latent properties of the Scheme code. The module type DivAlgebra has no analog in the Scheme code, except in the heads of the programmer and program reader. It seems clear that a compiler can produce better machine code from the Ocaml version.

Ocaml is a typed language in the obvious sense that the types of this program are made explicit. The function G appears in both programs and maps from collections of functions to collections of functions. In Scheme G is an ordinary dynamic runtime function. In Ocaml G is a compile time functor components of an algebra are grouped in a module. Ocaml modules cannot include functors. In this sense Scheme is more general. This is not a criticism—just now I have no need of functors in modules—and this is critical to Ocaml’s ability to grok the program so as to produce better code.

Neither Scheme nor Ocaml make mathematical expressions easy to read. I spent two days tracking down an obscure and trivial error in the transcription—in essence learning to debug Ocaml.

I think that ocaml requires understanding type theory at a deeper level than Scheme. This is good for some projects and bad for others. My current opinion is that Scheme is a good first language and introduction to caml.

Records instead of Modules

Ocaml records package several values of miscellaneous types into one value, just as a module does. Functors are available to define modules in terms of other modules, but not in terms of other dynamically computed things. I see no language features to define new record types in terms of old record types; indeed each record type requires an explicit type definition. Ocaml module definitions can be concise as in module Quaternion = G(G(Reals));;. These are static compile-time expressions. There are no such constructs, even static constructs for records.

A language designer can always ‘go meta’ one more time starting from any language and uses of such generalizations can always be found. I wrote my Scheme code for division algebras (and Clifford algebras) before I learned Ocaml. It seems Ocaml is exactly as ‘meta’ as I need in this particular dimension.

match

The division algebra example did not use ocaml’s match feature; it didn’t need it. But this transcription from ocaml to Scheme suffers a great deal from the lack of a match construct. There are many cars, cdrs and caddrs, etc. which clutter the Scheme code for lack of ocaml’s ability to test the shape of a value and name its parts in one transparent construct. This is thick syntactic sugar but worth it, I think.