Hi friend,

I’m too excited about this small side-project I’m working on. I can share a tiny sneak-peek but not more (Yet!). It looks purdy though.

Skip to content
## Keeping Track of Experiments

## How To Get Better At What You Do Every Day With Retrospectives

## “Happy, Meh, Sad + Action Items”

## “Start, Stop, More, Less, Keep”

## “Sailboat to Paradise”

## Calculating Nonces That Result In Zero-Padded SHA256 Hashes

## How to test

## The Little Schemer in Clojure – Recap Chapter 6

## Changing Your Mind

## Parental Controls – Braces as Numbers

## My Journey Into Deep Work – Retrospective Week 17

## What went well

## What went okay

## What went bad

## Action items

## My Journey Into Deep Work – Retrospective Week 16

## What went well

## What went okay

## What went bad

## Action Items

## Thinking and Sleeping Better With Clojure

## Creating Comparisons

### Thinking, Testing and Implementing in Ruby

### Thinking, Testing and Implementing in Clojure

## Set Your Priorities Straight In 2 Minutes Without Thinking Hard

## The Little Schemer in Clojure – Recap Chapter 5

## Dealing With Nested Lists

## Traversing a Tree

## Testing equality

## The Little Schemer in Clojure – Chapter 4 Recap

Hi friend,

I’m too excited about this small side-project I’m working on. I can share a tiny sneak-peek but not more (Yet!). It looks purdy though.

I mentioned the Retrospectives I have been doing for the past years.

Retros are great fun. I use them to improve myself and my work week-over-week. I love them.

In case you’re every interested in doing one, here are three templates that I use regularly. Both, by yourself and as a team.

They’re a lot of fun.

The simplest one is “Happy, Meh, Sad + Action Items” (The one I told you about yesterday)

On a piece of paper, make the 4 columns, and for 10 minutes just write down what went well (Happy), what was so-so (Meh) and what isn’t going well (Sad). Then, go through the lists and think out loud what you can do to improve on it. Usually, that’s for the “Sad” column items.

On a piece of paper, draw the star and fill in the blanks around each piece. “What should I start doing, stop doing, do more of, do less of and what should I just keep doing?”

I love this one because almost all of it is super actionable.

Great fun, helps figure out short-term and long-term goals.

Draw the picture on a piece of paper, and fill out the sections “Island: Where do I want to be? “, “Wind: What’s pushing me forward?”, “Anchor: What’s holding me back?”

It’s that simple. And, if you do them regularly and work on your action-items, you’ll see tremendous improvements for yourself and your team.

Yesterday I watched Anders Brownworth’s awesome Blockchain demo and got inspired to follow along in Clojure.

I *had* to play around with implementing a toy (read: unoptimized!) algorithm to “mine” for nonces that, when added to the hashing input, produces n zeros at the beginning of the hash:

I came up with `make-nonce-for-zeros-finder`

, a function which takes the numbers of zeros you want to have at the beginning and a maximum search-depth and returns a function that will calculate the right nonce for your inputs.

What I personally enjoyed about this little exercise was to express an iterative process in a simple recursive function. And to make a function-maker once I wanted to play around with different types of hashes/nonces I wanted to find.

```
(with-test
(defn make-nonce-for-zeros-finder [z-count]
(fn
([num data]
((make-nonce-for-zeros-finder z-count) num data 0))
([num data nonce]
(cond (= (generate-zeros-string z-count) (subs (generate-hash num data nonce) 0 z-count)) nonce
:else (recur num data (inc nonce))))))
(is (= ((make-nonce-for-zeros-finder 1) nil nil) 39))
(is (= ((make-nonce-for-zeros-finder 1) 1 nil) 25))
(is (= ((make-nonce-for-zeros-finder 1) 1 1) 11))
(is (= ((make-nonce-for-zeros-finder 1) "foo" "bar" 0) 20))
(is (= ((make-nonce-for-zeros-finder 2) nil nil) 286))
(is (= ((make-nonce-for-zeros-finder 4) nil nil) 88484))
(is (= ((make-nonce-for-zeros-finder 4) 1 1) 64840))
(is (= ((make-nonce-for-zeros-finder 4) "foo" "bar") 42515)))
```

With it, I can quickly create finders for different lengths of zero paddings:

```
(def find-nonce-for-one-zero-padded-hash
(make-nonce-for-zeros-finder 1))
(def find-nonce-for-two-zeros-padded-hash
(make-nonce-for-zeros-finder 2))
(def find-nonce-for-three-zeros-padded-hash
(make-nonce-for-zeros-finder 3))
(def find-nonce-for-four-zeros-padded-hash
(make-nonce-for-zeros-finder 4))
(def find-nonce-for-five-zeros-padded-hash
(make-nonce-for-zeros-finder 5))
(def find-nonce-for-six-zeros-padded-hash
(make-nonce-for-zeros-finder 6))
;; and so on...
```

With these guys set up, we can now calculate the nonce for hashes with 1, 2, 3, 4 and 5 zeros padded. Let’s see how that looks:

```
(find-nonce-for-one-zero-padded-hash "foo" "bar")
;; => 20
;; takes less than a millisecond
;; we can verify that the hash has one zero at the beginning:
(generate-hash "foo" "bar" 20)
;; => "0fdc57809f5917eba08907d2805e43ce83f4c933a090b4a2b2549923a35e43d7"
(find-nonce-for-two-zeros-padded-hash "foo" "bar")
;; => 102
;; takes less than a millisecond
;; we can verify that the hash has two zeros at the beginning:
(generate-hash "foo" "bar" 102)
;; => "006668bba91b7e2d5b5357b56600784edb77a72ecf86dc09d515853a841485f6"
(find-nonce-for-three-zeros-padded-hash "foo" "bar")
;; => 4663
;; takes less than a millisecond
;; we can verify that the hash has three zeros at the beginning:
(generate-hash "foo" "bar" 4663)
;; => "0005d9cd6c13fe6bf56e169fd2a7008003fc3a4c6539f8a1cf7d82975d00210e"
```

