Blogging in Lisp


Lisplog is a templating system that blends Apache and Hunchentoot to aid in the maintenance of a blog-like web site.

It is open source, written in Common Lisp, and the code is at

I'm looking for work. My resumé is at

Kakuro-Dojo Is Good Enough to Play

Submitted by Bill St. Clair on Tue, 25 Oct 2016 17:35:37 GMT

My Kakuro puzzle game, written in Elm is now quite usable on in iOS browsers, at least it works well on my iPhone 6S Plus and iPad 2. If you have an Android device, please give it a try, and let me know in comments how it works for you.

In order to properly size it on the small screen, I changed my original HTML table-based layout to SVG, giving me full control of all sizes. Works good.

Here it is running on my iPad:

Kakuro Dojo on iPad

You have to scroll it vertically into game-playing position, but pinch and zoom are disabled by the game, so you don't need to size it. I will eventually add a checkbox to turn off everything on the page but the game controls.

The game remembers your state in every game you've played, in your browser's "database". But this doesn't port across browsers or devices, so I'm working next on a backend for that.

I'm planning to write the backend in Haskell, using PostgreSQL or one of the key/value stores for persistence. It will be a general-purpose, but very simple, web-enabled key/value store, which I'll use for mapping appid/key to JSON strings. I have other plans for the backend, which I'll share when it's working and I start development.

Add comment   Edit post   Add post

SVG Rocks!

Submitted by Bill St. Clair on Sat, 22 Oct 2016 10:01:57 GMT

I laid out the tables at as, well, html <table>s. There's a problem, though. They tend to squish sometimes, and it's bloody difficult, for me, to get them to auto-size properly for the small screen (e.g. iPhones). So I've decided to do it all myself, in SVG, and it doesn't look like i's going to be that hard. Below is my test code. Now I just have to parameterize it with the screen dimensions. The new code is likely to be simpler than the old. View source to see what the SVG looks like.

16 17 9 8 7 9

Add comment   Edit post   Add post

What Are You Listening To?

Submitted by Bill St. Clair on Thu, 20 Oct 2016 17:11:36 GMT

I snarfed from an old IRC client, that I no longer use, nor remember the name of, an AppleScript that inserted the current tune playing in iTunes. I modified it to make it work in the "Services" menu.

First, download the script. If it doesn't automatically uncompress, double click it so it does.

Now, in the Finder, go to the "~/Library/Services" directory. "~/Library" is usually hidden, so you need to use the Finder's "Go / Go to Folder..." menu item:

Finder "Go to Folder..." menu item

Type "~/Library/Services" into the resulting dialog, and click "Go":

Finder "Go to Folder..." dialog

