A coder's scratchpad

Articles covering programming, design and leveraging technology to one's advantage

If there's one thing that defines how I work, it's that I'd rather deal with hard numbers than trust my hand at drawing things. The only creative software I've ever had success with is FreeCAD, because it lets you sketch out drawings and then constrain them to specific sizes. Unfortunately Emacs doesn't have a wallpaper-mode that I know of.

I like my wallpapers simple, and with minimal distractions. A solid background, with a small pattern of box-shadowed cubes in the top-right. Here's an example, scaled down slightly. I made the original in Inkscape, and spent far too much time making something so simple.

Coding a solution

FreeCAD is a parametric modeller. It's shapes are defined by easily adjustable numbers. The most touted example is if you model a wheel, and you want to adjust the number of spokes in that wheel, you change the spoke number. You don't have to worry about remodelling anything, because you told FreeCAD to repeat a shape around a given axis, and all you're doing is telling it to add more of that shape. I decided to take that idea and use it to make a small program to generate myself a parametrically defined wallpaper. You can find the result here

The first thing I did was define the parameters. I'm a Racket guy, so I did so in an s-expression:

(define options
  `((width . 1920) ; screen width
    (height . 1080) ; screen height
    (horizontal-margin . 0) ; push pattern to left this much
    (vertical-margin . 0)) ; push pattern down this much

; Usage example
(assoc 'width options)
; = (width . 1920)

(cdr (assoc 'width options))
; = 1920

This defines a variable called 'options' as a list of lists containing key-value pairs. We've got keys to control the size of the resulting wallpaper, and keys to move the pattern in the top-right away from the sides a bit if they get covered by a bar or dock. How convenient.

From there, I followed the following algorithm: – Draw the background as a solid rectangle of defined width and height – Draw a single cube – Draw a cube under that cube to make a drop shadow – Stick the cubes together to make the pattern – Put this pattern on the background, taking the margins into account – Output as a .png

Quirks and Considerations

Every procedure in the code related to drawing takes the options variable as an argument. This is less efficient, because every called procedure has to look up the values they care about, but it means every part of the drawing process can be run independently just by giving it the list of options. The entire thing runs in a second or two anyway, so this isn't much of a concern.

Racket's pict library defines a (freeze _) procedure, which takes a generated pict and turns it into a bitmap. This means that the program only has to generate the pict once, after which it just reuses the result.

The most annoying part of coding something involving colour is the difference between British English and American English. I decided to use the American spelling throughout the code, because having a color function adjust colours would be too confusing.

Improvements

Once I had the wallpaper generator working, I exposed more of it to the options variable. I added the ability to adjust the opacity of the shadows, the size of the cubes, the size of the gap between the cubes and the colour palette.

The colour palette was the most interesting one. I 'borrowed' my colours from Google's Material Design color palettes, but they define the colours in the more common #rrggbb format, and Racket only accepts colours as a list of 3 decimal numbers. I got fed up of using KCalc to manually convert each individual value to Racket's format, so I wrote this:

(define (->rgb s)
  (list
   (string->number (substring s 1 3) 16)
   (string->number (substring s 3 5) 16)
   (string->number (substring s 5 7) 16)))

; Usage example
(->rgb "#ffebee")
 ; = (255 235 238)

Conclusion

The wallpaper generator was a very interesting project to work with. It isn't the most advanced idea to implement, but it was fun to come up with and is convenient to use. Perhaps one day I'll write one that can output more than one pattern, but I'm satisfied with the results for now.

Let's start with the idea of an associative list. An alist is basically a list of lists, where the first value of each inner list is a key and the second is a value. Here are a few alists, in different langauges:

[["name", "foo"], ["occupation", "bar"], ["age", 20]] #Python
'((name . "foo") (occupation . "bar") (age . 20)) ; Racket

Why would you want to do this when dictionaries are so convenient? You wouldn't. Alists predate dictionaries. They're old, and you'll generally find something better. That said, they're a convenient tool to reach for when using Lisp-based languages, and if you're recursively acting on key-value pairs they should be more efficient than hash tables.

First, let's start with a few procedures to manipulate alists.

(assoc key alst)

Assoc takes an alist named alst, and a symbol named key (Note: symbols are like enums, but you don't need to pre-define them). If it finds a key-value pair with the same key, it returns that. If not, it returns a boolean False.

(define (alist-delete alst key)
  (filter-not (lambda (x) (equal? (car x) key)) alst))

This is a procedure made to return a new alist without the given key. It effectively deletes that key-value pair from the alist. We have to define this, because as far as I can tell Racket does not have this in it's standard library.

(define (alist-add alst pair)
  (if (assoc (car pair) alst)
      (alist-add (alist-delete alst (car pair)) pair)
      (cons pair alst)))

This procedure returns a new alist, and adds a new pair to it. If the given pair already exists, it overwrites the pair previously in the alist. We overwrite the previous pair by adding it to a version of the alist with that pair deleted.

Now let's make an alist constructor, so we can guarantee any alist made with it will have specific values:

(define (person #:x x #:y y #:name name)
  `((x . ,x)  (y . ,y) (name . ,name)))