And that’s really all there is to it. Once you cross 6 padded zeros, you’ll notice an increase in time it takes to compute.

I’ve been a huge fan of the `with-test`

macro. Because of that, you’ll find all test-coverage in core.clj instead of a separate “_test.clj” file.

To run all tests, use `lein test`

**Shadows**

Using helper functions increases readability and helps abstract away representations.

In particular, the example is a simple calculating function `value`

such as `(value '(1 + (7 + 11)) ;; => 19`

We can implement this with standard procedures and recursion:

```
(with-test
(def value
(fn [u]
(cond (atom? u) u
(eq? (car (cdr u)) '+) (+ (value (car u))
(value (car (cdr (cdr u)))))
(eq? (car (cdr u)) '*) (- (value (car u))
(value (car (cdr (cdr u)))))
:else (int (java.lang.Math/pow (value (car u))
(value (car (cdr (cdr u)))))))))
(is (= (value 13) 13))
(is (= (value '(1 + 3)) 4))
(is (= (value '(1 + (3 pow 4))) 82)))
```

Now, you can already see a lot of visual noise. There is a *lot* of `car`

-ing and `cdr`

-ing about. If you squint your eyes a little, you’ll also notice that they all look similar. in fact, there is a lot of repetition in this function:

We see this pattern three times and each it’s along the lines of:

```
((eq? (car (cdr u)) 'OPERATOR) (OPERATOR (value (car u)) (value (car (cdr (cdr u))))))
```

Since we know that our “language” right now is infix arithmetic expressions such as

`(1 + 2)`

and `(1 + (4 * 999))`

…we can extract helper functions that get the `operator`

, the `first sub expression - 1`

and the `second sub expression - 2`

like so:

```
(with-test
(def operator
(fn [aexp]
(car (cdr aexp))))
(is (= (operator '()) nil))
(is (= (operator '(1)) nil))
(is (= (operator '(1 + )) '+))
(is (= (operator '(1 + 2)) '+)))
(with-test
(def first-sub-exp
(fn [aexp]
(car aexp)))
(is (= (first-sub-exp '()) nil))
(is (= (first-sub-exp '(1)) 1))
(is (= (first-sub-exp '(1 + 2)) 1))
(is (= (first-sub-exp '(2 + 1)) 2)))
(with-test
(def second-sub-exp
(fn [aexp] (car (cdr (cdr aexp)))))
(is (= (second-sub-exp '()) nil))
(is (= (second-sub-exp '(1)) nil))
(is (= (second-sub-exp '(1 +)) nil))
(is (= (second-sub-exp '(1 + 2)) 2))
(is (= (second-sub-exp '(1 + 3)) 3)))
```

And then, since we have test-coverage already, refactor our `value`

function to be…

```
(with-test
(def value
(fn [u]
(cond (atom? u) u
(eq? (operator u) '+) (+ (value (first-sub-exp u))
(value (second-sub-exp u)))
(eq? (operator u) '*) (- (value (first-sub-exp u))
(value (second-sub-exp u)))
:else (int (java.lang.Math/pow (value (first-sub-exp u))
(value (second-sub-exp u)))))))
(is (= (value 13) 13))
(is (= (value '(1 + 3)) 4))
(is (= (value '(1 + (3 pow 4))) 82)))
```

Dandy. The new help functions help read this much better.

Now, say, you wake up today and would like to change your newly-born arithmetic language to be written in prefix notation, such as `(+ 1 2)`

. In a way, I want to say:

I’ve changed my mind. Now, I want have

`(+ 1 2)`

express the common arithmetic expression that evaluates to`4`

.

The changes needed to make this happen are now trivial since we have used help functions to hide the representation of `operator`

, `first sub expression`

and `second sub expression`

.

Simply changing the helper functions as follows implements the prefix notation without having to change our `value`

function.

You have to adjust your tests accordingly, of course, and, in a way, doing so is as much as saying

“I want to change this and it should work as follows…”

```
(with-test
(def operator
(fn [aexp]
(car aexp)))
(is (= (operator '()) nil))
(is (= (operator '(+)) '+))
(is (= (operator '(+ 1)) '+)))
(with-test
(def first-sub-exp
(fn [aexp]
(car (cdr aexp))))
(is (= (first-sub-exp '()) nil))
(is (= (first-sub-exp '(+)) nil))
(is (= (first-sub-exp '(+ 1)) 1))
(is (= (first-sub-exp '(+ 1 2)) 1)))
(with-test
(def second-sub-exp
(fn [aexp]
(car (cdr (cdr aexp)))))
(is (= (second-sub-exp '()) nil))
(is (= (second-sub-exp '(+)) nil))
(is (= (second-sub-exp '(+ 1)) nil))
(is (= (second-sub-exp '(+ 1 2)) 2))
(is (= (second-sub-exp '(+ 1 2 3)) 2)))
(with-test
(def value-prefix
(fn [nexp]
(cond (atom? nexp) nexp
(eq? (operator nexp) '+) (+ (value-prefix (first-sub-exp nexp))
(value-prefix (second-sub-exp nexp)))
(eq? (operator nexp) '*) (* (value-prefix (first-sub-exp nexp))
(value-prefix (second-sub-exp nexp)))
:else (int (java.lang.Math/pow (value-prefix (first-sub-exp nexp))
(value-prefix (second-sub-exp nexp)))))))
(is (= (value-prefix 1) 1))
(is (= (value-prefix '(+ 1 3)) 4))
(is (= (value-prefix '(+ 1 (* 2 2))) 5))
(is (= (value-prefix '(+ 1 (pow 3 4))) 82)))
```

This is nice. We have changed `value`

s language by changing the helper functions without changing its own structure.

This way, we are able to demonstrate that we can represent the arithmetic expression **1 + 1** in several ways:

`(+ 1 1)`

to make it feel lispy`(1 + 1)`

