Hacker News new | past | comments | ask | show | jobs | submit login

Hello peconn,

This is right, although you could replace KontSkip(kont) with just kont. Defunctionalization does not just "move the recursion from one place to another." Rather, it doesn't change the recursion at all.

Also, your example is actually harder than the one in the talk, because it can involve an arbitrary amount of work after the last call to my_filter_recursive.

Like in the example in the talk, you still need merge the various calls to apply, and use tail-call elimination.

Merging:

    def apply(kont, acc):
        if isinstance(kont, KontAdd):
           apply(kont.kont, [kont.var] + acc)
        else:
           print(acc)
You will now actually need two levels of tail-call elimination because there are two recursions, rather than one as in the example in the talk. apply becomes this:

    def apply(kont, acc):
      while True:
            if isinstance(kont, KontAdd):
               kont = kont.kont
               acc = [kont.var] + acc
            else:
               print(acc)
               break
You can then inline this into my_filter_cps and do tail-call elimination again.

  def my_filter_defun(l, f, kont):
    while True:
      if l:
          x, *xs = l
          if f(x):
              l = xs
              kont = KontAdd(x, kont)
          else:
              l = xs
      else:
        acc = []
        while True:
          if isinstance(kont, KontAdd):
             kont = kont.kont
             acc = [kont.var] + acc
          else:
             print(acc)
             break



One little beef with CPS (for an interpreter) is that use it cause a hit on performance. Defunctionalization could be use to improve on that?




Consider applying for YC's Summer 2025 batch! Applications are open till May 13

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: