We already support mutual recursion in two ways:
-
Generative functions defined at the top level, with def, can be mutually recursive. (The programmer can use (declare ...) to write a forward declaration of one of them.)
-
Within a generative function, letfn can be used to define mutually recursive Clojure functions. Those functions can use the enclosing gen's tracer to make traced random choices:
(def example
(gen {:tracing-with t} []
(letfn [(f [i] (if (t i flip [0.5]) (g (inc i)) true))
(g [j] (if (t j flip [0.5]) (f (inc i)) false))]
(f 0)))
However, it is not currently possible to write a generative function that returns a set of mutually recursive generative functions. You can imagine this being useful for, e.g., writing a random PCFG generator: a generative function that makes random choices to construct a grammar, then returns a list of generative functions corresponding to the non-terminals in that PCFG. Maybe there are other examples, too. For this sort of thing, we'd need letgen.
A potential implementation technique is described here: https://stackoverflow.com/a/54587792/1931098
We already support mutual recursion in two ways:
Generative functions defined at the top level, with
def, can be mutually recursive. (The programmer can use(declare ...)to write a forward declaration of one of them.)Within a generative function,
letfncan be used to define mutually recursive Clojure functions. Those functions can use the enclosinggen's tracer to make traced random choices:However, it is not currently possible to write a generative function that returns a set of mutually recursive generative functions. You can imagine this being useful for, e.g., writing a random PCFG generator: a generative function that makes random choices to construct a grammar, then returns a list of generative functions corresponding to the non-terminals in that PCFG. Maybe there are other examples, too. For this sort of thing, we'd need
letgen.A potential implementation technique is described here: https://stackoverflow.com/a/54587792/1931098