to make it feel ‘normal’ and`(1 1 +)`

if we wanted to accommodate friends that read from right to left more naturally

After all, they *mean* the same thing but in different ways.

Now, another example: Let’s say we wanted to *represent* numbers differently but wanted, as reasonable human beings, to maintain the idea of plus, minus, multiplication and division.

So, instead of using the numeral…

**0**, I would like to use`()`

(a list of zero items)**1**, I would like to use`(())`

(a list of one items)**2**, I would like to use`(() ())`

(a list of two items)**3**, I would like to use`(() () ())`

(a list of three items)- and so on…

In terms of API, I would like then to be able to write `1 + 1`

as follows:

```
(+ '( () ) '( () ))
;; => 2
```

Clearly, the idea of addition or subtraction doesn’t change just because I’ve changed how I represent my numbers, right?

Our function to represent the operator `+`

was

```
(def + (fn [n m]
(cond (zero? m) n
:else (add1 (+ n (sub1 m))))))
```

To make our dream of (fairly unreadable) parenthesis number crunching real, all we have to do is rewrite our helper functions `zero?`

, `add1`

and `sub1`

and we’re off to the races:

```
(with-test
(def zero?
(fn [n] (null? n)))
(is (= (zero? '()) true))
(is (= (zero? '(())) false)))
(with-test
(def add1
(fn [n]
(cons '() n)))
(is (= (add1 '()) '(())))
(is (= (add1 '(())) '(() ())))
(is (= (add1 '(() ())) '(() () ()))))
(with-test
(def sub1
(fn [n] (cdr n)))
(is (= (sub1 '()) '()))
(is (= (sub1 '(())) '()))
(is (= (sub1 '(() ())) '(()))))
(with-test
(def + (fn [n m]
(cond (zero? m) n
:else (add1 (+ n (sub1 m))))))
(is (= (+ '() '()) '()))
(is (= (+ '(()) '())) '(()))
(is (= (+ '(() ()) '(())) '(() () ()))))
```

Anyways, that’s what I’ve taken away from the chapter.

I spent this week in Mallorca with my parents. Stil I got to take time to sit down and get 13 (!) hours of deep work done.

Here’s my recap:

- Still very inspired by “Amateurs vs. Pros”
- Feel like I’ve made good progress
- 1 Focus for the week: Work through “The Little Schemer” in Clojure. Finished Chapter 1 – 4.
- Wrote and published 4 blogposts
- Daily Yoga and especially Pranayama exercises
- Had an idea for a meditation video
- Very happy with my Psycho-Cybernetic Imagineering script rehearsals
- Cooking good food with the family
- Have a fireplace at home
- Have a minimal but functional work-space set up

- Didn’t spend a lot of time outside, especially when there’s the mediterranean just across from me.
- “Give and Take” is getting harder to read
- Access to internet only sometimes
- Still jumping a lot from idea to idea
- Didn’t celebrate/appreciate/acknowledge my progress
- Didn’t edit the blogposts
- Lost interest in RedditGrowth while it still could become something valuable

- Have procrastinated on writing the meet up summary
- Too reserved talking about my feelings with my parents

- Take a daily walk
- Celebrate successes and progress more often
- Edit posts before publishing
- Make a decision if I want to continue reading “Give and Take”

I managed to work deeply for 9.5 hours. I also traveled over the weekend, so my week was a bit shot.

Also, I have decided to extend my retros to look at my overall life not just deep work. Since I am independent right now, I want to make sure I maximize my time spent and minimize distractions.

I figured that “Life Retro” combined with action items to improve myself every week is a good idea.

- Using my Psycho-Cybernetics Imagineering script
- It was easy to get into work-flow
- With everything considered, 9.5 hours is still great!
- Traveled to Mallorca to see my parents 🙂
- Had good insight into my “stop-and-go” way of working
- Had a good mentoring session with my friend Philip on Friday
- Overall, I have a more positive outlook on my life than last week
- Inspired by reading “Give and Take” [1]
- Inspired by “Amateurs vs. Pros” [2]
- Got up most days before 9am
- Getting back into a daily Yoga and Meditation routine
- I fixed my vaporizer myself
- Feeling less distracted
- Got to hang out with Nina for an afternoon 🙂
- Went out to a cool bar on Friday with friends
- Made bubbles again
- Cooked delicious food with my father

- I didn’t follow up on my Whiteboard experiment
- I haven’t followed up on the Meetup idea I had
- There was a lot of organizational stuff this week
- Waiting for my accountant on paperwork
- The dating-pool in Berlin is rough. Didn’t do well to my self-image
- Didn’t hear back from someone I needed information from

- I still don’t have one specific idea/topic that I want to deep-dive into. Instead I jump around from idea to idea.
- Jumping between tasks and ideas is exhausting.

- Choose 1 main point of focus for coming week
- Buy a yoga mat while in Mallorca to continue practice there
- Create a visible backlog of tasks

[1] https://www.amazon.com/dp/B00AFPTSI0/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1

[2] https://medium.com/the-mission/the-7-differences-between-professionals-and-amateurs-f8efc4840861

To prioritize a list of todo-items, as in my Prioritization-app I recently launched, I needed to get a list of the unique combinations for the user to choose from:

It goes a little bit like this:

Which is more important:

AorB?

Which is more important:AorC?

Which is more important:BorC?

I wrote a version in Ruby for the app and then a sketch in Clojure to compare readability and expressiveness.

In my opinion, the Clojure version is much more readable and was far easier to reason about.

Probably because I’m not good to solve problems in Ruby but there might be more than meets the eye here.

Let’s say I have a todo-list of `A, B, C and D`

.

The list of comparisons I want is `A ↔ B, A ↔ C, A ↔ D, B ↔ C, B ↔ D and C ↔ D`

to use later in my app.

From the matrix below, you can see, I want only the *unique* comparisons (`A ↔ B`

and `B ↔ A`

are interchangeable for my purposes) and skip dupes that compare an element with itself (`A ↔ A, B ↔ B, C ↔ C, D ↔ D`

)

