Lisplog

Blogging in Lisp

Search

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 github.com/billstclair/Lisplog

I'm looking for work. My resumé is at lisplog.org/resume.html

Elm Tutorial on Commands, Subscriptions, and Ports

Submitted by Bill St. Clair on Thu, 27 Oct 2016 01:10:42 GMT

I wrote an Elm Tutorial, and posted it at Steemit: Elm: Commands and Subscriptions and Ports. Oh My! It's also in my Steemit archive on GitHub.

Add comment   Edit post   Add post

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.

Kakuro-Dojo.com

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 Kakuro-Dojo.com 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.

Yay!

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 EtWoF.com. 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 kakuro-master.com 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
                  z
                else
                  foo' (y-1) (z+1))
  in
      foo'

bar : Int -> Int -> Int
bar y z =
  if y <=0 then
    z
  else
    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) {
			foo$:
			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) {
		bar:
		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
    z
  else
    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 lisplog.org/print-ihftp.hs or display it at lisplog.org/print-ihtfp.hs.txt. 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 github.com/tekezo/Karabiner-Elements. 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