0

I have code:

let join a ~with':b ~by:key = 
  let rec a' = link a ~to':b' ~by:key
      and b' = link b ~to':a' ~by:(Key.opposite key) in
  a'

and compilation result for it is:

Error: This kind of expression is not allowed as right-hand side of `let rec' build complete

I can rewrite it to:

let join a ~with':b ~by:key = 
  let rec a'() = link a ~to':(b'()) ~by:key
      and b'() = link b ~to':(a'()) ~by:(Key.opposite key) in
  a'()

It is compilable variant, but implemented function is infinitely recursive and it is not what I need.

My questions: Why is first implementation invalid? How to call two functions and use their results as arguments for each other?

My compiler version = 4.01.0

Valentyn Zakharenko
  • 2,710
  • 1
  • 21
  • 47
  • 1
    This is similar to a dining philosopher's problem or a deadlock issue I can't imagine there being a solution too. I don't know anything about ocaml, just wanted to point out what kind of problem this is similar to. – Luminous Oct 24 '14 at 20:22

1 Answers1

1

The answer to your first question is given in Section 7.3 of the OCaml manual. Here's what it says:

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.

Your names appear as function arguments, which isn't supported.

I suspect the reason is that you can't assign a semantics otherwise. It seems to me the infinite computation that you see is impossible to avoid in general.

Jeffrey Scofield
  • 65,646
  • 2
  • 72
  • 108
  • I think it is answer to my second question too. Direct: Call two functions and use their results as arguments for each other is impossible because 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 (not functions). – Valentyn Zakharenko Oct 24 '14 at 23:17
  • I think these questions are closed. – Valentyn Zakharenko Oct 25 '14 at 00:46