To demonstrate, I only want the top-right triangle of comparisons:

× | A | B | C | D |
---|---|---|---|---|

A | skip (dupe) |
A ↔ B |
A ↔ C |
A ↔ D |

B | skip |
skip (dupe) |
B ↔ C |
B ↔ D |

C | skip |
skip |
skip (dupe) |
C ↔ D |

D | skip |
skip |
skip |
skip (dupe) |

Now, since I started the app in Ruby, I translated the behavior above as follows:

```
describe '.unique_combinations' do
context 'input list is empty' do
it 'returns an empty list' do
result = Combinator.unique_combinations([])
expect(result).to eq([])
end
end
context 'input list only has one element' do
it 'returns an empty list' do
result = Combinator.unique_combinations([1])
expect(result).to eq([])
end
end
context 'input list only has two elements' do
it 'returns a list with combination a' do
result = Combinator.unique_combinations([1, 2])
expect(result).to eq([[1,2]])
end
it 'returns a list with combination b' do
result = Combinator.unique_combinations([:foo, :bar])
expect(result).to eq([[:foo, :bar]])
end
end
context 'input list only has three elements' do
it 'returns a list with 3 combinations' do
result = Combinator.unique_combinations([1, 2, 3])
expect(result).to eq([[1, 2], [1, 3], [2, 3]])
end
end
context 'input list only has four elements' do
it 'returns a list with 6 combinations' do
result = Combinator.unique_combinations([1, 2, 3, 4])
expect(result).to eq([[1, 2], [1, 3], [1, 4], [2, 3], [2, 4], [3, 4]])
end
end
End
end
```

…and wrote, after several failed attempts and one sleepless night, the following, working but not very elegant solution. I felt weird about it, because even looking at it now, I can’t fully explain it well. It works, it has reasonable test-coverage. But I’m not proud of it.

```
def self.unique_combinations(ids)
return [] if ids.length < 2
all_combinations = []
for i1 in ids
for i2 in ids
if i1 != i2
contains = false
for c in all_combinations
if c[1] == i1 and c[0] == i2
contains = true
end
end
unless contains
all_combinations << [i1, i2]
end
end
end
end
return all_combinations
end
```

Okay, fine I thought. How would I solve this issue in Lisp?

I don’t know why but thinking in terms of lists and recursion instead of iteration made it simpler for me.

The top-level function works as follows:

```
(final-combinations '(A B C D))
;; => '((A B) (A C) (A D) (B C) (B D) (C D))
```

Yup, that’s the list I want.

Thinking about it I had an idea to break the problem further down:

The complete list of unique comparisons, the one I want, is…

- the
**union**of each row of one element combined with all the others. That’s`A`

combined with`B, C and D`

- Each row has an increasing
**offset**from the left that starts at 0 for row 1 and increases by 1 for each following row. - I have to subtract the
**dupes**such as`A ↔ A`

because I don’t need them.

For illustration purposes, here is the table again:

× | A | B | C | D |
---|---|---|---|---|

A | skip (dupe) |
A ↔ B |
A ↔ C |
A ↔ D |

B | skip |
skip (dupe) |
B ↔ C |
B ↔ D |

C | skip |
skip |
skip (dupe) |
C ↔ D |

D | skip |
skip |
skip |
skip (dupe) |

Given the above 3 steps, I basically just wrote them out as functions.

I derived the first function, `combine`

which takes `x`

and `l`

and returns a list of all possible combinations, including the ones we’ll later skip.

```
(with-test
(defn combine
([x l]
(combine x l '()))
([x l acc]
(cond (empty? l) (reverse acc)
:else (recur x (rest l) (conj acc (list x (first l)))) )))
(is (= (combine 1 '()) '()))
(is (= (combine 1 '(1)) '((1 1))))
(is (= (combine 1 '(2)) '((1 2))))
(is (= (combine 1 '(1 2)) '((1 1) (1 2))))
(is (= (combine 1 '(1 2 3)) '((1 1) (1 2) (1 3)))))
```

Then, I use `combine`

to create basically the table above but with nothing yet removed.

```
(with-test
(defn combine-lists
([l1 l2]
(combine-lists l1 l2 '()))
([l1 l2 acc]
(cond (empty? l1) (reverse acc)
:else (recur (rest l1) l2 (cons (combine (first l1) l2) acc)) )))
(is (= (combine-lists '() '()) '()))
(is (= (combine-lists '(1) '(1)) '(((1 1)))))
(is (= (combine-lists '(1 2) '(1 2)) '(((1 1) (1 2))
((2 1) (2 2))))))
```

Then I introduce the idea of an offset. To only take those elements in a list that are after a certain offset.

```
(with-test
(defn take-rest
([offset l]
(cond (= offset 0) l
:else (recur (dec offset) (rest l)))))
(is (= (take-rest 0 '()) '()))
(is (= (take-rest 1 '()) '()))
(is (= (take-rest 0 '(1)) '(1)))
(is (= (take-rest 0 '(1 2)) '(1 2)))
(is (= (take-rest 1 '(1 2)) '(2)))
(is (= (take-rest 1 '(1 2 3)) '(2 3)))
(is (= (take-rest 2 '(1 2 3)) '(3)))
(is (= (take-rest 2 '(1 2 3 4)) '(3 4))))
```

Now I can use `take-rest`

and apply it to each row in my matrix…

```
(defn unique-combinations
([offset ll]
(unique-combinations offset ll '()))
([offset ll acc]
(cond (empty? ll) (reverse acc)
:else (recur (inc offset) (rest ll) (cons (take-rest offset (first ll)) acc)))))
```

And finally remove the identity items such as `A ↔ A`

