Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Limitations of let rec in OCaml

I'm studying OCaml these days and came across this:

OCaml has limits on what it can put on the righthand side of a let rec. Like this one

let memo_rec f_norec =
let rec f = memoize (fun x -> f_norec f x) in
f;; 
Error: This kind of expression is not allowed as right-hand side of `let rec'

in which, the memoize is a function that take a function and turns it into a memorized version with Hashtable. It's apparent that OCaml has some restriction on the use of constructs at the right-hand side of 'let rec', but I don't really get it, could anyone explain a bit more on this?

like image 629
David Lau Avatar asked Nov 08 '13 13:11

David Lau


2 Answers

The kind of expressions that are allowed to be bound by let rec are described in section 8.1 of the manual. Specifically, function applications involving the let rec defined names are not allowed.

A rough summary (taken from that very link):

Informally, the class of accepted definitions consists of those definitions where the defined names occur only inside function bodies or as argument to a data constructor.

like image 119
gsg Avatar answered Sep 30 '22 17:09

gsg


You can use tying-the-knot techniques to define memoizing fixpoints. See for example those two equivalent definitions:

let fix_memo f =
  let rec g = {contents = fixpoint}
  and fixpoint x = f !g x in
  g := memoize !g;
  !g

let fix_memo f =
  let g = ref (fun _ -> assert false) in
  g := memoize (fun x -> f !g x);
  !g

Or using lazy as reminded by Alain:

let fix_memo f =
  let rec fix = lazy (memoize (fun x -> f (Lazy.force fix) x)) in
  Lazy.force fix
like image 27
gasche Avatar answered Sep 30 '22 17:09

gasche