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

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

Conway's Life in JavaScript

Submitted by Bill St. Clair on Thu, 26 May 2016 11:31:13 GMT

I was awake in the middle of the night a couple days back, so I spent two hours and wrote a minimal version of Conway's Life in JavaScript. Lots of potential work to do, but probably better to just use Golly, if my renewed interest in Life lasts for long.

I wrote my first Life in 1976 or thereabouts, in Fortran on a PDP-11/10 under DOS-11. Its display was via three D/A converters driving X, Y, and brightness on a video monitor. It got slow and warbly when lots of cells were full, due to having to visit each cell for a while to pump the brightness, wait for the eye to see it, then go to the next cell.

Add comment   Edit post   Add post

Mac OS X 10.11.4 Beachball on Wake from Sleep

Submitted by Bill St. Clair on Sun, 03 Apr 2016 15:26:31 GMT

Since updating to 10.11.4 on my 2011 iMac, my machine often beachballs on wake from sleep. Sometimes it eventually stops beachballing, so that I can enter my password, but often not. I have held the power button for 8 seconds on a few occasions, to power down. Restarting takes a long time, since I work with a lot of open applications.

Today, I discovered that if I SSH into the Mac from my iPhone (I use the "Serverauditor" app for that), and kill the "distnoted" process, the beachballing stops immediately. I did that as follows:

$ ps aux | grep distnoted
_spotlight  1119 0.0 0.0 2470808 1968   ?? S  Thu08PM 0:00.24 /usr/sbin/distnoted agent
billstclair 5057 0.0 0.0 2434840  680 s008 S+ 11:07AM 0:00.00 grep distnoted
billstclair 5058 0.0 0.0 2470808 1284   ?? S  11:07AM 0:00.01 /usr/sbin/distnoted agent
$ kill -kill 5058

Note that I chose the Process ID (PID) for the /usr/sbin/distnoted process for my User ID (billstclair).

I haven't tried it yet, but I think this will work just as well, and doesn't require you to choose and type a PID:

$ killall -e -kill distnoted

Of course, this will only work if you enable "Remote Login" in System Preferences/Sharing, and have an SSH client on another computer in your network.

1 comment   Edit post   Add post

Google Authenticator, in Your Web Browser

Submitted by Bill St. Clair on Sun, 28 Feb 2016 12:02:39 GMT

In anticipation of version 2.1 of the SMF forum software, which supports two-Factor authentication, I have written, in a single JavaScript-heavy web page, a near-clone of the Google Authenticator smart phone app. This allows you to enter one or more secret keys for two-factor authentication, and get the time-varying passwords you need to log in. Some of the administrators for a forum I maintain don't have smart phones, so they'll need an alternative if they are to use two-factor authentication.

It should work with any web site for which Google Authenticator works, assuming your computer's time is properly synchronized, which most modern computer's are.

It is entirely contained in one HTML file, and all the computations are done locally on your computer by the JavaScript in that file.

Documentation included in the file.

GitHub link at the bottom for the programmers in the audience.

Add comment   Edit post   Add post

Another Old Friend

Submitted by Bill St. Clair on Thu, 25 Feb 2016 02:34:25 GMT

I field-stripped and cleaned another old friend today. No rust here either. God bless the Bullfrog company!

M1A Field-Stripped
Springfield M1A field-stripped and cleaned

Springfield M1A
Springfield M1A reassembled after cleaning

Add comment   Edit post   Add post

Firefox Discontinuing Tab Groups

Submitted by Bill St. Clair on Fri, 12 Feb 2016 14:21:42 GMT

I saw a notice in the upgrade notes today for Firefox 44.0.1 that as of version 45, they're discontinuing the "Tab Groups" feature. Oh, NOOOO! Mr. Bill. I currently have 78 pages open in 7 tab groups. Fortunately, there are a few options that the Firefox folks recommend, or you can do nothing, and Firefox will save your tab groups when you upgrade to version 45.

I decided to install the Tab Groups addon. It automatically converts your existing tab groups, and its user interface is indistinguishable, to me, from the old built-in functionality, except there is now a help page that allows you to save and restore your tab groups. In particular, if you forget to install the add-on before the feature disappears from the standard Firefox distribution, you can restore from the save that Firefox does when it destroys your tabs.

Worked for me. Tab groups safe from the evil decisions of the Firefox development team. :)

Add comment   Edit post   Add post

Barlow's Declaration Turns Twenty

Submitted by Bill St. Clair on Tue, 09 Feb 2016 11:53:05 GMT

Jan Haas of AP at Wired - Its Been 20 Years Since This Man Declared Cyberspace Independence - On 8 February, 1996, John Perry Barlow first published the Declaration of Independence of Cyberspace. It is as true, relevant, and important today as ever. Thank you, sir!

A Declaration of the Independence of Cyberspace
by John Perry Barlow

Governments of the Industrial World, you weary giants of flesh and steel, I come from Cyberspace, the new home of Mind. On behalf of the future, I ask you of the past to leave us alone. You are not welcome among us. You have no sovereignty where we gather.