```
(with-test
(defn final-combinations
[l]
(filter #((= (first %) (second %)))) (partition 2 (flatten (unique-combinations 1 (combine-lists l l)))))
(is (= (final-combinations '()) '()))
(is (= (final-combinations '(1)) '()))
(is (= (final-combinations '(1 2)) '((1 2))))
(is (= (final-combinations '(1 2 3)) '((1 2) (1 3) (2 3))))
(is (= (final-combinations '(1 2 3 4)) '((1 2) (1 3) (1 4) (2 3) (2 4) (3 4)))))
```

Granted, this code is not yet refactored and in total more lines than the Ruby version, but here is the rub:

It took me **20 minutes** to think up and implement the solution in Clojure and 2 days including a sleepless night to do it in Ruby.

I don’t know what that means but I’ll probably use a Lisp like Clojure for problems like this in the future. Just to make sure I get some sleep.

“I have so much to do but I’m not sure which of the things I should do first.”

If you, like me, have struggled with figuring out what should be my #1 priority, then I have good news.

Prioritizing is hard, especially when your items can be *important* and/or *urgent*. The app that I just released gives you the answer to:

**What’s the most important and urgent thing I should do next? (The answer might surprise you!)**

I would like to have someone help me with this and say to me:

Your most important and urgent next step is… Make a balance sheet

Now, **I just released a simple web-app** that helps you (and me) prioritize a list (a todo-list, a list of chores, whatever you want) by two measures:

Importance and Urgency. Some things are important, some are urgent. And some are both. Make sure you tackle the one that’s both first.

The app guides you through comparing each item with each other based on both measures and comes up with the math and sorting automatically.

Here’s the result for the tasks I had on my list today:

Clearly, I need to create my balance sheet. After that I can do the other stuff.

The process is simple.

Go to the homepage and click the **start button**

Then, insert your list of tasks like so:

Then, the app will guide you through comparing each item with each other. This is called a binary sort and will make sure that what item is at the top is really the most *important* and *urgent* one.

Finally, you’ll see your result.

Now, what are you waiting for? Get your priorities straight in a few short minutes and tackle your next, most important and urgent task right away.

**Click here: https://prioio.herokuapp.com**

Have fun!

Alexis

*

PS: You can check out the source at https://github.com/akaalias/prio in case you want to poke around a bit.

PPS: Let me know if you, too, have found a surprising result of your top priority after sorting.

**Oh My Gawd, It’s Full Of Stars**

Learned how to deal with nested lists by asking at least 3 questions:

- Is the list null? If so, return the empty element (an empty list if the value of the function is to be a list, or 0 if you’re evaluating to a number)
- Is the first element in the list an atom? – If so, operate on that atom and cons it onto the natural recursion of the function.
- Else, cons the natural recursion of the function of
`car list`

onto the natural recursion of the function of`cdr list`

You can see this pattern in action on `rember*`

which removes any occurrence of `a`

in `l`

regardless of how deep `a`

s are hidden in the nested list. (*, or star is added to the function name to denote that it’s recurring on both, `car`

and `cdr`

.)

```
(with-test
(def rember*
(fn [a l]
(cond (null? l) '()
(atom? (car l)) (cond (eq? (car l) a) (rember* a (cdr l))
:else (cons (car l)
(rember* a (cdr l))))
:else (cons (rember* a (car l))
(rember* a (cdr l))))))
(is (= (rember* 'cup '()) '()))
(is (= (rember* 'cup '(coffee)) '(coffee)))
(is (= (rember* 'cup '(cup)) '()))
(is (= (rember* 'cup '(coffee cup)) '(coffee)))
(is (= (rember* 'cup '((cup))) '(())))
(is (= (rember* 'cup '(coffee (cup) and (another) cup)) '(coffee () and (another))))
(is (= (rember* 'sauce '(((tomato sauce)) ((bean) sauce) (and ((flying)) sauce))) '(((tomato)) ((bean)) (and ((flying)))))))
```

The same applies to `insertR and insertL*`

which respectively return a new list with `new`

inserted next to to `old`

in `l`

.

The questions are again:

- null? – return an empty list that can be
`cons`

-ed onto from previous calls - atom? – checks if
`car l`

is what we’re looking for and if so, adds a new element - else – recurs on both
`car l`

and`cdr l`

```
(with-test
(def insertR*
(fn [new old l]
(cond (null? l) '()
(atom? (car l)) (cond (eq? (car l) old) (cons old
(cons new (insertR* new old
(cdr l))))
:else (cons (car l)
(insertR* new old
(cdr l))))
:else (cons (insertR* new old (car l))
(insertR* new old (cdr l))))))
(is (= (insertR* 'new 'old '()) '()))
(is (= (insertR* 'new 'old '(old)) '(old new)))
(is (= (insertR* 'new 'old '((old))) '((old new))))
(is (= (insertR* 'new 'old '((these) old ((shoes old) perfume))) '((these) old new ((shoes old new) perfume)))))
```

```
(with-test
(def insertL*
(fn [new old l]
(cond (null? l) '()
(atom? (car l)) (cond (eq? (car l) old) (cons new (cons old (insertL* new old (cdr l))))
:else (cons (car l) (insertL* new old (cdr l))))
:else (cons (insertL* new old (car l))
(insertL* new old (cdr l))))))
(is (= (insertL* 'new 'old '()) '()))
(is (= (insertL* 'new 'old '(old)) '(new old)))
(is (= (insertL* 'new 'old '((old))) '((new old))))
(is (= (insertL* 'new 'old '((these) old ((shoes old) perfume))) '((these) new old ((shoes new old) perfume)))))
```

Then, the same pattern applies to `subst*`

which substitutes `new`

with `old`

in `l`

```
(with-test
(def subst*
(fn [new old l]
(cond (null? l) '()
(atom? (car l)) (cond (eq? (car l) old) (cons new (subst* new old (cdr l)))
:else (cons (car l) (subst* new old (cdr l))))
:else (cons (subst* new old (car l))
(subst* new old (cdr l))))))
(is (= (subst* 'orange 'banana '()) '()))
(is (= (subst* 'orange 'banana '(banana)) '(orange)))
(is (= (subst* 'orange 'banana '((banana))) '((orange))))
(is (= (subst* 'cup 'mug '((a mug) in the (((kitchen (mug)))))) '((a cup) in the (((kitchen (cup))))))))
```

