Global Day of Code Retreat 2022
In this article I want to share my experience from Global Day of Code Retreat 2022.
The initiative
GDCR is an annual event organized on site and virtually all over the world. As the event page describes it:
Coderetreats are free day-long, intensive practice events, focusing on the fundamentals of software development and design. By providing developers the opportunity to take part in focused practice, away from the pressures of “getting things done”, the coderetreat format has proven itself to be a highly effective means of learning and nurturing software development skills.
This year I had the pleasure to co-organize the event in Ocado Technology office in Wroclaw together with Klose Brothers.
How it works?
At the beginning of the day we’d define the problem - usually it’s Conway’s Game of Life. We set the focus on Test Driven Development and 4 rules of simple design. After the introduction it’s all about iterations. Each goes like this:
- Define the limitations
- Form pairs or groups
- Build the solution for 45 minutes
- Delete your code
- Conduct a retrospection, see what you have learned, find pros and cons of your decisions
- Take a short break and start again
The workshop is described in details in the workshop section so you’re welcome to check it out.
Conway’s Game of Life
Very often the problem we’ll try to solve during code retreat would be Conway’s Game of Life. The rules are simple and are best described by the image
In an infinite iteration, the game calculates the next state of the grid based on the previous one by applying the rules.
Depending on the initial set of active cells, the game will evolve differently. One of the possible outcomes is Gosper’s glider gun.
2022 edition rewind
It was the first time I had a chance to take part in code retreat. This time it was around 20 participants from various backgrounds and experience varying from non-programmers to developers with years of experience.
Bubble sort
Each iteration had it’s own character. For the first one all participants stood in the line and were asked to perform a bubble sort by their experience. This way we were lined up from the least to most experienced person. For that iteration we’d built pairs by taking people from each end.
This was a great starter as the most experienced people had a chance to test their skill of knowledge sharing and the mid-experienced pairs were well balanced.
Ping Pong
On the other iteration we went with the ping-pong approach. In this scenario the participants in pairs are supposed to follow this steps:
- One participant writes a failing test for a minimal part of the functionality and hands over the keyboard
- The other person implements the function and a new failing test, the roles change
This is a great exercise for TDD approach where the participants learn to organize the code in smallest possible pieces to make as many keyboard handovers as possible.
FP Solution Mob
Since many participants expressed the interest in solution built with functional programming techniques, we have decided to host one iteration as a mob programming.
Considering not all participants were very experienced, we didn’t want to go with too advanced solutions.
You can find the full code in this gist: https://gist.github.com/majk-p/b944530e2b3e8cf00bf9313429bc66c8
To keep things simple we have modelled the grid using a 2D ArraySeq
:
trait Grid {
def value: ArraySeq[ArraySeq[Cell]]
}
Where the Cell is defined as
case class Cell(isActive: Boolean, neighbors: Seq[Boolean])
The neat part about the solution though is the extension method map
that allows us to build a new grid by mapping each cell. The mapping function takes a Cell
as an argument, meaning that it has access to both the current state and the neighborhood.
extension (grid: Grid) {
def map(f: Cell => Boolean): Grid = new Grid {
val mappedState: ArraySeq[ArraySeq[Boolean]] = grid.value.map(_.map(f))
val value = mappedState.zipWithIndex.map { (row, i) =>
row.zipWithIndex.map { (cellActivity, j) =>
Cell(
isActive = cellActivity,
grid.neighborCoordinates(i, j).map((x, y) => mappedState(x)(y))
)
}
}
}
def neighborCoordinates(x: Int, y: Int): Seq[Coordinates] = ??? // irrelevant
}
Thanks to that, we were able to keep the high level business code clean and elegant, implementing the iteration model using fs2.Stream
object Main extends IOApp.Simple {
val initialState: Coordinates => Boolean =
List((1, 1), (1, 2), (1, 3)).contains(_)
val grid: Grid = Grid.instance(5, initialState)
val gameLogic: Cell => Boolean = cell => {
val activeNeighbors = cell.neighbors.count(_ == true)
if (cell.isActive)
activeNeighbors == 2 || activeNeighbors == 3
else
activeNeighbors == 3
}
def run: IO[Unit] =
Stream
.iterate(grid)(g => g.map(gameLogic))
.evalTap(g => Render.render(g)("⬛", "⬜"))
.metered(1.second)
.compile
.drain
}
As usual if you want to try the code you can launch it using scala-cli like this:
$ scala-cli https://gist.github.com/majk-p/b944530e2b3e8cf00bf9313429bc66c8
⬜⬜⬜⬜⬜
⬜⬛⬛⬛⬜
⬜⬜⬜⬜⬜
⬜⬜⬜⬜⬜
⬜⬜⬜⬜⬜
⬜⬜⬛⬜⬜
⬜⬜⬛⬜⬜
⬜⬜⬛⬜⬜
⬜⬜⬜⬜⬜
⬜⬜⬜⬜⬜
⬜⬜⬜⬜⬜
⬜⬛⬛⬛⬜
⬜⬜⬜⬜⬜
⬜⬜⬜⬜⬜
⬜⬜⬜⬜⬜
⬜⬜⬛⬜⬜
⬜⬜⬛⬜⬜
⬜⬜⬛⬜⬜
⬜⬜⬜⬜⬜
⬜⬜⬜⬜⬜
^C
Now by simply modifying the input state we can for example watch the Glider move diagonally towards the bottom right.
val glider = List(
// format: off
(1, 1),
(2, 2),
(0, 3), (1, 3), (2, 3)
)
val initialState: Coordinates => Boolean =
List(glider).flatten.contains(_)
val grid: Grid = Grid.instance(10, initialState)
And here is the output:
$ scala-cli main.scala
⬜⬜⬜⬛⬜⬜⬜⬜⬜⬜
⬜⬛⬜⬛⬜⬜⬜⬜⬜⬜
⬜⬜⬛⬛⬜⬜⬜⬜⬜⬜
⬜⬜⬜⬜⬜⬜⬜⬜⬜⬜
⬜⬜⬜⬜⬜⬜⬜⬜⬜⬜
⬜⬜⬜⬜⬜⬜⬜⬜⬜⬜
⬜⬜⬜⬜⬜⬜⬜⬜⬜⬜
⬜⬜⬜⬜⬜⬜⬜⬜⬜⬜
⬜⬜⬜⬜⬜⬜⬜⬜⬜⬜
⬜⬜⬜⬜⬜⬜⬜⬜⬜⬜
⬜⬜⬛⬜⬜⬜⬜⬜⬜⬜
⬜⬜⬜⬛⬛⬜⬜⬜⬜⬜
⬜⬜⬛⬛⬜⬜⬜⬜⬜⬜
⬜⬜⬜⬜⬜⬜⬜⬜⬜⬜
⬜⬜⬜⬜⬜⬜⬜⬜⬜⬜
⬜⬜⬜⬜⬜⬜⬜⬜⬜⬜
⬜⬜⬜⬜⬜⬜⬜⬜⬜⬜
⬜⬜⬜⬜⬜⬜⬜⬜⬜⬜
⬜⬜⬜⬜⬜⬜⬜⬜⬜⬜
⬜⬜⬜⬜⬜⬜⬜⬜⬜⬜
⬜⬜⬜⬛⬜⬜⬜⬜⬜⬜
⬜⬜⬜⬜⬛⬜⬜⬜⬜⬜
⬜⬜⬛⬛⬛⬜⬜⬜⬜⬜
⬜⬜⬜⬜⬜⬜⬜⬜⬜⬜
⬜⬜⬜⬜⬜⬜⬜⬜⬜⬜
⬜⬜⬜⬜⬜⬜⬜⬜⬜⬜
⬜⬜⬜⬜⬜⬜⬜⬜⬜⬜
⬜⬜⬜⬜⬜⬜⬜⬜⬜⬜
⬜⬜⬜⬜⬜⬜⬜⬜⬜⬜
⬜⬜⬜⬜⬜⬜⬜⬜⬜⬜
⬜⬜⬜⬜⬜⬜⬜⬜⬜⬜
⬜⬜⬛⬜⬛⬜⬜⬜⬜⬜
⬜⬜⬜⬛⬛⬜⬜⬜⬜⬜
⬜⬜⬜⬛⬜⬜⬜⬜⬜⬜
⬜⬜⬜⬜⬜⬜⬜⬜⬜⬜
⬜⬜⬜⬜⬜⬜⬜⬜⬜⬜
⬜⬜⬜⬜⬜⬜⬜⬜⬜⬜
⬜⬜⬜⬜⬜⬜⬜⬜⬜⬜
⬜⬜⬜⬜⬜⬜⬜⬜⬜⬜
⬜⬜⬜⬜⬜⬜⬜⬜⬜⬜
I encourage you to play around with the initial state to see what other results you can get.
If you are looking for more advanced approach check out the solution prepared by 47 degrees for GDCR in this blog post https://www.47deg.com/blog/game-of-life-scala
Summary
Code retreat is a fantastic way to improve your professional skills, an opportunity to meet great people and gain a new perspective on software development. I definitely recommend taking part in this kind of event if you have an opportunity to do so. Make sure to check out https://www.coderetreat.org/events/ to find upcoming events.