Monday 29 January 2007

Format

Format is one of those features in Common Lisp that people seem to have a love/hate relationship with, the other being loop. Both have their own mini languages that are not especially lispy. I'm still not too sure where I stand in this debate but being able to say things like this is still pretty incredible.




(defun print-diamond (str x &optional c a (max (1+ x)) (star "*"))
(format str "~&~[~:;~:*~vT~v@{~A ~:*~}~3@*~v,v/print-diamond/~:*~v[~:;~@*~vT~v@{~A ~:*~}~%~]~]"
x (- max x) star max star (1- x)))


Now for an explanation of that format string.
Bear with me this is hairy.


  • ~& : Conditional newline (insert newline if we aren't at the start of a line)

  • ~[ : Process the nth clause (seperated by ~:). ~:; specifies a default clause. This consumes the argument x. This directive causes print-diamond to stop processing when x is zero.

    • ~:* : Backup 1 argument (unconsumes the argument x)

    • ~vT : Insert arg number of spaces (this reconsumes the first argument ie. x)

    • ~v@{ : Iterate v times, v is (- max x).

      • ~A : Print 1 element

      • ~:* : Backup 1 element (The effects of the last 3 directives is to print star (- max x) times)

    • ~} : End loop

    • ~3@ : Move to the 3rd argument (star)

    • ~v,v/print-diamond/ : The recursive call. invoke print-diamond again with max, star and (1- x), This is equivalent to calling (print-diamond stream (1- x) nil nil max star)

    • ~:* : Backup 1 argument (unconsumes (1- x))

    • ~v[ : Conditional processing based (1- x).

      • ~@* : Go to the start of the argument list.

      • ~vT : Insert arg number of spaces (this consumes the first argument again)

      • ~v@{ : Iterate v times, v is (- max x).

        • ~A : Print 1 element

        • ~:* : Backup 1 element (The effects of the last 3 directives is to print star (- max x) times)

      • ~} : End loop

      • ~% : Insert a new line

    • ~] : End conditional processing

  • ~] End conditional processing




Whew, brain freeze.

now we can do (print-diamond t 10)

*
* *
* * *
* * * *
* * * * *
* * * * * *
* * * * * * *
* * * * * * * *
* * * * * * * * *
* * * * * * * * * *
* * * * * * * * *
* * * * * * * *
* * * * * * *
* * * * * *
* * * * *
* * * *
* * *
* *
*

darjeeling

This looks as if it could be quite interesting.

The ability to convert Ruby to Common Lisp (or ideally just load ruby files) should put paid to complaints about the lack of libraries in CL.

Of course it could turn out to be absolutely nothing but I'm going to keep an eye on it.

Thursday 11 January 2007

Lispworks 5.1 Personal Edition

At last, Lispworks Ltd has announced the release of Lispworks 5.1 Personal Edition!

New features
- Threading now uses pthread on Linux
- FreeBSD port
- Support for Intel Mac's

More here