= Solution
Add `Fixes [Ident] [Expr]` to the <abstract syntax tree>. For the stipulated nonempty, equally long lists of distinct names and <lambda abstractions>, define all <programming closures> against one common extended <semantic environment>:
``
eval (Fixes xs es) rho = result (head vs)
where
rho' = extend rho (zip xs vs)
vs = map (\e -> close e rho') es
``
Expanding the auxiliary <function>, if $e_i=\operatorname{Lambda}\ ys_i\ b_i$,
$$
\boxed{\begin{aligned}
\rho^*&=\operatorname{extend}(\rho,[(x_1,v_1),\ldots,(x_n,v_n)]),\\
v_i&=\operatorname{Function}\bigl(\lambda args.\,
\operatorname{eval}(b_i)(\operatorname{extend}(\rho^*,\operatorname{zip}(ys_i,args)))\bigr),\\
\operatorname{eval}(\operatorname{Fixes}\ [x_1,\ldots,x_n]\ [e_1,\ldots,e_n])\,\rho
&=\operatorname{result}(v_1).
\end{aligned}}
$$
Every body can therefore call every member of the family, including itself. Constructing the family performs no body computations in the arbitrary <computational monad>. As in part (c), host <lazy evaluation> ties the recursive <semantic environment>; a monadic fixed-point operator is unnecessary.
For example, with two bodies implementing evenness and oddness, respectively, each <programming closure> sees both names in $\rho^*$. Returning the first <programming closure> still retains access to the second. Building each <programming closure> in an independently extended old <semantic environment> would lose this <mutual recursion>. For $n=1$, the definition agrees with `Fix`.
Back to article page