# Eric Normand Newsletter 470: Worked Example: Days of the week

Your friendly reminder that if you aren't reading Eric's newsletter, you are missing out…

Lots of great content in the latest newsletter! Really glad I subscribed. Thanks, Eric, for your work.

Eric's newsletter is so simply great. Love it!

## Reflections 🤔

*Worked Example: Days of the week*

In this issue, I'd like to explore the simple abstraction of mapping the days of the week to the numbers 0-6. Note that this will be a rather theoretical treatment since I'm still exploring the ideas.

Our computers give us an abstraction so solid that we usually forget that it is one: Mapping from bit strings (concrete domain) to integers (abstract domain). It is not completely solid, though. It breaks down when the numbers get large. However, we can put the abstraction out of our minds because we only need seven numbers. The numbers will never get big enough to overflow.

Because we have that solid abstraction, we can securely map our domain concepts onto numbers. I've mentioned in previous issues that you can map the days of the week onto the numbers 0-6. We map days to numbers and numbers to bit strings. Hurray! We can store days of the week in RAM.

### Operations

Operations help constrain the myriad choices we can make in how we abstract. We want to ask questions like, "What is the day three days after Friday?" We map days to numbers because we can conveniently define our operations in terms of arithmetic.

```
(defn domain-operation [args] ;; signatures are in domain terms
(body ...)) ;; body is in terms of mapping
```

For instance, we could tell if two days were the same by using equality. In this abstraction, equality is equivalent in the concrete and abstract domains:

```
(defn days-equal? [a b]
(= a b))
```

Likewise, calculating 3 days after a Monday uses addition:

```
(defn days-after [weekday days]
(+ weekday days))
;; 0 is Monday
(days-after 0 3) ;;=> 3
```

It's all a theoretical exercise until you have use cases. We chose numbers because our use c ases neatly mapped to arithmetical addition. Those use cases constrain the problem and make the decision easier.

### What about going over 6?

We are mapping days of the week to the numbers 0-6. But we are also
doing addition. What happens if we add to a number and the result is
over 6? We call the mapping from integers to weekdays a *partial
function* because some integers do not map to any day of the week. There
are many ways to deal with that. We'll deal with partial mappings in a
future issue. For now, we will use the `mod`

(modulus) operator:

```
(defn days-after [weekday days]
(mod (+ weekday days) 7))
```

### Explicit mapping

We can do one more thing and define an explicit mapping. Tuesday is an
abstract concept. You can't touch Tuesday. However, the name of the
concept (the word *Tuesday*) is quite concrete, and our brains do the
mapping for us. We can map between strings of the names and the numbers
that the weekdays map to:

```
(defn day-name->int [name]
(get {"Monday" 0 "Tuesday" 1 "Wednesday" 2 "Thursday" 3 "Friday" 4 "Saturday"
5 "Sunday" 6} name))
```

And we can map back the other way:

```
(defn day-int->name [n]
(get ["Monday" "Tuesday" "Wednesday" "Thursday" "Friday" "Saturday" "Sunday"]
n))
```

This explicit mapping should allow us to do something like this:

```
(-> "Monday"
(day-name->int)
(days-after 3)
(day-int->name)) ;=> "Thursday"
```

We map the name into numbers, where arithmetic is easy, do the arithmetic, then map it back to a name. Expressions like this make me realize that we could easily map the name to other "spaces" where different operations are easy. We often get stuck trying to find a single representation that works in all use cases.

### Conclusions

Very many ideas came to the surface by working through this example. We defined our mapping, used use cases to constrain our design, dealt with incomplete mappings (non-total functions), and made some explicit mappings. This exercise was fun. I hope to explore more ideas in this vein in the hopes of eventually writing a book.

## Clojure Show 🍿

The Clouncil is a newish Clojure show, specifically aimed at beginners. Check it out!

## Grokking Simplicity 📘

I'm happy to see that people are still finding my book:

You can order the book on Amazon. Please leave a rating and/or review. Reviews are a primary signal that Amazon uses to promote the book. They help others learn whether the book is for them.

You can order the print and/or eBook versions on Manning.com (use TSSIMPLICITY for 50% off).

## Clojure Challenge 🤔

### Last challenge

## Issue 469 - Lazy Fibonacci Sequence

### This week's challenge

*Reverse words*

Write a function that takes a string containing words (one or more sentences) and returns a string containing the words in reverse order.

Examples

```
(reverse-words "my name is Eric.") ;;=> "Eric. is my name"
(reverse-words "hello") ;;=> "hello"
(reverse-words "I love you") ;;=> "you love I"
```

Note: Words are characters separated by whitespace.

Thanks to this site
for the problem idea, where it is rated *Very Hard* in Java. The problem
has been modified.

Please submit your solutions as comments on this gist.

Rock on!

Eric Normand