Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

let rec for values and let rec for functions in ocaml

Tags:

ocaml

What is the best intuition for why the first definition would be refused, while the second one would be accepted ?

let rec a = b (* This kind of expression is not allowed as right-hand side of `let rec' *)
and b x = a x

let rec a x = b x (* oki doki *)
and b x = a x

Is it linked to the 2 reduction approaches : one rule for every function substitution (and a Rec delimiter) VS one rule per function definition (and lambda lifting) ?

like image 927
nicolas Avatar asked Nov 16 '18 10:11

nicolas


People also ask

What is let REC in OCaml?

OCaml uses let to define a new function, or let rec to define a function that is recursive.

How does let work in OCaml?

The value of a let definition is the value of it's body (i.e. expr2). You can therefore use a let anywhere OCaml is expecting an expression. This is because a let definition is like a syntactially fancy operator that takes three operands (name, expr1 and expr2) and has a lower precedence than the arithmetic operators.

What is REC function?

Recursive functions - functions that call themselves - are identified explicitly in the F# language with the rec keyword. The rec keyword makes the name of the let binding available in its body. The following example shows a recursive function that computes the nth Fibonacci number using the mathematical definition.


1 Answers

Verifying that recursive definitions are valid is a very hard thing to do.

Basically, you want to avoid patterns in this kind of form:

let rec x = x

In the case where every left-hand side of the definitions are function declarations, you know it is going to be fine. At worst, you are creating an infinite loop, but at least you are creating a value. But the x = x case does not produce anything and has no semantic altogether.

Now, in your specific case, you are indeed creating functions (that loop indefinitely), but checking that you are is actually harder. To avoid writing a code that would attempt exhaustive checking, the OCaml developers decided to go with a much easier algorithm.

You can have an outlook of the rules here. Here is an excerpt (emphasis mine):

It will be accepted if each one of expr1exprn is statically constructive with respect to name1namen, is not immediately linked to any of name1namen, and is not an array constructor whose arguments have abstract type.

As you can see, direct recursive variable binding is not permitted.

This is not a final rule though, as there are improvements to that part of the compiler pending release. I haven't tested if your example passes with it, but some day your code might be accepted.

like image 199
PatJ Avatar answered Oct 07 '22 23:10

PatJ