Then, `member*`

returns `true`

if `a`

can be found in `l`

, otherwise it returns `false`

:

Note that instead of returning a list on `(null l)`

it returns `false`

which represents that the element couldn’t be found and we’ve reached the end where we can’t look no further.

```
(with-test
(def member*
(fn [a l]
(cond (null? l) false
(atom? (car l)) (or (eq? (car l) a)
(member* a (cdr l)))
:else (or (member* a (car l))
(member* a (cdr l))))))
(is (= (member* 'foo '()) false))
(is (= (member* 'foo '(foo)) true))
(is (= (member* 'foo '(bar)) false))
(is (= (member* 'foo '((foo))) true))
(is (= (member* 'foo '((the quick) ((((brown (springy foo)) jumps over)) the dog))))))
```

A personal favorite of mine is `leftmost`

which returns the left-most element in `l`

. It’s a bit simpler than the functions before. It recurs **only** on `(car l)`

unless it is an atom:

```
(with-test
(def leftmost
(fn [l]
(cond (null? l) nil
(atom? (car l)) (car l)
:else (leftmost (car l)))))
(is (= (leftmost '()) nil))
(is (= (leftmost '(apple)) 'apple))
(is (= (leftmost '((apple))) 'apple))
(is (= (leftmost '(((hot cider) with (green) tea))) 'hot)))
```

At the end of the chapter, the authors use recurring on a nested list to test for equality of any s-expression:

```
(with-test
(def eqlist?
(fn [l1 l2]
(cond (and (null? l1) (null? l2)) true
(or (null? l1) (null? l2)) false
:else (and (equal? (car l1) (car l2))
(eqlist? (cdr l1) (cdr l2))))))
(is (= (eqlist? '() '()) true))
(is (= (eqlist? '() '(foot)) false))
(is (= (eqlist? '(foot) '()) false))
(is (= (eqlist? '(foot) '(foot)) true))
(is (= (eqlist? '(foot rub) '(foot sub)) false))
(is (= (eqlist? '(strawberry ice cream) '(strawberry ice cream)) true))
(is (= (eqlist? '(strawberry ice cream) '(strawberry cream ice)) false))
(is (= (eqlist? '((coffee) (cup)) '((coffee) (cup))) true)))
(with-test
(def equal?
(fn [s1 s2]
(cond (and (atom? s1) (atom? s2)) (equan? s1 s2)
(or (atom? s1) (atom? s2)) false
:else (eqlist? s1 s2))))
(is (= (equal? 'a 'a) true))
(is (= (equal? 'a 'b) false))
(is (= (equal? 'a '(a)) false))
(is (= (equal? '(a) 'a) false))
(is (= (equal? '(a) '(a)) true))
(is (= (equal? '(a) '(b)) false)))
```

I am starting to realize how great it is to have a set of tests right away with any function definition. Refactoring will be easy and give me confidence that everything still works. Pretty stoked!

**Number Games**

I’ve enjoyed working through chapter 4. It’s simpler and more dense at the same time since it’s all about numbers. Over the course of this chapter I (re)implemented several arithmetic basic functions such as `add1`

, `sub1`

– Those were rather helper functions – and moved on to implementing `pluss`

and `minuss`

, `multiply`

and `divide`

(I added the extra “s” to pluss and minuss to avoid redefining built-in functions).

The cool thing about this chapter is that I was able to implement these functions only in terms of very simple operations (add1, sub1) and recursion.

For example, `pluss`

works as follows:

Given `n`

and `m`

, I want to evaluate their sum. For that to happen, I need to ask two questions:

- Is
`m`

equal to 0? If so, return`n`

. This would make an addition such as 1 + 0 work straight away. - Else,
`add1`

to the natural recursion of`pluss`

with`n`

and`(sub1 m)`

. This counts`m`

down with each recursion until it reaches 0.

If we were to add 1 and 3, the result of 4 would be calculated as:

```
(pluss 1 3)
1 + (pluss 1 2)
1 + 1 + (pluss 1 1)
1 + 1 + 1 (pluss 1 0)
1 + 1 + 1 + 1
```

Pretty cool.

```
(with-test
(def pluss
(fn [n m]
(cond (zero? m) n
:else (add1 (pluss n (sub1 m))))))
(is (= (pluss 0 0) 0))
(is (= (pluss 1 0) 1))
(is (= (pluss 0 1) 1))
(is (= (pluss 1 1) 2))
(is (= (pluss 1 2) 3))
(is (= (pluss 46 12) 58)))
```

For every function I write, I also make sure I start with the smallest possible test-case and then only add the code necessary to fix that test. I quiet enjoy it because it gives me confidence that, once I refactor, the functions still work.

For example, take `occur`

which takes an atom `a`

and a list `lat`

as its arguments and returns the count of `a`

in `lat`

.

To build the simple algorithm, I start out writing the bare minimum setup for the first, smallest test:

```
(with-test
(def occur
(fn [a lat]))
(is (= (occur 'a '()) 0)))
```

Running the test will fail since the function currently, and intentionally, only returns `nil`

and not 0 when given `'a`

and `'()`

as its inputs.

I can fix this situation by writing the smallest possible solution which is to return 0, hardcoded:

```
(with-test
(def occur
(fn [a lat] 0))
(is (= (occur 'a '()) 0)))
```

Our first test will now pass. We could, if we wanted to, make a commit at this point. On to the next.

```
(with-test
(def occur
(fn [a lat] 0))
(is (= (occur 'a '()) 0))
(is (= (occur 'a '(a)) 1)))
```

Running the tests will now fail for scenario 2 when we expect to receive 1 as the value and not 0. The smallest fix to solve for this is to introduce a conditional.

