Skip to content

Instantly share code, notes, and snippets.

View jackrusher's full-sized avatar

Jack Rusher jackrusher

View GitHub Profile
@jackrusher
jackrusher / gist:5139396
Last active August 6, 2026 15:08
Hofstadter on Lisp: Atoms and Lists, re-printed in Metamagical Themas.

Hofstadter on Lisp

In the mid-80s, while reading through my roommate's collection of Scientific American back issues, I encountered this introduction to Lisp written by Douglas Hofstadter. I found it very charming at the time, and provide it here (somewhat illegally) for the edification of a new generation of Lispers.

In a testament to the timelessness of Lisp, you can still run all the examples below in emacs if you install these aliases:

(defalias 'plus #'+)
(defalias 'quotient #'/)
(defalias 'times #'*)
(defalias 'difference #'-)
@jackrusher
jackrusher / webdav.clj
Last active March 20, 2026 08:29
A minimal webdav server/synthetic filesystem that works with JVM Clojure and babashka. See comments for instructions!
(ns webdav
(:require [clojure.string :as str]
[clojure.data.xml :as xml]
[org.httpkit.server :as hk-server]))
;; add the XML namespace that we'll use later
(xml/alias-uri 'd "DAV:")
(defn dissoc-in
"Should be in the standard library..."
@jackrusher
jackrusher / abstract.md
Last active November 3, 2025 16:13
An old programming koan.

The venerable master Qc Na was walking with his student, Anton. Hoping to prompt the master into a discussion, Anton said "Master, I have heard that objects are a very good thing - is this true?" Qc Na looked pityingly at his student and replied, "Foolish pupil - objects are merely a poor man's closures."

Chastised, Anton took his leave from his master and returned to his cell, intent on studying closures. He carefully read the entire "Lambda: The Ultimate..." series of papers and its cousins, and implemented a small Scheme interpreter with a closure-based object system. He learned much, and

@jackrusher
jackrusher / triples.clj
Last active February 18, 2025 16:40
A super simple example of inference from a set of triples.
;; knowledge representation, syllogism via knowledge base
(defrecord Triple [subject predicate object])
(def knowledge-base
[(Triple. :Socrates :is-a :Greek)
(Triple. :Greek :is-a :human-being)
(Triple. :human-being :has-property :mortal)])
(defn collect-predicate-along-axis [kb subject predicate axis]
@jackrusher
jackrusher / trinity.js
Created March 29, 2021 09:23
A fast, minimal JS triple store implementation in ~70 lines of code
// three indices to efficiently support all lookups
function createDB() {
return {eav: new Map(),
ave: new Map(),
vea: new Map()};
}
function addToIndex(xs, x, y, z, triple) {
let ys = xs.get(x);
if(ys == undefined) {
@jackrusher
jackrusher / negative-space.clj
Last active October 15, 2024 10:38
Clojure, Haskell and OCaml implementations of the same algorithm, which is a negative space finder for a very constrained situation involving nested rectangles. For those interested in a more comprehensive take on these relationships (using scheme rather than clojure), see: http://lambda.jimpryor.net/translating_between_ocaml_scheme_and_haskell/
(def parent {:x1 0 :y1 0 :x2 600 :y2 400})
(def rs [{:x1 0 :y1 0 :x2 300 :y2 200 }
{:x1 0 :y1 200 :x2 300 :y2 400 }])
(defn negative-space [parent rs]
(let [x (apply max (map :x2 rs))
y (apply min (map :y1 (filter (comp (partial = x) :x2) rs)))]
{:x1 x :y1 y :x2 (parent :x2) :y2 (parent :y2)}))
(negative-space parent rs)
@jackrusher
jackrusher / logic-triples.clj
Created August 30, 2013 06:27
Transitive properties in a toy triple store using Clojure's core.logic.
(defrel triple ^{:index true} s ^{:index true} p ^{:index true} o)
(facts triple [[:Berlin :is-a :city]
[:city :is-a :permanent-settlement]
[:Berlin :part-of :Germany]
[:Germany :part-of :EU]
[:EU :part-of :Eurasia]
[:Eurasia :part-of :Earth]])
(run* [q] (triple q :is-a :city))
;; If you have to do any sophisticated time calculations, including
;; calendrical stuff (day of week, &c), you should obviously use a
;; library to handle that stuff. However, if you only need some simple
;; things it can be very useful to leave ISO 8601 formatted dates in
;; string representation...
;; gold/oz 1995-01-03 to 2016-11-10
(def data
(->> (slurp "https://www.math.ttu.edu/~atrindad/tsdata/FTSdatasets/Gold.csv")
clojure.string/split-lines
@jackrusher
jackrusher / svg-preview.el
Created February 19, 2016 11:53
Automatically updating SVG preview in emacs
;; I wrote up a quick + dirty function to get me a preview of the SVG I'm editing:
(defun refresh-svg-preview ()
(interactive)
(let ((oldbuf (current-buffer)))
(with-current-buffer (get-buffer-create "*svg-preview*")
(fundamental-mode)
(erase-buffer)
(insert-buffer-substring oldbuf)
(image-mode))))
@jackrusher
jackrusher / seq-primer.clj
Created June 1, 2021 12:55
Condensed visual tutorial in #Bauhaus style for a subset of the #Clojure seq API (inspired by similar JS tweets)
(def ■ '■)
(def ▲ '▲)
(def ● '●)
(first [● ■ ▲]) ;
(second [● ■ ▲]) ;
(nth [● ■ ▲] 2) ;
(rest [● ■ ▲]) ; (■ ▲)
(last [● ■ ▲]) ;
(butlast [● ■ ▲]) ; (● ■)