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

My resumé is at

ZAP Meme

Submitted by Bill St. Clair on Thu, 18 Apr 2019 05:25:32 GMT is a meme maker written in Elm.

It's open source, with a link at the bottom of the page. It uses <svg> to layout the meme, and converts to JPEG or PNG for saving.

It stores meme and images (as data:// URLs) in your browser's localStorage database. They may be exported as JSON and imported into another browser.


Add comment   Edit post   Add post

stackoverflow April Fools 2019

Submitted by Bill St. Clair on Mon, 01 Apr 2019 07:57:03 GMT

For April Fools Day, 2019, stackoverflow put fairy dust on every question page, and had a definite retro look.

I saved the fairy dust, and the ASCII art HTML comment at

Also see Announcing the Stack Overflow Time Machine.

Add comment   Edit post   Add post

Image Sizing in elm-ui

Submitted by Bill St. Clair on Thu, 06 Dec 2018 03:53:36 GMT

I've been using Matthew Griffith's wonderful elm-ui package to make the user interface for GabDecker, a TweetDeck-like web app I'm building for I've had inline images since the beginning, scaled to fit the column width. Today I made clicking on one of those image open a dialog with the full-size version, scaled down if necessary to fit the available space.

elm-ui eschews CSS in the source code, usually making it much easier to get what you want. But in this case, I was NOT getting what I wanted, so I wrote my own CSS, and learned about the object-fit property in the process.

Here's the code that's now running:

imageDialog : String -> Model -> Element Msg
imageDialog url model =
        maxw =
            9 * model.windowWidth // 10

        maxws =
            String.fromInt maxw ++ "px"

        maxh =
            9 * model.windowHeight // 10

        maxhs =
            String.fromInt (9 * model.windowHeight // 10) ++ "px"
        -- This is black magic.
        -- It took much play with the CSS to get it right.
        [ centerX
        , centerY
        [ standardButton "" CloseDialog <|
                [ "object-fit" "contain"
                , "max-width" maxws
                , "max-height" maxhs
                , "border" "2px solid black"
                , "width" "auto"
                , "height" "auto"
                , Attributes.src url
                |> Element.html

Add comment   Edit post   Add post


Submitted by Bill St. Clair on Wed, 19 Sep 2018 10:04:00 GMT

"APL is like a diamond. It has a beautiful crystal structure; all of its parts are related in a uniform and elegant way. But if you try to extend this structure in any way - even by adding another diamond - you get an ugly kludge. LISP, on the other hand, is like a ball of mud. You can add any amount of mud to it and it still looks like a ball of mud." -- Joel Moses

Add comment   Edit post   Add post

How do I run elm-test in Elm 0.19?

Submitted by Bill St. Clair on Mon, 17 Sep 2018 00:24:33 GMT

This is a FAQ, so I'm making a blog post to answer it.

elm-test is still in beta for Elm 0.19. To install it:

$ npm install -g elm-test@beta

The tests directory no longer needs an elm-package.json file (nor does it need elm.json).

Your top-level elm.json file needs to include the following:

    "test-dependencies": {
        "elm-explorations/test": "1.0.0 <= v < 2.0.0"

The easiest way to get it there is with elm-test itself. The following will create a tests directory, containing an example test file, Example.elm, and will add test-dependencies to elm.json.

$ elm-test init

That's it. There is not yet support for running elm-test in the browser, nor is there support for testing DOM output.

billstclair/elm-localstorage is configured with a tests directory to test its JSON encoders and decoders: To run the tests:

$ git clone
$ cd elm-localstorage
$ elm-test

Add comment   Edit post   Add post

CLtL2 on Kludges

Submitted by Bill St. Clair on Sat, 15 Sep 2018 11:26:58 GMT

Lest we believe we're building amazing systems as programmers, always remember that Common Lisp the Language, Second Edition, by Guy L. Steele, Jr. (CLtL2), has an index entry for "kludges", saying that they appear on pages 1 to 971. Page 972 is the "References" section.


Add comment   Edit post   Add post

iPhone Xs Pricing

Submitted by Bill St. Clair on Wed, 12 Sep 2018 19:22:55 GMT

From the pages.

Watch the 12 September keynote.

Prices (in parentheses) are per month for Apple financing.

Model64 gig128 gig256 gig512 gigOrderShip
iPhone Xs:$999
Xs Max:$1099
iOS 12:Free9/17

Add comment   Edit post   Add post

New Elm Package: billstclair/elm-port-funnel

Submitted by Bill St. Clair on Sat, 08 Sep 2018 20:23:12 GMT

I just published version 1.0.0 of billstclair/elm-port-funnel. It enables communicating with ALL of your custom JavaScript through a single Cmd/Sub port pair. It takes care of loading the JavaScript code, which you simply drop in a directory and add to a list, and dispatching messages from your Elm code. It allows pure-Elm simulators, to make testing your app easy in `elm reactor`.

The example is live at

I will now begin work at converting my existing port modules to funnels. Those will be major version bumps, but will make them much easier to combine.

Thank you to Murphy Randall (@splodingsocks) for the basic idea that I generalized to create this package.

Add comment   Edit post   Add post

Building the Elm compiler

Submitted by Bill St. Clair on Fri, 07 Sep 2018 07:01:51 GMT

I learned how to build the Elm version 0.19 compiler, in an effort to get it to provide full backtraces of a bug I was tickling. I failed at getting the full backtraces, but I succeeded in adding some debugging output. Anyway, here's how to do it.

First, you need to install Haskell on your machine. You need version 8.2.2 for the Elm 0.19 compiler.

Then do the following:

$ git clone
$ cd compiler
$ cabal sandbox init
$ cabal install

The Elm executable will be in .cabal-sandbox/bin/elm.

The first build takes a while, as it needs to download and build all the dependenies. After that, it gets faster. cabal sandbox delete lets you start over.

After making changes to the source, run cabal install again, and it will compile only the changed files and files that depend on them.

To build the entire Haskell stack, with stack backtraces enabled, from @mfeineis on the Elm Slack channel (I haven't tried this):

Init with stack:

$ stack init --resolver lts-11.20

Add options in elm.cabal:

Executable elm
    if flag(dev)
        ghc-options: -O0 -Wall -Werror -rtsopts -eventlog

Build with stack:

$ stack build --flag elm:dev --profile

Run with RTS options:

$ elm make ./src/Main.elm \
   --output=./dist/app.js +RTS -xc -lu -RTC \

Add comment   Edit post   Add post


Submitted by Bill St. Clair on Wed, 05 Sep 2018 02:49:40 GMT

Elm 0.19 shipped without an upgraded version of the elm-lang/websocket package. Since I use WebSockets for my games, I badly miss it. So I wrote my own, billstclair/elm-websocket-client. Since it uses ports to do the work that isn't in Elm itself, it needs a little more help from the user than Evan's package, but not that much.


Add comment   Edit post   Add post