Skip to content

Boxed closures should be nameable, too #2257

Closed
@jwise

Description

@jwise

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

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions