Thursday, April 26, 2007

I've learnt some CFFI while trying to play with SDL (bottom line being, Macs are weird, I shoulda known better, *shakes fist*) and it's real smooth stuff. It's still not second nature, but it's really nice to read through the tutorial for a library, encounter a function or a type you haven't used yet, enter a simple declaration or two in my running SBCL image, and start playing around with the function to see how it works.

Tonight I was trying to learn to use SDL_audio (which is nice, because it forces me to learn how to do callbacks in CFFI) and I made a simple white noise generator. So it turns out it's not a good idea to cons in a callback that is called 44100 times a second. :D I managed to get the error message "Whoa! allocation trap and we weren't in lisp!" and had an uninterruptible stream of white noise coming out of my speakers while frantically trying to bring up a terminal to kill sbcl, my hard drive thrashing as it swapped out virtual memory it never knew it had.

Who says I don't ever do anything exciting?

Tuesday, January 16, 2007

Lexical closures in Common Lisp vs. Lua

I don't get to do too much with dynamic languages at work, so I was really happy to get a chance to write some Lua today. I wanted to make a function that would create a timer that would execute a callback when it was finished, and long story short, I started experimenting with closures to see exactly how they worked in Lua. I came across something that I didn't entirely expect. First, an example in CL:
(mapc (lambda (x) (funcall x))
(loop for i from 1 to 3 collect
(let ((localvar i))
(lambda ()
(format t "loop:~a, local:~a~%" i localvar)))))
This outputs:
loop:4, local:1
loop:4, local:2
loop:4, local:3
which makes sense to me, now that I've been working in Common Lisp. Inside the inner lambda, i refers to the loop variable, which is at 4 at the end of the loop. During each iteration of the loop, a new binding is created for localvar, and then the inner lambda closes over it. That's why we have different values for local but the same value for loop.

However, the closest equivalent I can manage in Lua is this (apologies for the temporary):
collection={}
for i=1,3 do
collection [i] = function ()
local localvar = i
print("loop:" .. i .. ", local:" .. localvar .. "\n")
end
end
for k,v in pairs (collection) do
v()
end
And this outputs:
loop:1, local:1
loop:2, local:2
loop:3, local:3
So, it looks like Lua actually closes over the value, whereas Lisp closes over the binding. I'm trying to think of a way to force Lua to close over the binding by boxing the value or something, but I'm coming up dry.