This procedure definition uses keywords, so you don't have to remember the order of it's arguments. It returns an alist representing a person, with x and y coordinates and a name.

My goal is to make a procedure that takes an alist of directions, and a person, and make them move in those directions. Here it is:

(define (parse-instructions instructions person)
  (if (empty? instructions)
      person
      (let* ((todo (car (car instructions)))
            (amount (cdr (car instructions)))
            (move-person
             (lambda (key operator)
               (alist-add person
                          (cons key
                                (operator
                                 (cdr (assoc key person))
                                 amount))))))
        (parse-instructions
         (cdr instructions)
         (match todo
           ('up    (move-person 'y +))
           ('down  (move-person 'y -))
           ('left  (move-person 'x -))
           ('right (move-person 'x +)))))))

That's a pretty spicy procedure. Let's break it down.

The procedure takes an alist of instructions and a person. The first thing it does is to check whether the alist of instructions is empty. If it is, it gives us the person.

If the alist of instructions contains instructions, it skims the first instruction off the top of the alist, moves the person by said first instruction, and does everything all over again with the rest of the instruction alist.

This is a recursive procedure. It runs itself, but every time it does so it removes the instruction it just did. Eventually the list of instructions will empty, which is why the first thing it does is check whether the instruction list is empty.

While writing the procedure, I noticed that I was copy-pasting code for each instruction. I grouped the copied code into a procedure named move-person, and it has made the code easier to read. It takes a key ('x or 'y) and an operator (+ or –) and moves the key coordinate by adding to or subtracting from it. Essentially it abstracts the movement into “When you go left you subtract from the x axis”, and “when you go up you add to the y axis”, which is pretty neat.

Let's put it to the test.

(define my-instructions
  '((up . 10)
    (left . 3)
    (up . 3)
    (right . 15)
    (down . 2)))

