Closed
Description
It would be really nice if it were possible for a boxed closure to recur on itself. A use case that I find particularly compelling is a variable substitution, which currently looks like this (impl
version suggested by @nikomatsakis):
/* this code is in an impl, e.subst(x, y) := [x/y]e */
fn subst(gen: fn@() -> var, x: expr, y: var) -> expr {
let fvs = x.freevars();
type subst_encap = { gen: fn@() -> var, x: expr, y: var, fvs: map::set<var>};
impl subst_ops for subst_encap {
fn subst(e: expr) -> expr {
alt e {
e_app(e1, e2) {
e_app(@self.subst(*e1), @self.subst(*e2))
}
e_lam(v, ep) {
alt self.fvs.find(v) { /* v free in x? */
option::none { /* no */
e_lam(v, @self.subst(*ep))
}
option::some(_) { /* yes, alpha-vary \v.ep */
let vp = self.gen();
e_lam(vp, @self.subst((*ep).subst(self.gen, e_var(vp), v)))
}
}
}
e_var(v) {
if v == self.y { self.x }
else { e }
}
}
}
}
let enc : subst_encap = {gen: gen, x: x, y: y, fvs: fvs};
enc.subst(self)
}
Previously, it was even worse; the inner function was something of the form 'fn subst_(...)', which passed 'gen', 'x', 'y', and 'fvs' all the way through, which was really painful.
@nikomatsakis then suggested that I file this bug. My suggestion is syntax of the form: fn@ subst_(...)
. The problem then is if we want functions that mutually recur; another thought, then, is an ML-style let rec func1 = fn@(...) {...} and func2 = fn@(...){...}
.
Thoughts?