```
(with-test
(def occur
(fn [a lat]
(cond (null? lat) 0
:else 1)))
(is (= (occur 'a '()) 0))
(is (= (occur 'a '(a)) 1)))
```

Great! All tests are passing now. Now, on to the next, simplest test-case where `(occur 'a '(b))`

should evaluate to 0.

```
(with-test
(def occur
(fn [a lat]
(cond (null? lat) 0
:else 1)))
(is (= (occur 'a '()) 0))
(is (= (occur 'a '(a)) 1))
(is (= (occur 'a '(b)) 0)))
```

The third test fails naturally. To fix it, I now have to introduce a new condition to check if `(car lat)`

is equal to `a`

:

```
(with-test
(def occur
(fn [a lat]
(cond (null? lat) 0
(equan? (car lat) a) 1
:else 0)))
(is (= (occur 'a '()) 0))
(is (= (occur 'a '(a)) 1))
(is (= (occur 'a '(b)) 0)))
```

Now, let’s test for multiple occurrences of `a`

in `lat`

: `(is (= (occur 'a '(a a)) 2))`

```
(with-test
(def occur
(fn [a lat]
(cond (null? lat) 0
(equan? (car lat) a) 1
:else 0)))
(is (= (occur 'a '()) 0))
(is (= (occur 'a '(a)) 1))
(is (= (occur 'a '(b)) 0))
(is (= (occur 'a '(a a)) 2)))
```

The test will fail when run. Now we have to fix it by introducing adding 1 to the natural recursion of the function as follows: `(add1 (occur a (cdr lat)))`

```
(with-test
(def occur
(fn [a lat]
(cond (null? lat) 0
(equan? (car lat) a) (add1 (occur a (cdr lat)))
:else 0)))
(is (= (occur 'a '()) 0))
(is (= (occur 'a '(a)) 1))
(is (= (occur 'a '(b)) 0))
(is (= (occur 'a '(a a)) 2)))
```

Splendid, all tests are passing.

Now, I want to make sure that we get the right result, when the list is mixed, such as `(is (= (occur 'a '(a b c a)) 2))`

```
(with-test
(def occur
(fn [a lat]
(cond (null? lat) 0
(equan? (car lat) a) (add1 (occur a (cdr lat)))
:else 0)))
(is (= (occur 'a '()) 0))
(is (= (occur 'a '(a)) 1))
(is (= (occur 'a '(b)) 0))
(is (= (occur 'a '(a a)) 2))
(is (= (occur 'a '(a b c a)) 2)))
```

Adding the test makes it fail of course, since we’re not accounting for this scenario. It’s a simple fix, we need to allow our `:else`

branch to continue searching for `a`

s with `(occur a (cdr lat))`

. The final solution to `occur`

is

```
(with-test
(def occur
(fn [a lat]
(cond (null? lat) 0
(equan? (car lat) a) (add1 (occur a (cdr lat)))
:else (occur a (cdr lat)))))
(is (= (occur 'a '()) 0))
(is (= (occur 'a '(a)) 1))
(is (= (occur 'a '(b)) 0))
(is (= (occur 'a '(a a)) 2))
(is (= (occur 'a '(a b c a)) 2)))
```

I think this is pretty cool. We’ve got a first set of reasonable inputs and outputs covered. This would be a great time to run the full test-suite with `lein test`

, and if everything passes, make a commit and push to master. For this I usually make myself a tiny script named `ship.sh`

that runs the test-suite one final time and does the git push for me:

ship.sh

```
#!/bin/bash
lein test && git push origin master
```

Nothing fancy, but it keeps me from habitually doing a `git push origin master`

without running all tests beforehand.

Anyways, I enjoyed showing you how I build my functions with TDD and baby-steps to arrive at a good place to commit and push. The full listing of my (un-refactored) chapter 4 is as follows:

