First attempt to compile source using Zarith

Please excuse my poor English and my very naive question.

I’m trying to use Zarith for calculation with big numbers.

I wrote this very little code :

open  Zarith

let rec puissance a b = Z.pow (Z.of_int a) b

in a file test.ml.

I call the compiler like this :

ocamlopt -I `ocamlfind query zarith` zarith.cmxa test.ml -o test

(I just copied the ocamlopt -I ‘ocamlfind query graphics‘ graphics.cmxa cardioid.ml -o cardioid command from book Learning Programming with OCaml.)

But I have this error

File "test.ml", line 1, characters 6-12:
1 | open  Zarith
          ^^^^^^
Error: Unbound module "Zarith"

In interactive mode (using ocaml in a terminal) the #require "zarith";; works well.

I guess it’s a beginner’s mistake and I appeal to your indulgence.

I don’t think there is any “wrapper” module Zarith in the zarith library, ie Z is already a top-level module. If you remove open Zarith then your code should build

No need to do so!

Cheers,
Nicolas

2 Likes

How I know if I should or not insert a open Module ?
Where is documented the difference between Graphics and Zarith of this issue ?

Can you recommend some useful reading for compiling programs using modules?

It depends on each library: some libraries are organized with a “wrapping” module named the same way as the library which contains every other item of the library (including any modules that the library may export). This is more typically used nowadays. But as far as OCaml is concerned a library is just a “bag of modules”, and so certain libraries (like zarith) simply consist of a few toplevel modules and there is no wrapper module called Zarith.

The only way to know is look at the documentation of each library or, absent that, look directly in the source (one can also guess it by looking at the .cmi artifacts on the file system or by using Merlin/LSP in your editor).

Unfortunately, nothing current comes to mind. Nowadays most people use a build system (eg Dune) to build their OCaml code, which largely insulates you from having to understand how things work in detail…

The classic French book “Le Langage Caml” https://caml.inria.fr/distrib/books/llc.pdf has a discussion of separate compilation in Chapter 10, but keep in mind that this book was written for Caml Light, so many details need to be adapted to apply to OCaml (however, the substance of the matter remains the same).

Cheers,
Nicolas

2 Likes

I’d suggest you write

ocamlfind ocamlopt -package zarith -linkpkg test.ml -o test

it’s more idiomatic and it can handle more complex dependencies than the ocamlfind query zarith trick you used. And if you need to use the graphics library as well, replace zarith by zarith,graphics.

In the fine documentation at OCaml Packages · Browse Community Packages . After a bit of navigation, you’ll find zarith 1.14 (latest) · OCaml Package, which shows:

zarith 1.14

Libraries

This package provides the following libraries (via ocamlobjinfo):

zarith

Documentation:

  • Zarith_version
  • Z Integers.
  • Q Rationals.
  • Big_int_Z Big_int interface for Z module.

So, there’s an OPAM package called “zarith”, at version 1.14. It contains a library called “zarith” as well. This library name is what you give to ocamlfind -package. This library provides top-level modules called Z, Q, Zarith_version, and Big_int_Z. To use a function from the Z module, say the pow function, you can write either Z.pow or do open Z and then just write pow.

Now, compare with https://ocaml.org/p/graphics/latest/doc/index.html:

graphics 5.1.2

Libraries

This package provides the following libraries (via ocamlobjinfo):

graphics

Documentation:

  • Graphics Machine-independent graphics primitives.
  • GraphicsX11 Additional graphics primitives for the X Windows system.

Here, the library is “graphics”, provides two top-level modules Graphics and GraphicsX11. To use the open_graph function from module Graphics, you write either Graphics.open_graph or do open Graphics and then just write open_graph.

So, it all boils down to using either fully-qualified names like Z.pow or use short names like open_graph after “opening” the module.

I’m sure you get it now. More puissance to you.

6 Likes