top of page

Henderson Picture Language

barton-square-cut.png

Henderson is a partial implementation in Clojure of the Henderson Picture Language (HPL) described in Structure and Interpretation of Computer Programs by Harold Abelson and Gerald Sussman (aka SICP).

HPL was invented by Professor Peter Henderson and first described in his 1982 paper (Henderson, P. (1982) Functional Geometry. Proc. ACM Symp. on Lisp and Functional Programming. pp. 179-187). An updated version of the paper is available here. SICP uses HPL to illustrate abstraction, high order functions, combinators and composition.

 

How to create images

The key abstration in HPL is a painter. A painter knows how to render an image. HPL comes with two primitive painters: segments-painter and make-image-painter. A painter is shown on the screen with the function (show-picture painter width height) where width and height are in pixels.


 

segments-painter

The segments-painter creates an image based on line segments. The origin (0,0) is the top left corner of the image and (1,1) is the bottom right corner. So for example to show a cross you could do:

 

Screenshot 2021-03-18 at 16.52.12.png
Screenshot 2021-03-18 at 16.52.34.png
make-image-painter

The make-image-painter creates a painter that can render an image from a file, such as a JPEG.

 

Screenshot 2021-03-18 at 17.01.30.png
Screenshot 2021-03-18 at 17.00.39.png
painter combinators

Painters can be combined to produce more complicated images. For example besides combines two painters to produce two images side by side and flip-vert takes a painter and renders it upside down. If wave is a painter that produces an image of a man waving, then the combinators and painters can be combined as follows:

 

Screenshot 2021-03-19 at 11.03.32.png
Screenshot 2021-03-19 at 11.02.58.png

Implementation

For more about how to use the library and how it works, see SICP

 

A frame is a rectangle (possibly distorted) in which painters render themselves. A frame is described by three vectors: a vector to the origin and two vectors representing the two edges. The implementation suggested in SICP views a painter as a function that takes a single input argument, a frame, and renders it. However, to allow for the modern windowing systems, I have implemented a painter as a function that takes two inputs: a Graphics2D object and a frame. A Graphics2D objects is a Java object designed for rendering images. Passing this as an argument allows the user of the painter to specify which window to render to. The beauty of the painter abstraction is that irrespective of this implementation change, painters are created and used in exactly the same way as before.

The current implementation makes me uncomfortable as the painters have side effects. For instance it makes it difficult to write tests for the painters. A neater implementation would be to make the painters data structures that merely describe how they would render an image. The show-picture function could then become an interpreter which does the actual IO. A Haskell implementation of an algebra inspired by Henderson Picture Language that takes this approach is described in Sandy Maguire's book Algebra-Driven Design.

My code for this project is available on GitHub.

 

bottom of page