```
(ns the-little-clojurian.chapter4
(:require [clojure.test :refer :all]
[the-little-clojurian.chapter1 :refer :all]
[the-little-clojurian.chapter2 :refer :all]
[the-little-clojurian.chapter3 :refer :all]))
(with-test
(def add1
(fn [x] (+ x 1)))
(is (= (add1 0) 1))
(is (= (add1 67) 68))
(is (= (add1 68) 69)))
(with-test
(def sub1
(fn [x] (- x 1)))
(is (= (sub1 0) -1))
(is (= (sub1 1) 0))
(is (= (sub1 2) 1))
(is (= (sub1 3) 2)))
(with-test
(def pluss
(fn [n m]
(cond (zero? m) n
:else (add1 (pluss n (sub1 m))))))
(is (= (pluss 0 0) 0))
(is (= (pluss 1 0) 1))
(is (= (pluss 0 1) 1))
(is (= (pluss 1 1) 2))
(is (= (pluss 1 2) 3))
(is (= (pluss 46 12) 58)))
(with-test
(def minuss
(fn [n m]
(cond
(zero? m) n
:else (sub1 (minuss n (sub1 m))))))
(is (= (minuss 0 0) 0))
(is (= (minuss 1 1) 0))
(is (= (minuss 2 1) 1))
(is (= (minuss 3 2) 1))
(is (= (minuss 100 1) 99)))
(with-test
(def tup?
(fn [l]
(cond (null? l) true
(not (number? (car l))) false
:else (tup? (cdr l)))))
(is (= (tup? '()) true))
(is (= (tup? '(a)) false))
(is (= (tup? '(1)) true))
(is (= (tup? '(1 a)) false))
(is (= (tup? '(1 2)) true))
(is (= (tup? '(2 11 3 79 47 6))))
(is (= (tup? '(8 55 5 555))))
(is (= (tup? '(1 2 8 apple 4 3)) false))
(is (= (tup? '(3 (7 4) 13 9)) false)))
(with-test
(def addtup
(fn [tup]
(cond (null? tup) 0
:else (pluss (car tup) (addtup (cdr tup))))))
(is (= (addtup '()) 0))
(is (= (addtup '(1)) 1))
(is (= (addtup '(1 2)) 3))
(is (= (addtup '(1 2 3)) 6))
(is (= (addtup '(3 5 2 8)) 18))
(is (= (addtup '(15 6 7 12 3)) 43)))
(with-test
(def multiply
(fn [n m]
(cond (zero? m) 0
:else (pluss n (multiply n (sub1 m))))))
(is (= (multiply 0 0) 0))
(is (= (multiply 1 1) 1))
(is (= (multiply 1 0) 0))
(is (= (multiply 5 3) 15))
(is (= (multiply 13 4) 52)))
(with-test
(def tup+
(fn [tup1 tup2]
(cond (null? tup1) tup2
(null? tup2) tup1
:else (cons (pluss (car tup1) (car tup2))
(tup+
(cdr tup1) (cdr tup2))))))
(is (= (tup+ '() '()) '()))
(is (= (tup+ '(1) '(1)) '(2)))
(is (= (tup+ '(2 3) '(4 6)) '(6 9)))
(is (= (tup+ '(3 6 9 11 4) '(8 5 2 0 7)) '(11 11 11 11 11)))
(is (= (tup+ '(3 7) '(4 6 8 1)) '(7 13 8 1))))
(with-test
(def greater-than
(fn [n m] false
(cond (zero? n) false
(zero? m) true
:else (greater-than (sub1 n) (sub1 m)))))
(is (= (greater-than 0 0) false))
(is (= (greater-than 1 0) true))
(is (= (greater-than 12 133) false))
(is (= (greater-than 120 11) true))
(is (= (greater-than 4 6) false)))
(with-test
(def smaller-than
(fn [n m]
(cond (zero? m) false
(zero? n) true
:else (smaller-than (sub1 n) (sub1 m)))))
(is (= (smaller-than 0 0) false))
(is (= (smaller-than 0 1) true))
(is (= (smaller-than 4 6))))
(with-test
(def equal
(fn [n m]
(cond (smaller-than n m) false
(greater-than n m) false
:else true)))
(is (= (equal 0 0) true))
(is (= (equal 0 1) false))
(is (= (equal 1 1) true))
(is (= (equal 44 44) true)))
(with-test
(def expt
(fn [n m]
(cond (zero? m) 1
:else (multiply n (expt n (sub1 m))))))
(is (= (expt 1 1) 1))
(is (= (expt 2 2) 4))
(is (= (expt 2 3) 8))
(is (= (expt 5 3) 125)))
(with-test
(def divide
(fn [n m]
(cond (zero? m) (throw (IllegalArgumentException.))
(smaller-than n m) 0
:else (add1 (divide (minuss n m) m)))))
(is (= (divide 0 1) 0))
(is (thrown? IllegalArgumentException (divide 1 0)))
(is (= (divide 15 4) 3))
(is (= (divide 15 3) 5))
(is (= (divide 100 10) 10)))
(with-test
(def length
(fn [lat]
(cond (null? lat) 0
:else (add1 (length (cdr lat))))))
(is (= (length '()) 0))
(is (= (length '(hotdogs)) 1))
(is (= (length '(hotdogs with mustard sauerkraut and pickles)) 6))
(is (= (length '(ham and cheese on rye)) 5)))
(with-test
(def pick
(fn [n lat]
(cond (zero? n) nil
(one? n) (car lat)
:else (pick (sub1 n) (cdr lat)))))
(is (= (pick 0 '(apple)) nil))
(is (= (pick 1 '()) nil))
(is (= (pick 1 '(apple)) 'apple))
(is (= (pick 2 '(apple bananas)) 'bananas))
(is (= (pick 4 '(apple)) nil)))
(with-test
(def rempick
(fn [n lat]
(cond (zero? n) nil
(one? n) (cdr lat)
:else (cons (car lat)
(rempick (sub1 n)
(cdr lat))))))
(is (= (rempick 0 '()) nil))
(is (= (rempick 1 '(apple)) '()))
(is (= (rempick 2 '(apple bananas gin)) '(apple gin))))
(with-test
(def no-nums
(fn [lat]
(cond (null? lat) '()
(number? (car lat)) (no-nums (cdr lat))
:else (cons (car lat)
(no-nums
(cdr lat))))))
(is (= (no-nums '()) '()))
(is (= (no-nums '(1)) '()))
(is (= (no-nums '(apple)) '(apple)))
(is (= (no-nums '(5 pears 6 prunes 9 dates)) '(pears prunes dates))))
(with-test
(def all-nums
(fn [lat]
(cond (null? lat) '()
(number? (car lat)) (cons (car lat)
(all-nums (cdr lat)))
:else (all-nums (cdr lat)))))
(is (= (all-nums '()) '()))
(is (= (all-nums '(1)) '(1)))
(is (= (all-nums '(apple)) '()))
(is (= (all-nums '(1 apple 2 pears 3 bananas)) '(1 2 3))))
(with-test
(def equan?
(fn [a1 a2]
(cond (and (number? a1) (number? a2)) (equal a1 a2)
(or (number? a1) (number? a2)) false
:else (eq? a1 a2))))
(is (= (equan? 0 0) true))
(is (= (equan? 0 1) false))
(is (= (equan? 0 'a) false))
(is (= (equan? 'a 'a) true))
(is (= (equan? 'a 'b) false)))
(with-test
(def occur
(fn [a lat]
(cond (null? lat) 0
(equan? (car lat) a) (add1 (occur a (cdr lat)))
:else (occur a (cdr lat)))))
(is (= (occur 'a '()) 0))
(is (= (occur 'a '(a)) 1))
(is (= (occur 'a '(b)) 0))
(is (= (occur 'a '(a a)) 2))
(is (= (occur 'a '(a b c a)) 2))
(is (= (occur 'a '(b c d e)) 0)))
(with-test
(def one?
(fn [x] (equal x 1)))
(is (= (one? 0) false))
(is (= (one? 1) true))
(is (= (one? 2) false)))
```