A Solution to the Five Weekends Problem in Common Lisp


I’ve been enjoying playing around with Rosetta Code problems lately. Here’s a solution I posted last week for the Five Weekends problem in Common Lisp:

  ;;; http://rosettacode.org/wiki/Five_weekends

  ;; Given a date, get the day of the week.  Adapted from
  ;; http://lispcookbook.github.io/cl-cookbook/dates_and_times.html

  (defun day-of-week (day month year)
          (encode-universal-time 0 0 0 day month year 0)

  (defparameter *long-months* '(1 3 5 7 8 10 12))

  (defun sundayp (day month year)
    (= (day-of-week day month year) 6))

  (defun ends-on-sunday-p (month year)
    (sundayp 31 month year))

  ;; We use the "long month that ends on Sunday" rule.
  (defun has-five-weekends-p (month year)
    (and (member month *long-months*)
             (ends-on-sunday-p month year)))

  ;; For the extra credit problem.
  (defun has-at-least-one-five-weekend-month-p (year)
    (let ((flag nil))
          (loop for month in *long-months* do
                   (if (has-five-weekends-p month year)
                           (setf flag t)))

  (defun solve-it ()
    (let ((good-months '())
                  (bad-years 0))
          (loop for year from 1900 to 2100 do
             ;; First form in the PROGN is for the extra credit.
                   (progn (unless (has-at-least-one-five-weekend-month-p year)
                                    (incf bad-years))
                                  (loop for month in *long-months* do
                                           (when (has-five-weekends-p month year)
                                             (push (list month year) good-months)))))
          (let ((len (length good-months)))
            (format t "~A months have five weekends.~%" len)
            (format t "First 5 months: ~A~%" (subseq good-months (- len 5) len))
            (format t "Last 5 months: ~A~%" (subseq good-months 0 5))
            (format t "Years without a five-weekend month: ~A~%" bad-years))))

(Image copyright gacabo under Creative Commons license.)

Emacs Compilation Mode Regexp for Perl 6

Stick this in your .emacs if you want Perl 6 support in Emacs’ compilation mode:

  (add-to-list 'compilation-error-regexp-alist 'perl6-stack-trace)
  (add-to-list 'compilation-error-regexp-alist-alist
               '(perl6-stack-trace .
                                   ("at \\([A-Za-z-_]+\\(\.p[l6m]\\)?\\):\\([[:digit:]]+\\)"
                                    1 3)))

I don’t know if this would be a good addition to perl6-mode, or if compilation mode regexps are supposed to live elsewhere.

If you like this sort of thing, see also: flycheck-perl6.

Statistics over Git Repositories with Scsh


Figure 1: A forest stream outside New Paltz, NY.

In this post I’ll share a scsh port of a nice shell script from Gary Bernhardt’s Destroy All Software screencasts. This is taken from season 1, episode 1 of the series 1.

The script is used to gather statistics on a git repository. You pass it a regex matching a filename, and it outputs a table showing how many lines of that type of file were included in each commit.

For example, I might want to see how the number of lines of documentation in Markdown files changed across commits:

$ repo-stats ".md$"
... snip! ...
52      c36cc6d First version of diff-checking code.
52      9ed53c3 Tweaks.
52      9e17d7e Add new service.
64      b293c3d Describe how to use the diffing code.
64      1886164 Update comments and documentation.
64      4a7ba26 Bump TODO prio.

The scsh code to do this is below; it’s a nearly 1:1 translation of Mr. Bernhardt’s bash code into scsh. It does differ in a few ways:

  • No dynamic/global variables: In the bash code there are variables being used inside functions that weren’t passed in as arguments to those functions. This is fine for small programs, but is probably not a Good Thing ™.
  • Since scsh is based on Scheme 48, we get a nice inspector/debugger for free.
  • At this program size, we don’t need to break out the Scheme 48 module system. However, if we wanted to integrate this scsh code cleanly with a larger system, we could do so fairly easily.
  • Something about how scsh is calling git and piping its output isn’t turning off git’s dumb (IMO) “I will behave differently depending on what kind of output I think I’m writing to” behavior. Therefore, unlike in Mr. Bernhardt’s example, we need to unset the GIT_PAGER environment variable.
  • Mr. Bernhardt used bash in his video due to its ubiquity. Scsh fails utterly in this regard, since almost no one uses it. However, that doesn’t really matter unless you need to distribute your code to a wider audience.2
  • Subjectively, Scheme is an immeasurably nicer language than whatever weird flavor of POSIXy sh is available.

Enough rambling, let’s have some code:

#!/usr/local/bin/scsh \
-e main -s

(setenv "GIT_PAGER" "")

(define (revisions)
  (run/strings (git rev-list --reverse HEAD)))

(define (commit-description rev)
  (run/string (git log --oneline -1 ,rev)))

(define (number-of-lines file-pattern rev)
   (| (git ls-tree -r ,rev)
      (grep ,file-pattern)
      (awk "{print $3}")
      (xargs git show)
      (wc -l))))

(define (main prog+args)
  (let ((pat (second prog+args))
        (revs (revisions)))
     (lambda (rev)
       (let ((column-1 (string-trim-both (number-of-lines pat rev)))
             (column-2 (string-trim-both (commit-description rev))))
         (format #t "~A\t~A~%" column-1 column-2)))



I feel like I should note for the record that:

  1. This is a legitimate, paid copy of Mr. Bernhardt’s videos that we’re working from.
  2. Although I’m only a few episodes into season 1, I am really enjoying the series and would recommend.

And if you do need to distribute your code to a wider audience, there is an easy way to dump a heap image that should be runnable by any other scsh VM of the same version. I’ve done this myself to distribute reasonably large/complex scripts to coworkers. I’m written a little scsh library to automate the process of installing an “app” in a heap image. I hope to write about it here soon.

Include Code Samples in Markdown Files



One useful feature that Markdown omits is any way to properly maintain formatted code samples in the text. Instead you have to indent your code samples “by hand”. This is easy to mess up, especially if you have a team of people all editing the same files.

Code indentation and formatting is an important issue if you are writing tech docs intended for engineers. It’s mostly about ease of readability. Badly formatted code is jarring to the eye of your reader and makes the rest of your documentation seem instantly suspect.

In this post I’ll share a technique (a script, really) that I’ve developed for “including” longer code samples into your Markdown documents from external files 1.


To understand the motivation for this technique, let’s look at some made-up code samples. If you already understand why one might want to do this, feel free to skip down to the code.

First up is the simple case: a code snippet that’s just a few lines long.

# Spaceship docking mechanism.

my $foo = Foo->new;

That wasn’t too bad. However, you may need a longer code sample like the one shown below which uses a lot of indentation. You really don’t want to be manually indenting this inside a Markdown file.

;; Ye Olde Merge Sort.

(define (merge pred l r)
  (letrec ((merge-aux
            (lambda (pred left right result)
              (cond ((and (null? left) (null? right))
                     (reverse result))
                    ((and (not (null? left)) (not (null? right)))
                     (if (pred (car left) (car right))
                         (merge-aux pred
                                    (cdr left)
                                    (cons (car left) result))
                         (merge-aux pred
                                    (cdr right)
                                    (cons (car right) result))))
                    ((not (null? left))
                     (merge-aux pred (cdr left) right (cons (car left) result)))
                    ((not (null? right))
                     (merge-aux pred left (cdr right) (cons (car right) result)))
                    (else #f)))))
    (merge-aux pred l r '())))

(define (merge-sort xs pred)
  (let loop ((xs xs)
             (result '()))
    (cond ((and (null? xs) (null? (cdr result))) (car result))
          ((null? xs) (loop result xs))
          ((null? (cdr xs))
           (loop (cdr xs) (cons (car xs) result)))
           (loop (cddr xs)
                 (cons (merge < (first xs) (second xs)) result))))))

Code to solve the problem

An easier way to do this is to “include” the code samples from somewhere else. Then you can maintain the code samples in separate files where you will edit them with the right support for syntax highlighting and indentation from your favorite code $EDITOR.

The particular inline syntax I’ve settled on for this is as follows:

{include code_dir/YourFile.java}

Where code_dir is a directory containing all of your code samples, and YourFile.java is some random Java source file in that directory. (It doesn’t have to be Java, it could be any language.)

The include syntax is not that important. What’s important is that we can easily maintain our code and text separately. We can edit Markdown in a Markdown-aware editor, and code in a code-aware editor.

Then we can build a “final” version of the Markdown file which includes the properly formatted code samples. One way to do it is with this shell redirection (see below for the source of the expand_markdown_includes script):

$ expand_markdown_includes < your-markdown-file.md.in > your-markdown-file.md

This assumes you use the convention that your not-quite-Markdown files (the ones with the {include *} syntax described here) use the extension .md.in.

Another nice thing about this method is that you can automate the “include and build” step using a workflow like the one described in Best. Markdown. Writing. Setup. Ever.

Finally, here is the source of the expand_markdown_includes script. The script itself is not that important. It could be improved in any number of ways. Furthermore, because it’s so trivial, you can rewrite it in your favorite language.

#!/usr/bin/env perl

use strict;
use warnings;
use File::Basename;
use File::Slurp qw< slurp >;

my $input_file = shift;
my $input_pathname_directory = dirname( $input_file );

my @input_lines = slurp( $input_file );

my $include_pat = "{include ([/._a-z]+)}";

for my $line ( @input_lines ) {
  print $line unless $line =~ m/$include_pat/;

  if ( $line =~ /$include_pat/ ) {
    my $include_pathname = $1;
    my $program_file = build_full_pathname($input_pathname_directory,
    my @program_text = slurp( $program_file );
    for my $program_line ( @program_text ) {
      printf( "    %s", $program_line );

sub build_full_pathname {
  my ($dir, $file) = @_;
  return $dir . '/' . $file;



While I was writing this I decided to do a bit of web searching and I discovered this interesting Stack Overflow thread that mentions a number of different tools that solve this problem. However I rather like mine (of course!) since it doesn’t require any particular Markdown implementation, just the small preprocessing script presented here.

(Image courtesy Claudia Mont under a Creative Commons license.)

How to Write Documentation for People that Don’t Read

These are my notes from Kevin Burke’s talk at the 2015 Write the Docs conference in Portland, Oregon. Any brilliant ideas in the below text should be attributed to Mr. Burke. Any errors, omissions, or misrepresentations are mine. You can also
watch a video of Mr. Burke’s talk.

Kevin Burke

Eye scans show that users read in an F-shaped pattern, from top left down the left side.

Users don’t look at big blocks of text.

Do this:

  • meaningful text and images
  • starts of paras
  • links
  • bullets

Use bulleted lists, not walls of text.

Bulleted lists perform 125% better (2.25x) than paragraphs for getting people to retain information.

Use the Markdown format for Github READMEs so you can have bold, etc. formatting.

People skip things that look like ads; this means they SKIP BIG RED CALLOUTS.

(NTS: we use this a ton, think about revisiting)

Text can’t be too wide (shows JIRA’s REST API docs as bad example)

Text should be 65-90 characters wide, like books.

(NTS: “information scent”)

Biggest paragraph from Github thing has 2 sentences.

Users are also bad at searching; they also don’t try other queries (“one and done”).

There is often benefit to having subtly different variants of questions around, as people tend to ask and search using different words.

People searched for client SDKs at Twilio as:

  • helper libraries
  • client SDKs
  • API SDKs
  • library bindings
  • language-specific wrappers

Example question: “how do I forward a number to my cell phone?”

Meanwhile, the docs said: “How to do everything with an incoming call”

A user won’t associate this; it’s better to have targeted pages.

No one reads anything above or below code snippets.

Code snippets can often have implicit configuration (env vars, library requires, etc.).

There can also be typos in code snippets.

A lot of people are not familiar with pip/gem/etc., so you have to help them figure out how to use peripheral tools.

Twilio has JS that fills in snippets with your actual credentials so when you copypasta a code sample it’s runnable.

People copy the dollar signs from bash snippets.


every user failure is a potential job to be done

Say you get an SSL error authenticating to the Twilio API.

What are you going to do? Google it!

None of the top google results are your actual docs (SO, blogs, forums, etc.)

(NTS: if your stuff isn’t on google, it doesn’t exist.)

transgression: docs behind a wall

At one point 50% of twilio traffic was from Google.

If you have a login wall, you’re throwing away 50% of your traffic.

transgression: providing pdfs

PDFs are not searchable.

WikiHow stole traffic from Twilio!

If users get an error message from you, put that exact message in your docs.

Error messages should be copypastable into the goog.

Validation as documentation; maybe we can improve the error message.

Suggestion: put the user’s input back into the error message string so your user can see what they passed in to cause the error.

Strings are easy to find/change.


  • break up text
  • first 3-5 words of every para
  • more links
  • care about SEO
  • your docs should always win on google
  • make error messages explain how to fix the problem
  • better yet, solve the problem for the user

Reasons to Recommend Common Lisp

On Reddit, /u/rhabarba asks: Should I learn (Common) Lisp? Here’s my reply:

I am a technical writer and “hobbyist” programmer who does some unofficial programming at work to automate documentation things. To give you a sense of my language background, I enjoy programming in Perl, Python, Scheme, and Common Lisp.

Reasons to recommend Common Lisp include:

  • In many ways, it’s a superset of the other languages I mentioned: you can “script” with regular expression and filesystem support, and you can also write larger programs using built-in OO that’s still more advanced than the built-in Perl or Python stuff.
  • Multi-paradigm: you can write code in whatever style you want to solve your problem. You only use OO if you want to, you’re not forced by the language. Functional style is there for you, especially via libraries. You can also be imperative and bash as much state as you want. Almost any type of code you might want to write can be (probably has been?) written in Common Lisp. There’s a lot of room to grow as you learn more.
  • Dynamic, interactive, and inspectable: redefine almost anything on the fly at the REPL, watch those changes get picked up by the rest of your system as it runs. This is true for running web servers, whatever. The debugger and inspector available via SLIME in Emacs is also better than anything else I’ve used in other languages.
  • Multiple good implementations to choose from; there are several fast “native” compilers, several portable interpreter-based implementations. If you write portable code you can run on many different implementations, so you can mix and match depending on what’s easiest to install or use for your needs.
  • Quicklisp lets you install any of 1200* libraries, very easily. You’ve got all the basics: HTTP clients and servers, JSON, XML, and Markdown parsers, and lots more advanced stuff too.
  • 25 year old code that does advanced, weird, or just cool things still works fine. It just runs way faster now.
  • Good books: ‘Paradigms of Artificial Intelligence Programming’ by Peter Norvig, ‘Object-Oriented Programming in Common Lisp’ by Sonya Keene, and many others.

Finally, I have been able to write programs to do “harder” things in Lisp than I have in other languages, even though I’m not really a programmer or “engineer” or whatever title you prefer. I think the simple list data structure is a great way to bootstrap a prototype of your program, and it encourages data-structure thinking rather than “stringy” thinking as some languages do. That said, I use a lot of languages to get my work done, so it’s not a religion or anything.

Good luck!

The Sentinel File Pattern

In this short essay I’ll describe the “sentinel file” pattern, which I recently used when writing a command-line tool to use at $WORK for interacting with our web API.

The essence of the sentinel file pattern is that you use a certain file’s last-modified time as a record against which you compare other time-based values.

It is useful in many contexts, such as software builds; in the context of web APIs, it can be used to track whether you will need to reauthenticate with the API before you fire off a bunch of API calls.

The recipe is essentially this:

  • Update a sentinel file F‘s timestamp at time T.
  • When you are about to take an action such as make an API call, see if the current time, T’, is greater than the timeout value of your web API, V, plus the sentinel file’s existing timestamp T.

We can translate this into Scheme as follows (this is scsh, to be exact), where:

;; F = sentinel-file
;; T = (file-last-mod sentinel-file)
;; T' = (time)
;; V = api-timeout-value

(define (sentinel-expired? sentinel-file)
   (> (time)
      (+ (file-last-mod sentinel-file) api-timeout-value)))

Note that TIME and FILE-LAST-MOD are part of the scsh POSIX API.

This pattern is much more efficient than storing some kind of “am I logged in?” value in a JSON/YAML/XML/s-expression config file that has to be read in and parsed on every invocation and written out from time to time.

I debated whether to write about this simple technique at all because it seems like an old trick that many people know. However, I’m going to assume that I am not unique, and that there are lots of people out there who could benefit from using this technique when the right situation arises.