- 
                Notifications
    You must be signed in to change notification settings 
- Fork 13.9k
Closed
Labels
A-type-systemArea: Type systemArea: Type system
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?
Metadata
Metadata
Assignees
Labels
A-type-systemArea: Type systemArea: Type system