Ray Tracing In One Weekend (in Lisp, and n-dimenions) September 26th, 2024
Patrick Stein

Earlier this year, I started working through the online book Ray Tracing In One Weekend (Book 1). I have been following along with it in Common Lisp, and I have been extending it all from 3-dimensional to n-dimensional.

I reproduced 4-dimensional versions of all of the book images which you can see on my weekend-raytracer github page.

Here is the final image. This is a 250-samples-per-pixel, 640x360x10 image plane of three large hyperspheres (one mirrored, one diffuse, one glass) atop a very large, diffuse hypersphere. Also atop this very large hypersphere are a bunch of smaller hyperspheres of varying colors and materials. The image is rendered with some defocus-blur.

Image described in detail in post.
Final image of 4-dimensional scene

Caveat: This depends on a patched version of the policy-cond library that is not in the current Quicklisp distribution but should be in the next.

Track-Best Library Released May 9th, 2013
Patrick Stein

In doing a problem set from the Internet a few weeks ago, I found myself writing awkward constructions with REDUCE and LOOP to try to find the best one (or two or three) things in a big bag of things based on various criteria: similarity to English, hamming distance from their neighbor, etc.

I wrote a macro that encapsulated the pattern. I’ve reworked that macro into a library for public use.

Acquiring

Using

There are a variety of examples in the README and the tests directory.

Here is one example to pique your interest. Suppose you have some data about the elevations of various cities in various states and you (being a Moxy Fruvous fan) want to know What Is the Lowest Highest Point? Here’s how you might tackle that with the TRACK-BEST library:

(let ((data '(("Alabama"  ("Birmingham" 664)
                          ("Mobile" 218)
                          ("Montegomery" 221))
              ("Alaska"   ("Anchorage" 144)
                          ("Fairbanks" 531))
              ("Arizona"  ("Grand Canyon" 6606)
                          ("Phoenix" 1132)
                          ("Tuscon"  2641)))))
  (with-track-best (:order-by-fn #'<)
    (dolist (state-info data)
      (multiple-value-bind (city altitude)
          (with-track-best ()
            (dolist (city-info (rest state-info))
              (track (first city-info) (second city-info))))
        (track (list (first state-info) city) altitude)))))

With this limited dataset, the end result would be (VALUES '("Alaska" "Fairbanks") 531). The inner WITH-TRACK-BEST finds the highest city in each state. The outer WITH-TRACK-BEST finds the lowest of these.

USerial Library — v0.1.2010.12.26 December 27th, 2010
Patrick Stein

I am putting together a networking library atop usocket for use in a multiplayer Lisp game. So far, I have implemented a library for serializing data into a byte buffer.

Here is a simple example of serializing some things into a buffer:

(make-enum-serializer :opcode (:login :run :jump :logout))
(make-bitfield-serializer :login-flags (:hidden :stay-logged-in))

(serialize* (:opcode :login
             :uint32 sequence-number
             :login-flags '(:hidden)
             :string login-name
             :string password) buffer)

You can unserialize those bits into existing places:

(let (opcode sequence-number flags login-name password)
  (unserialize* (:opcode opcode
                 :uint32 sequence-number
                 :login-flags flags
                 :string login-name
                 :string password) buffer)
  ...)

You can unserialize them into newly-created variables for use within a body:

(unserialize-let* (:opcode opcode
                   :uint32 sequence-number
                   :login-flags flags
                   :string login-name
                   :string password) buffer
  ...)

Or, you can unserialize them into a list:

(let ((parts (unserialize-list* (:opcode
                                 :uint32
                                 :login-flags
                                 :string
                                 :string) buffer)))
  ...)

You can find out more about the serialization library on my unet page.

CL-Growl client library released April 12th, 2010
Patrick Stein

Growl is a notification system for Mac OS X. You run a Growl server on your machine. Then, applications can send notifications that will be displayed on your desktop. Growl supports a thin network protocol called Growl Talk that programs can use to send notifications to the Growl server (and hence, to your desktop).

Growl is incredibly useful for any program that operates asynchronously with the user. If you want to be notified when some portion of your job completes or when there is a critical error in your web application, Growl is a great tool to have at your disposal.

I wrote an implementation for Common Lisp of the client protocol. Here is a simple example of how you might use it:

(let ((growl:*growl-default-app* "My Lisp Application")
      (growl:*growl-default-host* "localhost")
      (growl:*growl-default-password* "my-growl-password"))
  (growl:register :enabled (list "Warn" "Error")
                  :disabled (list "Info"))
  (growl:notify "Program starting up..."
                :notification "Info")
  (unless (connect-to-database ...)
    (growl:notify "Cannot connect to database!"
                  :title "Critical Error!"
                  :notification "Error"
                  :sticky t
                  :priority 2)))

For more complete usage information and to learn how to obtain the library, see the CL-Growl web page.

Parser Generator released April 9th, 2010
Patrick Stein

A few weeks back, I described an XML Parser Generator that I was working on. At the time, it could generate the parser it used itself. Now, it’s got Objective-C support and Lisp support. (The Lisp support is slightly better than the Objective-C support right now. With the Objective-C backend, you can create arrays of structs, but not arrays of strings or integers.)

Here is the Parser Generator home page.

Updates In Email

Email:

l