Archive for the 'Lisp' Category

Practical Common Lisp

Wednesday, October 18th, 2006

Practical Common LispLast Sunday, browsing the bookshops in town, “Practical Common Lisp” by Peter Siebel caught my eye. I remember reading it online about a year ago. It allowed me to rediscover Lisp, since, to my regret, I had to bid farewell to the programmable programming language when I left college. It might have been nostalgia but I thoroughly enjoyed this book. Thanks to Peter Siebel! I had no hesitation, I bought the hardcover straight away. I can only recommend it highly for anyone wanting to learn Lisp.

This post would not be complete without pointing you to Paul Graham’s “On Lisp”.

Little LISP challenge

Tuesday, February 21st, 2006

Last night, I happened to land on Paul Bissex’s Let’s play a game: BASIC vs. Ruby vs. Python vs. PHP. Obviously this competition has degenerated into a brawl involving a great variety of programming languages including Rebol, Haskell and JavaScript, for example. I decided to set myself a little challenge: come up with a LISP competitor (at the same time, I’ll prove to Jer that I’m not afraid of a pair of parenthesis or two). I quote Paul for the rules of the game:

The game of REVERSE requires you to arrange a list of numbers in numerical order from left to right. To move, you tell the computer how many numbers (counting from the left) to reverse. For example, if the current list is 2 3 4 5 1 6 7 8 9 and you reverse 4, the result will be 5 4 3 2 1 6 7 8 9. Now if you reverse 5, you win.

I came up with two versions. But first, let me introduce two self-explanatory utility functions used in both versions:

(defun shuffle-list (l)
  (loop for i below (length l) do
	(rotatef
	 (elt l i)
	 (elt l (random (length l)))))
  l)

(defun prompt (l)
  (format t "~{~a~^, ~}~%How many to swap? " l)
  (read))

Here is the non-recursive version:

(defun playgame (n)
  (let ((goal (loop for i from 1 to n collect i)))
    (do ((count 0 (1+ count))
	 (state (shuffle-list (copy-list goal))
		(let ((howmany (prompt state)))
		  (append
		   (reverse (subseq state 0 howmany))
		   (subseq state howmany)))))
	((equal state goal)
	 (format t "Done! that took ~d steps.~%"
		 count)))))

and the recursive version:

(defun play (state step)
  (if (equal state (sort (copy-list state) #'<))
      step
      (let ((howmany (prompt state)))
        (play (append
               (reverse (subseq state 0 howmany))
               (subseq state howmany))
              (+ step 1)))))

(defun playgame2 (n)
  (format t \"Done! That took ~d steps.~%\"
          (play (shuffle-list
                 (loop for i from 1 to n collect i)) 0)))

Can you improve on this? Do not hesitate to comment!

Metaprogramming, Java’s downfall

Monday, February 20th, 2006

I have been a Java developer for almost 10 years and I must admit I really enjoy coding in Java. When I first discovered it, I was amazed by its API, the quality of its documentation, its simplicity and most of all its portability. With experience came a better understanding of the Java philosophy and a deeper understanding of Object Oriented concepts. Lately though, I have found Java to be a limiting factor to my productivity. I have identified the main reason behind this: Java lacks metaprogramming. Briefly put,metaprogramming is writing programs that write programs (see metaprogramming on wikipedia).

Here is an illustration of the problem. Everytime I want to write a JavaBean object, I have to make the class serializable, make sure the class has a default constructor, write getters and/or setters for all properties, write methods to register and unregister listeners for the bound properties, etc. It has to be done for every single bean you ever write. Coupled to the fact that unit tests for getters and setters are rarely written, leads to a very error prone process. It is easy to see that there is a definite pattern to this extremely repeatitive task, and obviously there are ways to ease the pain. Code generating tools like xdoclet and eclipse for example, do a decent job in this case. However, these tools suffer because they each use their own templating language and their functionality is usually limited to a C/C++ macro style of behaviour, agnostic of the language itself. By contrast, in a metaprogramming language, this templating and the code it generates are implemented in one language only. It is therefore possible to extend the language itself, by adding new constructs, rather than just develop the object hierarchy.

LISP is probably the quintessential metaprogramming language. LISP’s macros are so powerful that it has been able to adapt and incorporate every new programming paradigm. To my knowledge (and wikipedia’s), LISP (1958) predates all OO languages, as the concept was only being born, and yet CLOS is implemented in LISP itself and supports some features that other OO languages can only dream of (multiple dispatch for example). When AOP came about, it did not take long for LISP to have its own implementation: AspectL.

People usually object that LISP is unreadable. I suppose we will all agree that parentheses, like everything in life, must be used in moderation. But metaprogramming does not have to be implemented in a heavy and unreadable way. In order of increasing readability, I will point you to Io and to Ruby. Ruby uses metaprogramming, for example, to define accessors. But Ruby’s killer-app, Rails pushes this usage even further to provide a DSL for web development. See for yourself, I doubt you will find that Rails’s productivity claims are exaggerated.

For more information on metaprogramming and DSLs, I would recommend listening to the latest Rails podcast with Glenn Vanderburg and to check out Glenn’s blog, starting by this post. I also found Jose Antonio Ortega Ruiz’s blog, programmings musings to be a goldmine, see particularly: this post and follow the link to this good introduction to metaprogramming.

Follow

Get every new post delivered to your Inbox.