Friday, February 29, 2008

Implementing LISP's ITERATE macro in Groovy

I've always been a big fan of posts like Why Ruby is an acceptable LISP and Paul' Graham's Revenge of the Nerds, even though I despise the syntax of LISP. I love that, aside from the requisite flame posts, these types of posts tend to stir up great efforts from skilled programmers to show the relative merits of their personal lingua franca.

I've worked with Java for well over 10 years now not because I felt it was the best language, but because I felt that combined with the JVM it offered the best compromise between language features, portability, vendor independence, library availability, and mainstream acceptance. And the emergence of Groovy and Grails on that platform has rejuvenated my confidence in the platform despite the crossfire from the likes of Ruby/Rails, Flex/Flash/Actionscript, C#/.NET, and others.

So with that in mind, I decided it might be fun to play around with the idea of implementing one of LISP's extremely powerful macros, ITERATE, in Groovy. If you haven't seen the ITERATE macro, it's well worth a look because it shows how LISP's macro facility can be used to elegantly implement many looping constructs that often require entirely new keywords and/or syntax in other languages. Here are some simple examples taken directly from the ITERATE manual:

Example: collect the numbers from 1 to 10 into a list, and returns the list
  (iter (for i from 1 to 10)
(collect i)) => (1 2 3 4 5 6 7 8 9 10)
Example: collect all the odd numbers in a list
  (iter (for el in list)
(if (and (numberp el) (oddp el))
(collect el)))
Example: take the keys of an alist and returns a new alist associating the keys with their positions in the original list
  (iter (for (key . item) in alist)
(for i from 0)
(declare (fixnum i))
(collect (cons i key)))
And here's a contrived example from one of the blog posts above attempting to show some of the macro's capability:
  (iter (for x in '(1 2 3 -4 -10 -43 49 49 8934))
(until (= (sqrt 7) x))
(collect x into collection)
(finding x maximizing (abs x) into y)
(finally (return (list collection y))))
;; ((1 2 3 -4 -10 -43) -43)
So with that in mind, I've started prototyping what it might look like in Groovy, whether it can truly be implemented, and whether it's even needed (e.g. the simplest example above is built directly into the Groovy language as 1..10). And I'll be posting results here as I go.