Saturday, March 22, 2014

Closures in VimL


I’ve talked about Anonymous Functions in VimL before, but what about closures?

What is necessary for a language to be able to say that it supports closures? What is sufficient for someone to be able to fake their way through it?

Here is the first example from Wikipedia’s Closure article:


def start(x):
    def increment(y):
        return x+y
    return increment

first_inc = start(0)
second_inc = start(8)

first_inc(3)   # returns 3
second_inc(3)  # returns 11

# The x value remains the same for new calls to the function:
first_inc(1)   # returns 1
second_inc(2)  # returns 10

Here is a faked-up alternative in VimL:


function! Start(x)
  let obj = {}
  let obj.x = a:x
  func obj.increment(y)
    return self.x + a:y
  endfunc
  return obj
endfunction

let first_inc = Start(0)
let second_inc = Start(8)

echo first_inc.increment(3)
echo second_inc.increment(3)

echo first_inc.increment(1)
echo second_inc.increment(2)

Okay, so not really what you think of as a closure, but it lets you get similar things done. Wikipedia says:
Closures are typically implemented with a special data structure that contains a pointer to the function code, plus a representation of the function’s lexical environment (i.e., the set of available variables) at the time when the closure was created.
— Wikipedia
The manual marshalling in our object-oriented implementation above probably doesn’t count, but it’s a similar idea… isn’t it?

Vim certainly has First Class Functions and with VimaholicsAnonymous, it has Anonymous Functions… Does it have closures? If not… does it matter? Can you achieve something similar using its prototypal object notation?