Open up your "Downloads" folder, and drag the "iTunes.workflow" file to the "Services" folder (it's actually a directory, but one that Finder treats as a file):

Drag to Services

After what is on my machine a random delay, the new script should appear in the "Services" sub-menu of each application's application menu, when a text field is focused for input:

iTunes menu item on Services menu

If you select it, after a bit of a delay (AppleScript is slow to start), it should insert the tune to which you're currently listening. The text is designed for IRC clients (and Skype and probably a few other copycats), where "/me" turns into your username, but you can edit that.

Tune pasted

Add comment   Edit post   Add post

Wake 2011 iMac from Sleep

Submitted by Bill St. Clair on Tue, 18 Oct 2016 06:51:14 GMT

I've been having a problem with my late 2011 iMac. I wrote about it back in April, in Mac OS X 10.11.4 Beachball on Wake from Sleep. With my upgrade to macOS Sierra, the problem has changed. It no longer beach balls, but it wouldn't wake from putting the display to sleep (which I do with a hot corner in System Preferences / Dekstop & Screen Saver.

I discovered a month or so ago that momentarily pressing the power button, on the back left corner of the iMac, wakes it up. I've been very happily using that since then. Today, I discovered that clicking the mouse button also works.


Add comment   Edit post   Add post

End the War on Freedom Returns!

Submitted by Bill St. Clair on Sat, 15 Oct 2016 16:13:48 GMT

I've revived my political blog, End the War on Freedom, after a year and a half in mothballs. It's now at Check out my reintroduction post, and don't miss the news aggregator.

Add comment   Edit post   Add post

Elm Converts Tail Calls to Loops!

Submitted by Bill St. Clair on Wed, 12 Oct 2016 19:19:50 GMT

I've been converting my Kakuro game at to Elm. I'm loving it. I decided I needed a hash function, and not finding any good ones, I wrote my own, connecting to a JavaScript implementation I found via a quick Google search.

I figured I might as well provide it to the community, so I packaged it up as a module, pushed it to GitHub, and did "elm package publish" to upload it to the community packages site. I was met with this bug report:

It is not possible to publish packages with native modules.

Elm compiles to JavaScript right now, but that may not always be true. For the long-term health of our package ecosystem, as many packages as possible should be written in Elm. This definitely means we will grow a bit slower, but I am willing to pay that cost if it leads to a better community and ecosystem!

Oh, well. I understand. Evan Czaplicki is working on non-JavaScript backends, and doesn't want the conversion to get any worse than it already is.

So I decided to convert the JavaScript library into Elm, just for practice. It has lots of loops, which need to be converted to recursion in Elm, so I wanted to see if I was setting myself up for stack overflow. Apparently, not. Let-bound functions can call themselves recursively, and the compiler turns tail calls, in both let-bound functions and top-level functions, into loops in the generated JavaScript. There's no need to worry about stack overflow.

Here's the Elm code:

foo : Int -> Int -> Int
foo =
  let foo' = (\y z ->
                if y<= 0 then
                  foo' (y-1) (z+1))

bar : Int -> Int -> Int
bar y z =
  if y <=0 then
    bar (y-1) (z+1)

And here's the output of the compiler:

var _billstclair$elm_sha256$Temp$foo = function () {
	var foo$ = F2(
		function (y, z) {
			while (true) {
				if (_elm_lang$core$Native_Utils.cmp(y, 0) < 1) {
					return z;
				} else {
					var _v0 = y - 1,
						_v1 = z + 1;
					y = _v0;
					z = _v1;
					continue foo$;
	return foo$;

var _billstclair$elm_sha256$Temp$bar = F2(
	function (y, z) {
		while (true) {
			if (_elm_lang$core$Native_Utils.cmp(y, 0) < 1) {
				return z;
			} else {
				var _v0 = y - 1,
					_v1 = z + 1;
				y = _v0;
				z = _v1;
				continue bar;

But it's not smart enough to handle tail-calls correctly for two mutually-recursive functions, each of which tail-calls the other. Can't say I'm surprised. It's certainly possible to do, but it would be much easier if JavaScript just provided tail call optimization. Then the generated code would work. As it happens, the new ECMAScript 6 DOES provide tail-call optimization.

Here's my mutually-recursive Elm example:

foo : Int -> Int -> Int
foo y z =
  if y <=0 then
    bar (y-1) z

bar : Int -> Int -> Int
bar y z =
  foo y (z + 1)

And here's the generated JavaScript:

var _billstclair$elm_sha256$Temp$foo = F2(
	function (y, z) {
		return (_elm_lang$core$Native_Utils.cmp(y, 0) < 1) ?
                  z :
                  A2(_billstclair$elm_sha256$Temp$bar, y - 1, z);

var _billstclair$elm_sha256$Temp$bar = F2(
	function (y, z) {
		return A2(_billstclair$elm_sha256$Temp$foo, y, z + 1);

The single self-recursive program is all I need for my sha256 loops. And now I know that I have to keep the recursion inside ONE Elm function, until ECMAScript replaces JavaScript inside major browsers.

Add comment   Edit post   Add post

My First Haskell Program

Submitted by Bill St. Clair on Fri, 07 Oct 2016 05:08:55 GMT

I've been working through Learn You a Haskell for Great Good, after spending quite a bit of time learning Elm, and realizing that it is basically a subset of Haskell that compiles to JavaScript.

I wrote my first tiny Haskell program. It matches one of my early Lisp programs, way back in 1974, that printed the 120 permutations of the MIT slogan: "I hate this fucking place!"

Permutation is much clearer in Haskell. And lazy computation is incredibly neat.

You can download it at or display it at Full text below:

-- print-ihtfp.hs
-- Build with:
--   ghc --make print-ihtfp
-- Run with:
--   ./print-ihtfp
-- Or, in ghci:
--  :l print-ihtfp
--  main

import Data.Char (toUpper)

distribute :: a -> [a] -> [[a]]
distribute x [] = [[x]]
distribute x (y:ys) =
  (x:y:ys) : (map (y:) $ distribute x ys)

permute :: [a] -> [[a]]
permute [] = []
permute [x] = [[x]]
permute (x:xs) =
  concatMap (distribute x) (permute xs)

permuteSentence :: String -> [String]
permuteSentence x =
  map unwords $ permute $ words x

nums :: [String]
nums = map (++ ": ") $ map show [1..]

fixSentence :: String -> String
fixSentence "" = ""
fixSentence (x:xs) =
  (toUpper x) : xs ++ "!"
ihtfp :: [String]
ihtfp = permuteSentence "I hate this fucking place"

main = do
  putStrLn $ unlines $ zipWith (++) nums $ map fixSentence ihtfp

2 comments   Edit post   Add post

Karabiner-Elements for macOS Sierra

Submitted by Bill St. Clair on Mon, 12 Sep 2016 21:20:26 GMT

On Saturday, I bemoaned the breaking of Karabiner in macOS Sierra. I was very unfond of having to again press the "control" key instead of the "fn" key. Well, the replacement now works well enough for my purposes. You can download it at Follow the instructions there for creating a karabiner.json config file, and put the following in it:

    "profiles": [
            "name": "Default profile",
            "selected": true,
            "simple_modifications": {
                "fn": "left_control",
                "left_control": "fn"

2 comments   Edit post   Add post

macOS 10.12 Sierra

Submitted by Bill St. Clair on Sat, 10 Sep 2016 06:19:06 GMT

Since the user beta is now what will ship next Wednesday, and after testing in a VMWare VM that it didn't break anything I really need to do my work (Emacs and Clozure Comon Lisp), I installed macOS 10.12 Sierra on my big iMac. This post is to let you know what worked and what didn't.

Didn't Work

  • Karabiner doesn't work. This is a known bug, and Takayama Fumihiko is hard at work on Karabiner-Elements to fix it. I use Karabiner to map the "fn" key on my Apple Wireless keyboard to left "control". The control key belongs in the lower-left-hand corner, NOT the seldom-used "fn" key. Especially for an Emacs weenie like me, who uses "control" every few seconds. The temporary fix is to add to the variables set by m-x customize-group for the "ns" group. In particular:
        (custom-set-variables '(ns-function-modifier (quote control)))
    This makes "fn" behave as "control" while in Emacs, but it doesn't fix it for Terminal, or general text field editing, which Karabiner used to fix.
  • Seashore crashes on launch. This is an ancient paint program that I will sorely miss. Maybe even enough to try to fix it.
  • I had to update Skype to the latest version (7.35). My old version crashed on launch.

Did Work

Most everything worked. I won't mention the Apple apps that ship with the OS. Those work, of course. But here are the others, with the version I'm running in parentheses.

2 comments   Edit post   Add post

Sizing An iOS Custom Keyboard for Scaled Apps

Submitted by Bill St. Clair on Fri, 05 Aug 2016 19:24:19 GMT

I've been writing a custom iOS keyboard for Learning Touch, a novel way of entering text that we're hoping will be easier for people with non-steady hands, though it works fine for the rest of us, too. Can't give any more details until the patent request has been filed, but that will be soon.

I lay out the keyboard myself, with sizes designed to work on a standard 768x1024 pixel iPad, and scaled to the screen size of the device on which it's running. This works fine, for apps that have been updated for each device's screen size, but it failed for old apps that were scaled and/or run in letterbox mode; the keyboard was too wide, so part of it was invisible off the right edge of the screen.

I was just using the hardware bounds, in logical pixels. I needed to scale to the view size, which is narrower for scaled apps. The simple (Swift) code below takes the hardware size from UIScreen.mainScreen.bounds.size and the parent view size (that view is set outside this function and referenced with the getParentView() call).

Strangely, I found no hint of this algorithm in a bunch of Google searches, so I'm posting it, to hopefully make it easier for the next guy to find.

    public static func screenSize() -> CGSize {
        var size = UIScreen.mainScreen().bounds.size
        if let parent = getParentView() {
            // Accomodate for old apps that need to be scaled.
            let vw = parent.frame.width
            let factor = vw / size.width
            size.width = vw
            size.height *= factor
        return size

Unfortunately, there doesn't appear to be any way to tell if an app is running in letterbox mode, so you'll tend to size the keyboard vertically bigger than ideal for those.

Add comment   Edit post   Add post