11

Is there a way to declare a function before defining it in OCaml? I'm using an OCaml interpreter.

I have two functions:

let myFunctionA = 
(* some stuff here..... *) myFunctionB (*some stuff *)

let myFunctionB = 
(* some stuff here .... *) myFunctionA (* some stuff *)

This doesn't work though, since myFunctionA can't call myFunctionB before it's made.

I've done a few google searches but can't seem to find anything. How can I accomplish this?

nlucaroni
  • 47,556
  • 6
  • 64
  • 86
Casey Patton
  • 4,021
  • 9
  • 41
  • 54
  • Relevant keywords: "ocaml corecursive function". See [Notes on OCaml: Mutually Recursive Functions](http://www.csc.villanova.edu/~dmatusze/resources/ocaml/ocaml.html#Mutually%20recursive%20functions). –  Sep 30 '11 at 17:06
  • 1
    I cannot say I've ever heard co-recursion to imply mutual recursion --although, it is pretty obvious what would be meant. – nlucaroni Sep 30 '11 at 19:53

2 Answers2

24

What you want is to make these two functions mutually recursive. Instead of using "let ... let ...", you have to use "let rec ... and ..." as follows:

let rec myFunctionA = 
(* some stuff here..... *) myFunctionB (*some stuff *)

and myFunctionB = 
(* some stuff here .... *) myFunctionA (* some stuff *)
Martin Jambon
  • 4,629
  • 2
  • 22
  • 28
2

Actually "let rec .." has a very serious limitation: it only works within a single module. This forces the programmer to write big modules where it is not desired .. a problem which does not occur in lowly C!

There are several workarounds, all unsatisfactory. The first is to make a variable of the function type and initially store a function raising an exception in it, then later store the desired value.

The second is to use class types and classes (and one indirection). If you have a lot of mutually recursive functions this is the best way (because you only need to pass a single object to each of them).

The easiest and most ugly is to pass the functions to each other as arguments, a solution which rapidly gets out of control. In a module following all the definitions you can simplify the calling code by introducing a set of "let rec" wrappers. Unfortunately, this does not help defining the functions, and it is common that most of the calls will occur in such definitions.

Yttrill
  • 4,725
  • 1
  • 20
  • 29
  • Note that this is now somewhat eased by recursive modules, for example like so: http://stackoverflow.com/a/33482273/2482998. It's still pretty awkward, however. – antron Nov 06 '15 at 17:41