We have no elected government, nor are we likely to have one, so I address you with no greater authority than that with which liberty itself always speaks. I declare the global social space we are building to be naturally independent of the tyrannies you seek to impose on us. You have no moral right to rule us nor do you possess any methods of enforcement we have true reason to fear.

Governments derive their just powers from the consent of the governed. You have neither solicited nor received ours. We did not invite you. You do not know us, nor do you know our world. Cyberspace does not lie within your borders. Do not think that you can build it, as though it were a public construction project. You cannot. It is an act of nature and it grows itself through our collective actions.

You have not engaged in our great and gathering conversation, nor did you create the wealth of our marketplaces. You do not know our culture, our ethics, or the unwritten codes that already provide our society more order than could be obtained by any of your impositions.

You claim there are problems among us that you need to solve. You use this claim as an excuse to invade our precincts. Many of these problems don't exist. Where there are real conflicts, where there are wrongs, we will identify them and address them by our means. We are forming our own Social Contract. This governance will arise according to the conditions of our world, not yours. Our world is different.

Cyberspace consists of transactions, relationships, and thought itself, arrayed like a standing wave in the web of our communications. Ours is a world that is both everywhere and nowhere, but it is not where bodies live.

We are creating a world that all may enter without privilege or prejudice accorded by race, economic power, military force, or station of birth.

We are creating a world where anyone, anywhere may express his or her beliefs, no matter how singular, without fear of being coerced into silence or conformity.

Your legal concepts of property, expression, identity, movement, and context do not apply to us. They are all based on matter, and there is no matter here.

Our identities have no bodies, so, unlike you, we cannot obtain order by physical coercion. We believe that from ethics, enlightened self-interest, and the commonweal, our governance will emerge. Our identities may be distributed across many of your jurisdictions. The only law that all our constituent cultures would generally recognize is the Golden Rule. We hope we will be able to build our particular solutions on that basis. But we cannot accept the solutions you are attempting to impose.

In the United States, you have today created a law, the Telecommunications Reform Act, which repudiates your own Constitution and insults the dreams of Jefferson, Washington, Mill, Madison, DeToqueville, and Brandeis. These dreams must now be born anew in us.

You are terrified of your own children, since they are natives in a world where you will always be immigrants. Because you fear them, you entrust your bureaucracies with the parental responsibilities you are too cowardly to confront yourselves. In our world, all the sentiments and expressions of humanity, from the debasing to the angelic, are parts of a seamless whole, the global conversation of bits. We cannot separate the air that chokes from the air upon which wings beat.

In China, Germany, France, Russia, Singapore, Italy and the United States, you are trying to ward off the virus of liberty by erecting guard posts at the frontiers of Cyberspace. These may keep out the contagion for a small time, but they will not work in a world that will soon be blanketed in bit-bearing media.

Your increasingly obsolete information industries would perpetuate themselves by proposing laws, in America and elsewhere, that claim to own speech itself throughout the world. These laws would declare ideas to be another industrial product, no more noble than pig iron. In our world, whatever the human mind may create can be reproduced and distributed infinitely at no cost. The global conveyance of thought no longer requires your factories to accomplish.

These increasingly hostile and colonial measures place us in the same position as those previous lovers of freedom and self-determination who had to reject the authorities of distant, uninformed powers. We must declare our virtual selves immune to your sovereignty, even as we continue to consent to your rule over our bodies. We will spread ourselves across the Planet so that no one can arrest our thoughts.

We will create a civilization of the Mind in Cyberspace. May it be more humane and fair than the world your governments have made before.

Davos, Switzerland
February 8, 1996

Add comment   Edit post   Add post

Hello Again Old Friend

Submitted by Bill St. Clair on Mon, 08 Feb 2016 20:02:10 GMT

I think it's been over three years since I took my Colt AR-15 out of the safe. I used to go to the range at least once a week, with the AR quite often, though it had to share time with the M1A, the 444 Marlin, and my two most fun rifles, a Henry lever-action .22 and a 44 Marlin. Hand-loaded cowboy-action .44 Magnum lead-bullet loads make that Marlin one sweet rifle to shoot.

But I stopped improving and lost interest. Also, ammunition got a lot more expensive. Well, for some reason I decided today to field strip, clean, and oil the AR. Not a speck of rust, thanks largely I think to the Bullfrog Rust Blocker Emitter in the safe.

I usually clean and lubricate with BreakFree CLP (Cleaner, Lubricant, Preservative). That may also share responsbility for the lack of rust. Sometimes I use Bullfrog Rust Hunter Gun Wipes.

I clean the barrels of my rifles with exclusively Hoppe's BoreSnake Rifle Bore Cleaners (which I forgot to put in the image below). Since I discovered them many years ago, I haven't used a regular cleaning rod. I use shotgun cleaning patches soaked with BreakFree to clean the outside, but the inside stays shiny with only BreakFree on the BoreSnake. And a softly-sharpened wooden dowel helps with the nooks and crannies.

Must be time to take this rifle to the range.

Click on either image for the full-resolution version.

Colt AR-15 field-stripped
Colt AR-15 field-stripped and cleaned

Colt AR-15
Colt AR-15 reassembled after cleaning

Add comment   Edit post   Add post