(define my-guy
  (person #:x 0 #:y 0 #:name "foo"))

(parse-instructions my-instructions my-guy)

-> '((y . 11) (x . 12) (name . "foo"))

When I'm on the bus, or on my break at work, I try to get some coding practice on my phone. It isn't ideal, but a bit of tinkering here and there lets me learn more about the languages I use, and can lead to coming up with small programming projects.

First of all, I use Android. I'm not a fan of either popular phone OS, but if given the opportunity to strip Android down to it's bare essentials I'll take it. From there I install the terminal environment Termux and the Hacker's Keyboard (both available on the F-Droid store), and then I install the programming languages I want in Termux itself, and I'm good to go.

My favourite language to play around with is Racket, but that's because I already use Racket everywhere else. It has an interpreter to see your results in real time, it has plenty of built-in functions so you don't have to key out extra functions, and it's easily available through Termux's repos. So far I've built one application through playing with Racket on my phone, an Islamic prayer times calculator that grabs information from the AlAdhan API and presents it in the terminal. I am currently playing around with a program to generate Markdown, though I don't expect it to become anything fancy.

I've also had fun working with more unorthodox languages, like Forth. Working within the limits of a language so different from ones I'm used to is a puzzle in itself. I hope to start experimenting with Rust, Prolog and Perl6 in the future.

The fact that Termux allows users to write their own command line applications is appealing to me, because it means I can develop “apps” on the device itself, without knowing any Android specifics. It's a great time-waster, and allows me to be ever so slightly more productive.

Last org-mode article for now, I promise.

Let's say you're planning a birthday party. We'll start with a checklist.

- [/] Plan party
  - [ ] Invite friends
  - [ ] Buy snacks
  - [ ] Bake cake

You can tick off each entry by holding Ctrl and pressing C twice while the line is active. Now let's start budgeting.

#+NAME: Budget
| Category      | Budget (£) | Spent (£) |
|---------------+------------+-----------|
| Snacks        |         20 |         0 |
| Cake          |         10 |         0 |
| Entertainment |         10 |         0 |
|---------------+------------+-----------|
| Total         |            |           |

Add the formulas for the two columns next to “Total” by typing “:=vsum(@I..II) and Org-mode will store them underneath the table like so:

#+TBLFM: @5$2=vsum(@I..II)::@5$3=vsum(@I..II)

Quick tip, change @5 to @>. That way you're referring to the last row, not the 5th. It only matters if you want to add more rows to the table, but it's worth doing anyway.

Now we need tables for each category.

#+NAME: Snacks
| Item    | Budget |
|---------+--------|
| Crisps  |      7 |
| Pizza   |      6 |
| Popcorn |      5 |
|---------+--------|
| Total   |     18 |
#+TBLFM: @>$2=vsum(@I..II)

#+NAME: Cake
| Item      | Budget |
|-----------+--------|
| Cake Mix  |      2 |
| Milk      |      1 |
| Eggs      |   1.80 |
| Chocolate |      1 |
|-----------+--------|
| Total     |    5.8 |
#+TBLFM: @>$2=vsum(@I..II)

#+NAME: Entertainment
| Item            | Budget |
|-----------------+--------|
| Cheap movie DVD |      6 |
|-----------------+--------|
| Total           |      6 |
#+TBLFM: @>$2=vsum(@I..II)

Now we reveal the purpose of the #+NAME tag. We can call fields from different tables using it. Going back to the first table, replace the spent field of each item with “:=remote(name, coordinate)”

#+NAME: Budget
| Category      | Budget (£) | Spent (£) |
|---------------+------------+-----------|
| Snacks        |         20 |        18 |
| Cake          |         10 |       5.8 |
| Entertainment |         10 |         6 |
|---------------+------------+-----------|
| Total         |         40 |      29.8 |
#+TBLFM: @>$2=vsum(@I..II)::@>$3=vsum(@I..II)::@2$3=remote(Snacks, @>$2)::@3$3=remote(Cake, @>$2)::@4$3=remote(Entertainment, @>$2)

And we're done! A checklist to keep track of progress, and a table managing budgets. The only thing to add here is a recalculate button, so you don't have to keep hitting C-c, C-c every time. Add this above the tables: [[elisp:(org-table-iterate-buffer-tables)][Recalculate]] This uses the link feature touched upon earlier to call a function that repeatedly calculates every table in the buffer until nothing changes, all at the click of a button.

With these articles I've only barely scratched the surface of what Org-mode is capable of. It supports embedding code blocks of multiple different languages and having each one inter-operate, it has a calendar system with agenda, and has a feature called “capture” to automatically save random notes to a specified file for easy access. Every time I look at Org-mode, and Emacs as a whole, I learn something new that I never noticed before.

Org tables support coordinates. $ represents columns, and @ represents rows. @x$y represents column x, row y. Remember that @ comes before $.

| @1$1 | @1$2 | @1$3 | @1$4 |
| @2$1 | @2$2 | @2$3 | @2$4 |
| @3$1 | @3$2 | @3$3 | @3$4 |
| @4$1 | @4$2 | @4$3 | @4$4 |
| @5$1 | @5$2 | @5$3 | @5$4 |

Looking back at the example from the previous article:

| Fruits | Amount |
|--------+--------|
| Apple  |      2 |
| Banana |      3 |
| Pear   |      4 |
|--------+--------|
| Total  |        |

The amount of apples is @2$2, bananas are @3$2 and pears are @4$2. The dividers in this table don't take up coordinates, but allow the ability to specify ranges between them. Ranges are defined with Roman numerals, so the first is @I and the second is @II. The range between them is @I..II. The number of fruits in this table is the sum of @I..II$2. Org uses vsum() to add all values in a range, and we can use that to embed a formula.

| Fruits | Amount |
|--------+--------|
| Apple  |      2 |
| Banana |      3 |
| Pear   |      4 |
|--------+--------|
| Total  | :=vsum(@I..II$2)       |

Typing := followed by a formula will add it to the cell. Hold Ctrl and press C twice to run it, which will move the formula to the bottom of the table.

| Fruits | Amount |
|--------+--------|
| Apple  |      2 |
| Banana |      3 |
| Pear   |      4 |
|--------+--------|
| Total  |      9 |
#+TBLFM: @5$2=vsum(@I..II$2)

All formulae are stored in their own tag at the bottom of each table. This allows org-mode to keep track of them while still showing the answers to them in the correct cells. As one last tip, you can replace @5$2 in the formula definition with @>$2. @> is a shorthand for “The last cell in the column”, so when your table grows you won't have to redo it.

In the next article I will elaborate on using org-mode tables.

Org-mode works with tabulated data, surprisingly. You just draw an ASCII table and it handles the rest.

| Fruits | Amount |
|--------+--------|
| Apple  |      2 |
| Banana |      3 |
| Pear   |      4 |
|--------+--------|
| Total  |      9 |

Tables support tab-completion, so they'll automatically space everything to look nice. In the next article I'll go over coordinates and formulas.

Checklists

Checklists are a fantastic way of structuring your work. They make you break your problem into smaller problems, they keep track of your progress and they let you visualise how much more work you need to do. Checklists are easy to do in Org-mode:

- [ ] Shopping List
  - [ ] Eggs
  - [ ] Milk
  - [ ] Flour
  - [ ] Sugar

There's no special formatting needed. Just type that into an org-mode buffer in Emacs and it'll understand what you mean. To tick a checkbox, just hold Ctrl and press C twice while it's line is highlighted.

- [-] Shopping List
  - [X] Eggs
  - [X] Milk
  - [ ] Flour
  - [ ] Sugar

You can also change how each checkbox tracks the ones inside it. Replace the empty space with a / or % for the following:

- [2/4] Shopping List
  - [X] Eggs
  - [X] Milk
  - [ ] Flour
  - [ ] Sugar
- [50%] Shopping List
  - [X] Eggs
  - [X] Milk
  - [ ] Flour
  - [ ] Sugar

You can also embed clickable links directly into org files:

[[www.google.com]]
[[www.google.com][Google]]

In this case the first example just makes the link clickable, and the second replaces the URL with a convenient title. Links don't have to be Internet-related either:

[[elisp:(switch-to-buffer "*scratch*")][Switch to scratch buffer for quick notes]]

This runs Emacs Lisp code to switch to the scratch buffer, which is a quick note-taking buffer not associated with a file.

In the next article I will introduce tables, and using Org-mode as a basic spreadsheet.

Org-mode is an amazing tool built into Emacs. It lets you take notes, crunch numbers and keep track of projects, all in plaintext. It has massively improved my productivity. The only problem is that it's documentation could do with some work.

In the following days I will write more on org-mode, but for now I'll just cover the fundamentals.

Org-mode is a mode built into Emacs. While there are many tools in other text editors to work with org files, you won't get most of org's features. Whenever you open a file with the extension .org in Emacs, it will automatically switch to org-mode.

For now, let's experiment with headers. Here is an example:

* Example programs
** Hello world
  The hello world program is used to demonstrate printing to stdio, and is commonly used as a first program in most languages.
** Factorial
  Pure functional languages instead use a recursive factorial for their hello world. This is because printing to stdio is not pure.
** Blink
  Microcontrollers such as the Arduino tend to come with a program to blink an LED. This provides direct feedback without having to connect via serial.

Org will automatically understand that anything starting with a * is a header. Add more asterisks for subheaders, subsubheaders and so on. This allows you to easily categorise your thoughts, which leads to org-mode's usefulness in taking notes. Pressing tab will fold and unfold headers, to limit distractions.

Org can easily export it's documents to multiple formats. Hold Ctrl, and press C and E individually to bring up the export dialog.

In the next article I'll go over lists, and how they can be used to keep track of work

As mentioned in the previous article, the map function does the following:

map f(x) [1, 2, 3, 4, 5]
-> [f(1), f(2), f(3), f(4), f(5)]

The Scheme family of languages provide a more advanced map function which allows the following:

map f(x, y) [1, 2, 3, 4] [a, b, c, d]
-> [f(1, a), f(2, b), f(3, c), f(4, d)]

This version of map can take multiple lists, and a function with as many arguments as there are lists, and apply over every list at once to return a single list of answers. The only requirement is that all given lists must be the same length.

For more examples:

(define (zip lst1 lst2)
  (map list lst1 lst2))

(define (add-index lst)
  (map cons (range (length lst)) lst))

(define (square-list lst)
  (map * lst lst))

Map is one of my favourite coding tools. It takes a list and an “a –> b” function, and returns the list with each value replaced by the function's output. Or to put it graphically:

map f(x) [1, 2, 3, 4, 5] = [f(1), f(2), f(3), f(4), f(5)]

One habit I find myself doing is chaining multiple map commands together. I've always wondered how efficient that is, and have decided to put it to the test. I started with the hypothesis “Repeatedly calling map with simple functions is slower than calling it once with a complex function”, and wrote a small program in Racket.

(define random-numbers
  (for/list ((x (make-list 100000 0))) (random 101)))

This generates 100,000 random numbers between 1 and 100 inclusive. It's probably not the best way to do it, but that's not the part being graded here. I then wrote the following two functions:

(define (ctof1 lst)
  (map (lambda (x) (+ 32 x))
       (map (lambda (x) (/ x 5))
            (map (lambda (x) (* 9 x)) lst))))

(define (ctof2 lst)
  (map (lambda (x) (+ 32 (/ (* 9 x) 5))) lst))

Both of these functions do the same thing; They convert temperatures from Celsius to Fahrenheit. Multiply by nine, divide by 5, add 32. The first calls map 3 times, one for each step. The second calls it once, and does all 3 steps at the same time.

(define c1 (time (ctof1 random-numbers)))
(define c2 (time (ctof2 random-numbers)))

The time procedure runs whatever is inside it, and prints out runtime stats. The stats aren't used as part of the definition, but they come up in the terminal for me to compare myself. To make sure this works correctly, I added this:

(if (equal? c1 c2)
    "Both give the same result"
    "Both give different results (This shouldn't happen)")

Every test resulted in both c1 and c2 being the same, which makes sense since they do the same thing. The times came out differently however. On a Thinkpad T420 running Ubuntu 20.04, with DrRacket 7.6, these were the CPU times after 5 runs:

3 maps, simple functions: 63 60 682 23 39
1 map, complex function:  60 40 47  18 19

The 682 was caused by the garbage collector kicking in. I can't explain why the numbers get smaller with every run. Maybe DrRacket has some sort of caching built in.

For now the conclusion seems to be that running map once on a set of data with a complex function is more efficient than running it multiple times with simple ones. It makes sense, since the less you run map the less you have to actually calculate, and the less have to traverse lists. I'll probably try this again with something like Rust in the future.