Johan Hidding's homepage
AboutOver the past years I have develloped some things. Most of them are quite modest. I gathered here some tools and thoughts on programming.
Conan - Cosmology tool chain
My research focusses on formation of structure in the Universe. This requires solving the Poisson equation
in different elegant and less elegant ways. I have made some of my codes public. These are available on github, and can be downloaded by typing:
git clone https://github.com/jhidding/conan.git
in a command shell.
SCAM - Schemes for Artistic Model rendering
Scam is a set of Scheme modules for making publication quality printable 3D graphics. The name might be a bit daunting, but it falls in a rich tradition among Schemers and Racketeers. One example of graphics created with SCAM is from my own paper on the Zeldovich approximation.
The most unique feature of SCAM may be that it is capable of rendering simplicial complexes in Aitoff-Hammer projection. Here is an example from real life, a rendering of structures at distances between 10 and 20 Mpc, aimed at the Local Void (click to enlarge).
Implementations are available in both Scheme (prototype) and C++, by typing:
git clone https://github.com/jhidding/scam.git
in a command shell. More information can be found at the dedicated github page.
Fancy shell (bash)One of the most annoying things when compiling C++ code are the heaps of error messages. The second most annoying thing is that you can't find where you typed the compile command, that is, where your last zillion of unreadable template errors end and the next begin. That why I have a shell prompt that draws a nice coloured bar across the width of the terminal. The code that I made to get it is the ugliest python + bash hack that I've ever seen. It starts with a nice module that controls the terminal:
case "$TERM" in xterm*|x-term*) export TERM="xterm-256color" PS_COLOR=`~/bin/rand_color.py` PS1="\[\`bar.py \$PS_COLOR \$?\`\]`ps1.py \$PS_COLOR`" ;; *) PS1="[\[\e[1m\]\#\[\e[m\]]-[\[\e[32m\]\u@\h\[\e[m\]]-[\[\e[1;34m\]\w\[\e[m\]$ " ;; esacThe \[ thingies make sure that bash does not count terminal escape sequences as adding to the total width of the prompt, bash does some bookkeeping to that account. This entire thing could probably be hugely improved by using $(..) in stead of backtics, but I never got round to fixing that.
make (bash script)
I don't like make. Other people don't like make too. So they build automake. Which is a tool to generate make-files. This is a strategy that doesn't agree with me. So at some point when my C++ projects grew bigger and bigger, I created an alternative in pure bash.
I started out programming by coping GW-BASIC listings from the forgotten Dutch magazine called "WeetIk", and still remember feeling as if I performed a piece of magic. Ever since then part of the pleasure derived from programming, is trying to recall this same feeling of wizardry. Remember the moment that Sussman puts on his fez in the lecture where he derives the Scheme interperter from within Scheme. If any function truly embodies the magic that is involved here, it is the y-combinator. I write it with a small letter y, so it is a λ upside down.
In most languages, calling a recursive function means that you store the function in some location with a name. When you need to make the recursive call, you reference the name and get back the function. The name externalises the concept of self. Moreover, this implies the existence of an machine outside the function that has a concept of time. First we create the function, in which it calls a name; then we assign this function to this name. Only then does this function do what it is designed to do. The y-combinator circumvents this neccesity. It allows for the definition of recursive functions in a pure functional environment, that is, without the concept of time. The y-combinator takes a non-recursive function, and tells this function who it is, giving it a name that only this function knows. The y-combinator is like a mirror, granting the function a soul. Ok, that's enough with the silly poetry...
From the "Why of Y" we learn that we can write the factorial function as
(define factorial (lambda (h) (lambda (n) (if (< n 2) 1 (* n (h (- n 1)))))))And the y-combinator itself can be defined as
(define y (lambda (f) (define g (lambda (h) (lambda (x) ((f (h h)) x)))) (g g)))I'd like to be able to reduce this definition to a combination of higher order functions. Here Scheme poses us with a problem since there's no higher order way of delaying the evaluation of (f (h h)). We could use a form of delay, but this is neccesarily defined as a syntax macro, and those are not first class objects in Scheme. But Kernel can do the job. Fortunately I have a Kernel implementation at my disposal (see below). The following code runs correctly, even in the current crippled version of Scarlett.
($define! $delayed ($vau (f) e ($lambda X (eval [f . X] e)))) ($define! self-apply ($lambda (f) (f f))) ($define! foldr ($lambda (f lst start) ($define! foldr' ($lambda ((x . xs) x0) ($if (nil? xs) (f x x0) (foldr' xs (f x x0))))) (foldr' (reverse lst) start))) ($define! id ($lambda (x) x)) ($define! compose-2 ($lambda (f g) ($lambda args (f (g . args))))) ($define! compose ($lambda F (foldr compose-2 F id))) ($define! y ($lambda (f) (self-apply (compose $delayed f self-apply)))) ($define! f (y ($lambda (h) ($lambda (n) ($if (< n 2) 1 (* n (h (- n 1)))))))) (display (f 10) "\n")I think this is pretty cool. Of course in a lazy language like Haskell, the y-combinator looks even more appealing. Let's read this up loud: take a function f, given a function previously called h, apply h to h, apply that to f, but don't evaluate the result just yet. Out we get a function, previously called g, that we apply to itself, thus becomming h, the snake biting its tail. The nasty thing is that it is increddibly hard to reverse engineer what this function actually does.