Friday, December 30, 2016

Books I read 2016

January
- El Eternauta, Héctor Germán Oesterheld and Francisco Solano López
- Barcelona. Los vagabundos de la chatarra, Jorge Carrión and Sagar Fornies
- Rip Van Winkle, Washington Irving
- La guerra interminable (The Forever War), Joe Haldeman
- Maintanable JavaScript, Nicholas C. Zakas
- Ve y pon un centinela (Go Set a Watchman), Harper Lee
- El nombre del viento (The Name of the Wind), Patrick Rothfuss
- You Don't Know JS: Async & Performance, Kyle Simpson
- Sapiens: A Brief History of Humankind, Yuval Noah Harari
- The Principles of Object Oriented JavaScript, Nicholas C. Zakas

February
- The Leprechauns of Software Engineering, Laurent Bossavit
- The Wise Man's Fear, Patrick Rothfuss
- Fundamentals of Object-Oriented Design in UML, Meilir Page-Jones
- Old Man's War, John Scalzi
- Cevdet Bey e hijos (Cevdet Bey ve Oğulları), Orhan Pamuk
- Ringworld, Larry Niven
- Why Nations Fail: The Origins of Power, Prosperity, and Poverty, Daron Acemoglu and James A. Robinson

March
- The Grumpy Programmer's Guide To Building Testable PHP Applications, Chris Hartjes
- The Grapes of Wrath, John Steinbeck
- The Coding Dojo Handbook, Emily Bache
- Fahrenheit 451, Ray Bradbury

April
- Implementation Patterns, Kent Beck (3rd time)
- The Power of Habit: Why We Do What We Do in Life and Business, Charles Duhigg
- How to Win Friends and Influence People, Dale Carnegie
- Understanding the Four Rules of Simple Design, Corey Haines (2nd time)
- La llamada de Cthulhu (The Call of Cthulhu), El horror de Dunwich (The Dunwich Horror) and Las ratas en las paredes (The Rats in the Walls), H. P. Lovecraft
- The Tales of Beedle the Bard, J. K. Rowling

May
- The Slow Regard of Silent Things, Patrick Rothfuss
- Building Microservices, Designing Fine-Grained Systems, Sam Newman
- Man's Search for Meaning, Viktor Frankl
- Manifiesto del Partido Comunista (Das Kommunistiche Manifest), K. Marx and F. Engels
- Web Development with Clojure, Build Bulletproof Web Apps with Less Code, Dimitri Sotnikov
- Patterns of Enterprise Application Architecture, Martin Fowler
- The Checklist Manifesto: How to Get Things Right, Atul Gawande
- How to Fail at Almost Everything and Still Win Big: Kind of the Story of My Life, Scott Adams

June
- Pragmatic Thinking and Learning, Refactor Your Wetware, Andy Hunt
- Testable JavaScript, Mark Ethan Trostler
- The Secrets of Consulting: A Guide to Giving & Getting Advice Successfully, Gerald M. Weinberg
- La desfachatez intelectual. Escritores e intelectuales ante la política, Ignacio Sánchez-Cuenca
- REST in Practice, Jim Webber, Savas Parastatidis and Ian Robinson
- Mindset, Carol Dweck

July
- The Call of the Wild, Jack London
- Weinberg on Writing: The Fieldstone Method, Gerald M. Weinberg
- Dinner at the Homesick Restaurant, Anne Tyler
- How to Solve It: A New Aspect of Mathematical Method, G. Polya
- Object Oriented Software Engineering: A Use Case Driven Approach, Ivar Jacobson
- A Far Cry from Kensington, Muriel Spark

August
- The Difference Engine, William Gibson and Bruce Sterling
- Clojure Applied, From Practice to Practitioner, Ben Vandgrift and Alex Miller
- Vampir, Joann Sfar
- Los mares del Sur, Manuel Vázquez Montalbán
- El océano al final del camino (The Ocean at the End of the Lane), Neil Gaiman
- La Guerra Civil Española, Paul Preston and José Pablo García
- Wiser: Getting Beyond Groupthink to Make Groups Smarter, Cass R. Sunstein and Reid Hastie

September
- And The Weak Suffer What They Must?: Europe, Austerity and the Threat to Global Stability, Yanis Varoufakis
- Clojure Reactive Programming, Leonardo Borges
- Designing Object-Oriented Software 1st ed., Rebecca Wirfs-Brock, Brian Wilkerson and Lauren Wiener
- Divina Comedia (Divina Commedia), Dante Alighieri

October
- David Copperfield, Charles Dickens
- Utopía (Utopia), Thomas More
- La pulga de acero (Сказ о тульском косом Левше и о стальной блохе), Nikolái Leskov
- Living Clojure, An Introduction and Training Plan for Developers, Carin Meier
- Buddha in Blue Jeans: An Extremely Short Zen Guide to Sitting Quietly and Being Buddha, Tai Sheridan

November
- De tu tierra (Paesi tuoi), El Camarada (Il Compagno), Cesare Pavese
- A Passage to India, E. M. Forster
- React: Up & Running. Building Web Applications, Stoyan Stefanov
- El relato de Arthur Gordon Pym (The Narrative of Arthur Gordon Pym of Nantucket),Edgar Allan Poe.

December
- The Remains of the Day, Kazuo Ishiguro
- Quiet: The Power of Introverts in a World That Can't Stop Talking, Susan Cain
- Robinson Crusoe, Daniel Defoe
- All you Zombies, Robert A. Heinlein

Saturday, December 24, 2016

An example of introducing symmetry to enable duplication removal

Symmetry is a subtle concept that may seem only related to code aesthetics. However, as Kent Beck states in Implementation Patterns,
"...finding and expressing symmetry is a preliminary step to removing duplication. If a similar thought exists in several places in the code, making them symmetrical to each other is a first good step towards unifying them"
In this post we'll look at an example of expressing symmetry as a way to make duplication more visible. This is the initial code of a version of a subset of the Mars Rover kata that Álvaro García and I used in a refactoring workshop some time ago:

This code is using conditionals to express two consecutive decisions:
  1. Which command to execute depending on a command code.
  2. How to execute the command depending on the direction the rover faces.
These decisions are repeated for different responsibilities, displacing the rover and rotating the rover, so the code presents a Case Statements smell. Since those decisions are completely independent, we could mechanically refactor the code to start using polymorphism instead of conditionals. This way we'll end having two consecutive single dispatches, one for each decision.

If we start applying Replace Type Code with State/Strategy refactoring to the code as it is now, there is a subtle problem, though.

Looking carefully more carefully, we can observe that in the case of the rover's displacement, the sequence of two decisions is clearly there:
However, that sequence is not there in the case of the rover's rotations. In this case there's a third decision (conditional) based on the command type which as, we'll see, is not necessary:
This difference between the two sequences of decisions reveals a lack of symmetry in the code. It's important to remove it before starting to refactor the code to substitute the conditionals with polymorphism.

I've seen many cases in which developers naively start extracting methods and substituting the conditionals with polymorphism starting from asymmetrical code like this one. This often leads them to create entangled and leaking abstractions.

Particularly, in this case, blindly applying Replace Type Code with State/Strategy refactoring to the left and right rotations can very likely lead to a solution containing code like the following:

Notice how the Direction class contains a decision based on the encoding of the command. To be able to take that decision, Direction needs to know about the encoding, which is why it's been made public in the Command class.

This is bad... Some knowledge about the commands encoding has leaked from the Command class into the Direction class. Direction shouldn't be taking that decision in the first place. Neither should it know how commands are encoded. Moreover, this is a decision that was already taken and doesn't need to be taken again.

How can we avoid this trap?

We should go back to the initial code and instead of mechanically applying refactoring, we should start by removing the asymmetry from the initial code.

You can see one way of doing it in this video:



After this refactoring all cases are symmetrical (they present the same sequence of decisions)
We've not only removed the asymmetry but we've also made more explicit the case statements (Case Statements smell) on the command encoding and the duplicated switches on the direction the rover is facing:

Now it's clear that the third decision (third nested conditional) in the original rover's rotations code was unnecessary.

If we start the Replace Type Code with State/Strategy refactoring now, it's more likely that we'll end with a code in which Direction knows nothing about how the commands are encoded:

and the encoding of each command is known in only one place:

As we said at the beginning, symmetry is a very useful concept that can help you guide refactoring. Detecting asymmetries and thinking why they happen, can help you to detect hidden duplication and, as in this case, sometimes entangled dimensions of complexity [1].

Then, by removing those asymmetries, you can make the duplication more visible and disentangle the entangled dimensions of complexity. The only thing you need is to be patient and don't start "obvious" refactorings before thinking a bit about symmetry.

[1] Dimension of Complexity is a term used by Mateu Adsuara in a talk at SocraCan16 to name an orthogonal functionality. In that talk he used dimensions of complexity to group the examples in his test list and help him choose the next test when doing TDD. He talked about it in this three posts: Complexity dimensions - FizzBuzz part I, Complexity dimensions - FizzBuzz part II and Complexity dimensions - FizzBuzz part III. Other names for the same concept that I've heard are axes of change, directions of change or vectors of change.

Sunday, December 18, 2016

Recorded talk about functions in Clojure (in Spanish)

Last Wednesday we did our third remote talk about Clojure as part of our small Clojure/ClojureScript study group.

This time we talked a bit about functions and we recorded it as well.

This is the resulting video:

You'll find the examples we used here.

Again I'd like to especially thank Ángel and Magento Barcelona for letting me do the talk from their office.

I hope you find it useful.

Thursday, December 1, 2016

Interesting Talk: "Code Symbiosis, a technical keynote"

I've just watched this wonderful talk by Michael Feathers

Recorded talk about destructuring in Clojure (in Spanish)

I recently started to work at Codesai.

Some members of the team wanted to learn Clojure, so we started a small Clojure/ClojureScript study group.

We created a slack called clojuresai where I'm posting some readings (we're reading Clojure for the Brave and True) and exercises (we're working through a selection of exercises from 4Clojure) each week and where they can ask doubts about the exercises and readings, and comment things they find interesting.

Some colleagues from the Clojure Developers Barcelona meetup that are beginning to learn clojure have also joined the study group.

Now and then, we do introductory talks using Google Hangouts (Codesai's team is distributed) to go deeper in some of the topics they've just read in the book.

So far we've done two talks. The first one was about Clojure collections. Unfortunately, we didn't record it, but you can find the examples we used here.

Today we did a second remote talk. This time it was about destructuring in Clojure, and since some of the members of the study group members weren't able to make it, we decided to record it.

This is the resulting video:

You'll find the examples we used in this previous post.

I'd like to especially thank Ángel and Magento Barcelona for letting me do the talk today from their office (their internet connection is much better than mine).

Recently, Miguel de la Cruz (thanks a million Miguel!!) has joined our study group as a tutor. He knows a lot of Clojure so he will help answering doubts and giving some talks that we'll hopefully share with you soon, as well.

Friday, November 25, 2016

Creating custom effects in re-frame

In previous posts, we learned how to use coeffects and effects in re-frame to have effectful event handlers that are pure functions.

The example with effects we saw, used two of re-frame's built-in effect handlers (dispatch and dispatch-later). Since the set of possible side-effects is open-ended, re-frame gives you a way to define your own effects.

In this post, we'll show how to create your own effect by defining one that writes to the local storage.

Let's have a look at an event handler using that effect that writes to the local storage:

Notice the a key-value pair having the key :write-localstore in the effects map returned by the event handler. This key-value pair is telling re-frame to do a side-effect, which is uniquely identified by that key and requires the data in the corresponding value. But, how does re-frame know how to action on the :write-localstore effect?

We have to use re-frame's reg-fx function to associate the effect key, (:write-localstore), with an effect handler, (local-store/write function):

reg-fx receives two arguments: the key that identifies the effect and the function which actions the side-effect, the effect handler.

When an event handler returns an effects map which contains a given effect key, the effect handler associated with it using reg-fx will be called to action on the effect, passing it the value associated to the effect key in the effects map.

The local-store/write function is passed a map containing the key-value pairs it has to write to the local store.

Finally, this is how we'd test the event handler using it:

being check-writing-to-local-storage-contains and check-writing-to-local-storage:

And that's all we need to know in order to create a custom effect in re-frame.

Thursday, November 17, 2016

Interesting Podcast: "Cognicast with Paul Stadig"

I've just listened to this great Cognicast podcast with Paul Stadig talking about about Polymorphism and other interesting things:

Quotes from "Why should physicists study history?"

My top highlights from the wonderful paper Why should physicists study history? by Matthew Stanley:
"History is not a list of names and dates. It's a way of thinking that can be powerful and illuminating."

"Social interactions really do influence what scientist produce."

"How a community tells its history changes the way it thinks about itself."

"A historical perspective on science can help physicists understand what is going on when they practice their craft, and it provides numerous tools that are useful for physicists themselves."

"Physics is a social endeavor."

"Research is done by people. And people have likes and dislikes, egos and prejudices. Physicists, like everyone else get attached to their favorite ideas and hang on them perhaps long after they should let them go."

"The history of science can help dismantle the myth of the purely rational genius living outside the everyday world. It makes physics more human."

"And a more human physics is a good thing. For starters, it makes physics more accessible."

"A field in which people are aknowledged as people is much more appealing than one in which they are just calculating machines."

"Physics only work when people talk to each other and communication s not always easy."

"Everything seems obvious in retrospect."

"The history of physics can remind us how difficult is to justify ideas that now seem obvious."

"Complexity, not simplicity , has ruled the practice of science."

"Every discovery has come out of a messy mix of people, ideas, accidents and arguments."

"Students and young researchers are often heartened to learn that physics is hard work and that it is ok for their own efforts not to look like a text-boo presentation. Messiness is a standard. Mistakes are normal. The results of physics are not self-evident."

"The history of physics suggests that there are usually several ways to approach a problem."

"Turning complexity into good physics requires creativity. You can never tell what weird idea will help clarify a confusing observation or provide the key to interpreting an equation. History uncovers the strange stew of concepts that were necessary for the development of physics."

"The interplay of various approaches is what brought us a modern view."

"Strange but ultimately useful perspectives come from fields and disciplines apparently distant from the problem at hand."

"The history of science shows how important it is for scientists across different fields to talk to each other. Conversations among separate groups are healthy. Apparently isolated problems are often closedly tied together, and you never know where you will find the weird idea that solves your difficulty."

"The best strategy for encouraging diverse ideas is to cultivate a diverse community."

"Underrepresented groups that offer different ways of thingking are often the source of fresh insights and novel methods."

"Underrepresented groups are usually marginalized because of cultural inertia or deliberate decisions made long ago."

"The diversity of ideas and interpretations serves as a reminder that physics is a work in progress. Knowledge is provisional. There are always new ways to tackle a problem, and there is always more to be learned."

"Accepting uncertainty would require changes in how science is taught."

"Curiosity should be revered, and everyone should be encouraged to ask, what else?"

"If scientist are not explicit and honest about their doubts, a crisis of confidence arises when that uncertainty is revealed."

"Physics wasn't always as it is."

"The flip side of accepting physics will be different in the future is accepting that it was different in the past. Everyone has a tendency to assume that the way things are now is the norm. But history makes it clear that things were not always this way. An understanding of why people used to think differently is a powerful tool for understanding people today. By drawing attention to older, usnpoken assumptions, history shows us how to start paying attention to our own."

"A knowledge of the historic and physical background, gives the kind of independence from prejudices of his generation from which most scientists are suffering" Einstein


"..they should study the history of those ideas and understand the circumstances in which they were justified and found useful."

"History trains you to think critically about received ideas. History provides evidence of roads not taken."

"Science's plurality of interpretation can make the history of science a resource for modern scientific research." Hasok Chang
"Complementary Science -> recovering forgotten and unsolved puzzles from the past."

"Putting complementary science into practice demands difficult self-examination. Thinking deeply about assumptions and accepted knowledge can be hard to do in professional scientific contexts, but history is a mode in which it's encouraged."

"The simple realization that people used to think differently can be quite powerful."

"Physics doesn't have rigid rules."

"Scientist simply don't follow a rigid, linear problem-solving system. Sometimes they start with a hypothesis, sometimes with a strange observation, sometimes with a weird anomaly in an otherwise straightforward experiment."

"... a scientist must be an "unscrupulous opportunist", adopting and adapting various approaches as new challenges arise."

"History teaches that knowledge is not fixed."

"Engaging with history will teach you to understand ideas on their own terms."

"Historical thinking makes its subject dynamic. It helps you think about science as a series of questions rather than a series of statements. Those questions will continue into the future, and it is helpful to know what has been asked so far." "In the end, history of science exposes scientists to new ways of thinking and forces them to reexamine what is already known. Such intellectual flexibility is essential for any discipline, but it's particularly important for fields as influential and authoritative as physics and other sciences."

Thursday, November 10, 2016

Using effects in re-frame

In re-frame, we'd like to use pure event handlers because they provide some important advantages, (mentioned in a previous post about coeffects in re-frame): local reasoning, easier testing, and events replay-ability.

However, as we said, to build a program that does anything useful, it's inevitable to have some side-effects and/or side-causes. So, there will be many cases in which event handlers won't be pure functions.

We also saw how using coeffects in re-frame allows to have pure event handlers in the presence of side-causes.

In this post, we'll focus on side-effects:
If a function modifies some state or has an observable interaction with calling functions or the outside world, it no longer behaves as a mathematical (pure) function, and then it is said that it does side-effects.
Let's see some examples of event handlers that do side-effects (from a code animating the evolution of a cellular automaton):

These event handlers, registered using reg-event-db, are impure because they're doing a side-effect when they dispatch the :evolve event. With this dispatch, they are performing an action at a distance, which is in a way a hidden output of the function.

These impure event handlers are hard to test. In order to test them, we'll have to somehow spy the calls to the function that is doing the side-effect (the dispatch). Like in the case of side-causes from our previous post, there are many ways to do this in ClojureScript, (see Isolating external dependencies in Clojure), only that, in this case, the code required to test the impure handler will be a bit more complex, because we need to keep track of every call made to the side-effecting function.

In this example, we chose to make explicit the dependency that the event handler has on the side-effecting function, and inject it into the event handler which becomes a higher order function. Actually, we injected a wrapper of the side-effecting function in order to create an easier interface.

Notice how the event handlers, evolve and start-stop-evolution, now receive as its first parameter the function that does the side-effect, which are dispatch-later-fn and dispatch, respectively.

When the event handlers are registered with the events they handle, we partially apply them, in order to pass them their corresponding side-effecting functions, dispatch-later for evolve and dispatch for start-stop-evolution:

These are the wrapping functions:

Now when we need to test the event handlers, we use partial application again to inject the function that does the side-effect, except that, in this case, the injected functions are test doubles, concretely spies which record the parameters used each time they are called:

This is very similar to what we had to do to test event handlers with side-causes in re-frame before having effectful event handlers (see previous post). However, the code for spies is a bit more complex than the one for stubs.

Using test doubles makes the event handler testable again, but it's still impure, so we have not only introduced more complexity to test it, but also, we have lost the two other advantages cited before: local reasoning and events replay-ability.

Since re-frame's 0.8.0 (2016.08.19) release, this problem has been solved by introducing the concept of effects and coeffects.

Whereas, in our previous post, we saw how coeffects can be used to track what your program requires from the world (side-causes), in this post, we'll focus on how effects can represent what your program does to the world (side-effects). Using effects, we'll be able to write effectful event handlers that keep being pure functions.

Let's see how the previous event handlers look when we use effects:

Notice how the event handlers are not side-effecting anymore. Instead, each of the event handlers returns a map of effects which contains several key-value pairs. Each of these key-value pairs declaratively describes an effect using data. re-frame will use that description to actually do the described effects. The resulting event handlers are pure functions which return descriptions of the side-effects required.

In this particular case, when the automaton is evolving, the evolve event handler is returning a map of effects which contains two effects represented as key/value pairs. The one with the :db key describes the effect of resetting the application state to a new value. The other one, with the :dispatch-later key describes the effect of dispatching the :evolve event after waiting 100 microseconds. On the other hand, when the automaton is not evolving, the returned effect describes that the application state will be reset to its current value.

Something similar happens with the start-stop-evolution event handler. It returns a map of effects also containing two effects. The one with the :db key describes the effect of resetting the application state to a new value, whereas the one with the :dispatch key describes the effect of immediately dispatching the :evolve event.

The effectful event handlers are pure functions that accept two arguments, being the first one a map of coeffects, and return, after doing some computation, an effects map which is a description of all the side-effects that need to be done by re-frame.

As we saw in the previous post about coeffectts, re-frame's effectful event handlers are registered using the reg-event-fx function:

These are their tests:

Notice how by using effects we don't need to use tests doubles anymore in order to test the event handlers. These event handlers are pure functions, so, besides easier testing, we get back the advantages of local reasoning and events replay-ability.

:dispatch and :dispatch-later are builtin re-frame effect handlers already defined. It's possible to create your own effect handlers. We'll explain how and show an example in a future post.

Interesting Paper: "Designing software for ease of extension and contraction"

I've just read this great paper by David L.Parnas

Wednesday, November 2, 2016

Codesai

I'm very happy to announce that I've joined Codesai's team.

Many reasons made my path converge with Codesai's one.

First of all, the people in Codesai.
I met Carlos in 2011, because he was teaching the first TDD course I attended. Carlos is a humble and honest person that tries very hard to make sure his actions match what he believes. Later I've known him as a quiet, open-minded leader who is always willing to listen what other people have to say, and this permeates the whole Codesai team. During the last two years, I had the opportunity to meet most of Codesai's apprentices. They are very enthusiastic and eager to learn. I had great fun participating with them in some Software Craftsmanship Gran Canaria events and talking about code and life in general in Codesai's apartment.

I share Codesai's values and feel very confortable with their culture and communication style because the team creates a healthy and safe environment which respects the diversity of its members and the debate of ideas.

I met the rest of the team last week during Codesai's summit (aka #flejesai16) and it was a confirmation that I'm in the right place.

Second, the opportunity to learn from experienced XP practicioners.
I've been developing software for 6 years now. I've learned a lot, most of it by reading books, practising on my own, attending courses and from colleagues, both from the community and at work. However, I felt the need of having a mentor, because I think I'll learn more and better than if I keep working on my own. I've found some great mentors in Codesai who acknowledge that I need a safe environment to get experience step by step.

Finally, the last reason is more personal.
I live in Barcelona but I'm from Canary Islands. Codesai is a remote-first team but the core of Codesai's team is currently in my hometown in the Canary Islands. So being a part of Codesai also gives me the chance of visiting my family more often.

So far I'm enjoying the Codesai experience a lot.

I think we'll keep on evolving as a team and do great things.

Thanks a million for letting me in!

Monday, October 24, 2016

Using coeffects in re-frame

Event handlers, collectively, provide the control logic in a re-frame application. Since the mutation of the application state is taken care of by re-frame, these event handlers can be pure functions that given the current value of the application state as first argument and the event (with its payload) as second argument, provide a new value for the application state.

This is important because the fact that event handlers are pure functions brings great advantages:
  • Local reasoning, which decreases the cognitive load required to understand the code.
  • Easier testing, because pure functions are much easier to test.
  • Events replay-ability, you can imagine a re-frame application as a reduce (left fold) that proceeds step by step. Following this mental model, at any point in time, the value of the application state would be the result of performing a reduce over the entire collection of events dispatched in the application up until that time, being the combining function for this reduce the set of registered event handlers.

However, to build a program that does anything useful, it's inevitable to have some side-effects and/or side-causes. So, there would be cases in which event handlers won't be pure functions.

In this post, we'll focus on side-causes.
"Side-causes are data that a function, when called, needs but aren't in its argument list. They are hidden or implicit inputs."
Let's see an example:

The event handler for the :word-ready-to-check event, that we are registering using reg-event-db, is not pure because it's using the value returned by JavaScript's Date.now function instead of getting it through its arguments. To make matters worse, in this particular case, this side-cause also makes the event handler untestable because JavaScript's Date.now function returns a different value each time it's called.

To be able to test this event handler we'll have to somehow stub the function that produces the side-cause. In ClojureScript, there are many ways to do this (using with-redefs, with-bindings, a test doubles library like CircleCI's bond, injecting and stubbing the dependency, etc.).

In this example, we chose to make the dependency that the handler has on a function that returns the current timestamp explicit and inject it into the event handler which becomes a higher order function.

In the previous code example, notice that the event handler now receives as its first parameter a function that returns the current timestamp, time-fn.

And this would be how before registering that event handler with reg-event-db, we perform a partial application to inject JavaScript's Date.now function into it:

Using the same technique, we can now inject a stub of the time-fn function into the event handler in order to test it:

This is the code of the home-made factory to create stubs for time-fn that we used in the previous test:

We've seen how using a test double makes the event handler testable again, but at the price of introducing more complexity.

The bottom line problem is that the event handler is not a pure function. This makes us lose not only the easiness of testing, as we've seen, but also the rest of advantages cited before: local reasoning and events replay-ability. It would be great to have a way to keep event handlers pure, in the presence of side-effects and/or side-causes.

Since re-frame's 0.8.0 (2016.08.19) release, this problem has been solved by introducing the concept of effects and coeffects. Effects represent what your program does to the world (side-effects) while coeffects track what your program requires from the world (side-causes). Now we can write effectful event handlers that keep being pure functions.

Let's see how to use coeffects in the previous event handler example. As we said, coeffects track side-causes, (see for a more formal definition Coeffects The next big programming challenge).

At the beginning, we had this impure event handler:

then we wrote a testable but still impure version:

Thanks to coeffects, we can eliminate the side-cause, passing the timestamp input through the argument list of the event handler. The resulting event handler is a pure function:

This event handler receives, as its first parameter, a map of coeffects, cofx, which contains two coeffects, represented as key/value pairs. One of them is the current timestamp which is associated to the :timestamp key, and the other one is the application state associated to the :db key. The second argument is, as in previous examples, the event with its payload.

The map of coeffects, cofx, is the complete set of inputs required by the event handler to perform its computation. Notice how the application state is just another coeffect.

This is the same event handler but using destructuring (which is how I usually write them):

How does this work? How does the coeffects map get passed to the event handler?

We need to do two things previously:

First, we register the event handler using re-frame's reg-event-fx instead of reg-event-db.

When you use reg-event-db to associate an event id with the function that handles it, its event handler, that event handler gets as its first argument, the application state, db.

While event handlers registered via reg-event-fx also get two arguments, the first argument is a map of coeffects, cofx, instead of the application state. The application state is still passed in the cofx map as a coeffect associated to the :db key, it's just another coeffect. This is how the previous pure event handler gets registered:

Notice the second parameter passed to reg-event-fx. This is an optional parameter which is a vector of interceptors. Interceptors are functions that wrap event handlers implementing middleware by assembling functions, as data, in a collection. They "can look after cross-cutting concerns helping to "factor out commonality, hide complexity and introduce further steps into the 'Derived Data, Flowing' story promoted by re-frame".

In this example, we are passing an interceptor created using re-frame's inject-cofx function which returns an interceptor that will load a key/value pair (coeffect id/coeffect value) into the coeffects map just before the event handler is executed.

Second, we factor out the coeffect handler, and then register it using re-frame's reg-cofx. This function associates a coeffect id with the function that injects the corresponding key/value pair into the coeffects map. This function is known as the coeffect handler. For this example, we have:

Since the event handler is now a pure function, it becomes very easy to test it:

Notice how we don't need to use tests doubles anymore in order to test it. Thanks to the use of coeffects, the event handler is a pure function, and we can just pass any timestamp to it in its arguments.

More importantly, we've also regained the advantages of local reasoning and events replay-ability that comes with having pure event handlers.

In future posts, we'll see how we can do something similar using effects to keep events handlers pure in the presence of side-effects.

Friday, October 7, 2016

Interesting Talk: "Leaving side effects aside"

I've just watched this wonderful talk by Juanma Serrano These are the slides.

Refactoring tests using builder functions in Clojure/ClojureScript

Using literals in your tests can have some advantages, such as, readability and traceability.

While this is true when the data are simple, it's less so when the data are nested, complex structures. In that case, using literals can hinder refactoring and thus become an obstacle to adapting to changes.

The problem with using literals for complex, nested data is that the knowledge about how to build such data is spread all over the tests. There are many tests that know about the representation of the data.

In that scenario, nearly any change in the representation of those data will have a big impact on the tests code because it will force us to change many tests.

This is an example of a test using literals, (from a ClojureScript application using re-frame, I'm developing with Francesc), to prepare the application state (usually called db in re-frame):

As you can see, this test knows to much about the structure of db.

There were many other tests doing something similar at some nesting level of the db.

To make things worse, at that moment, we were still learning a lot about the domain, so the structure of the db was suffering changes with every new thing we learned.

The situation was starting to be painful, since any refactoring provoke many changes in the tests, so we decided to fix it.

What we wanted was a way to place all the knowledge about the representation of the db in just one place (i.e., remove duplication), so that, in case we needed to change that representation, the impact of the change would be absorbed by changing only one place.

A nice way of achieving this goal in object-oriented code, and at the same time making your tests code more readable, is by using test data builders which use the builder pattern, but how can we do these builders in Clojure?

Option maps or function with keyword arguments are a nice alternative to traditional builders in dynamic languages such as Ruby or Python.

In Clojure we can compose functions with keyword arguments to get very readable builders that also hide the representation of the data.

We did TDD to write these builder functions. These are the tests for one of them, the db builder:

and this is the db builder code:

which is using associative destructuring on the function's optional arguments to have a function with keyword arguments, and creating proper default values using the :or keyword (have a look at the material of a talk about destructuring I did some time ago for Clojure Barcelona Developers community).

After creating builder functions for some other data used in the project, our test started to read better and to be robust against changes in the structure of db.

For instance, this is the code of the test I showed at the beginning of the post, but now using builder functions instead of literals:

which not only hides the representation of db but also eliminates details that are not used in particular tests, while still being as easy to read, if not easier, than the version using literals.

We have seen how, by composing builder functions and using them in our tests, we managed to reduce the surface of the impact that changes in the representation of data might have on our tests. Builder functions absorb the impact of those changes, and enable faster refactoring, and, by doing so, enable adapting to changes faster.

Interesting Talk: "Dependency management in Clojure"

I've just watched this great talk by Holger Schauer

Friday, September 30, 2016

Kata: Variation on Cellular Automata, animating automaton evolution using re-frame

In the last Clojure Developers Barcelona meetup, we started to use re-frame to animate in the browser the code to evolve cellular automata that we wrote some weeks ago.

We managed to make a rough version but we didn't have time to test it and make it nice.

When I got home I redid the exercise from scratch using a mix of TDD and REPL Driven Development.

First, I coded a couple of evolution rules. These are their tests:

and this is their code:

Next, I coded the cellular automata evolution, these are its tests:

and the resulting code:

Once I had the evolution working, I started to work on the view, using Figwheel and a hard-coded list of cellular automaton states on the db. This way I focused only on rendering the list of cellular automaton states.

With that working, I played on the REPL to create a subscriber that reacted to changes on the cellular automaton states making the view render.

This is the resulting code of the view:

the code of the subscriber:

and the default db:

Then, I used TDD to write the event handlers.

The use of effects keeps re-frame handlers pure. They allow us to avoid making side effects. We just have to describe as data the computation that will be made instead of doing it. re-frame takes care of that part.

These are the handlers tests:

these are the handlers:

Notice, how in order to dispatch to another handler (a side effect) we just have to add a key-value pair to the map of effects returned by the handler. In this case, I used the :dispatch and :dispatch-later effects which are part of re-frame's built-in effects. You can also create and register your own effects (I will talk about it in some future post).

To see the whole picture this is the code that registers the handlers:

I think that effects and coeffects (I'll talk about them in a future post) are just great!

They make testing handlers logic very easy (since handlers keep being pure functions) and avoid having to use test doubles.

Finally, everything is put together in the core namespace:

You can see the cellular automaton evolving in this video (I used garden library to add some CSS to make it look nicer):

You can find the code on this GitHub repository.

In this post I've tried to, somehow, describe the process I followed to write this code, but the previous gists just reflect the final version of the code. If you want to follow how the code evolved, have a look to all the commits on Github.

I really love using ClojureScript and re-frame with Figwheel.

Wednesday, September 28, 2016

Kata: Variation on Lights Out, a bit of FRP using reagi library

To finish with the series of exercises we've been doing lately around the Lights Out kata, I decided to use reagi library to raise the level of abstraction of the communications between the Lights and the LightsGateway components.

reagi is an FRP library for Clojure and ClojureScript which is built on top of core.async. I discovered it while reading Leonardo Borges' wonderful Clojure Reactive Programming book.

I started from the code of the version using the component library I posted recently about and introduced reagi. Let's see the code.

Let's start with the lights-gateway name space:

The main change here is that the ApiLightsGateway component keeps a lights-stream which it's initialized in its start function and disposed of in its stop function using reagi.

I also use, reagi's deliver function to feed the lights-stream with the response that is taken from the channel that cljs-http returns when we make a post request to the server.

Next,the lights name space:

Notice how the dependency on core.async disappears and the code to update the lights atom is now a subscription to the lights-stream (look inside the listen-to-lights-updates! function). This new code is much easier to read and is at a higher level of abstraction than the one using core.async in previous versions of the exercise.

Now the lights-view name space:

Here I also used reagi to create a stream of clicked-light-positions. Again the use of FRP makes the handling of clicks much simpler (in previous versions a callback was being used to do the same).

Another change to notice is that we made the view a component (LightsView component) in order to properly create and dispose of the clicked-light-positions stream.

Finally, this is the core name space where all the components are composed together:

This was a nice practice to learn more about doing FRP with reagi. I really like the separation of concerns and clarity that FRP brings with it.

You can find my code in these two GitHub repositories: the server and the client (see the master branch).

You can check the changes I made to use reagi here (see the commits made from the commit d51d2d4 (using a stream to update the lights) on).

Ok, that's all, next I'll start posting a bit about re-frame.

Tuesday, September 20, 2016

Kata: Variation on Lights Out, introducing component library

Recently at a Clojure Barcelona Developers event, we had a refactoring session in which we introduced Stuart Sierra's component library in a code that was already done: our previous solution to the Lights out kata.

First, we put the code in charge of talking to the back end and updating the lights atom in a separated component, ApiLightsGateway:

Then, we did the same for the lights code which was put in the Lights component:

This component provided a place to create and close the channel we used to communicate lights data between the Lights and the ApiLightsGateway components.

Next, we used the Lights component from the view code:

And, finally, we put everything together in the lights core name space:

This was a nice practice to learn more about component and what it might take to introduce it in an existing code base.

You can find the code we produced in these two GitHub repositories: the server and the client (see the componentization branch).

You can check the changes we made to componentize the code here (see the commits made on Aug 30, 2016).

As usual it was a great pleasure to do mob programming and learn with the members of Clojure Developers Barcelona.

Wednesday, September 14, 2016

Kata: Scrabble sets in Clojure

I recently did the Scrabble sets kata in Clojure.

I used a mix of a bit of TDD, a lot of REPL-driven development (RDD) following this cycle:
  1. Write a failing test (using examples that a bit more complicated than the typical ones you use when doing only TDD).
  2. Explore and triangulate on the REPL until I made the test pass with some ugly but complete solution.
  3. Refactor the code to make it more readable.
I'm founding that this way of working in Clojure is very productive for me.

These are the tests I wrote using Midje:

and this the resulting code:

See all the commits here if you want to follow the process.

You can find all the code on GitHub.

Monday, September 12, 2016

Kata: Parrot Refactoring in Clojure

I did Emily Bache's Parrot Refactoring Kata again (I did this kata in Java some time ago) but this time in Clojure. This is a very simple kata that is meant to practice the Replace Conditional with Polymorphism refactoring.

This is the initial code of the kata that have to be refactored:

Since Clojure provides several ways of achieving polymorphism, I did two versions of the kata:

- One using protocols:

This refactoring was a bit more involved than the one I did for the next version, but I managed to get rid of the exception and the resulting tests were more readable.

If you feel like following the refactoring process, check the baby steps in the commits. You can find the code in this GitHub repository.

- And another one using multimethods:

This version is much shorter and the refactoring is less involved than the previous one, but the resulting tests read much worse and the map representing the parrot has many "optional" entries.

Again, check the commits of the refactoring baby steps here, if you feel like following the refactoring process. You can find the code of this second version in this GitHub repository. I'd like to thank Emily Bache for sharing this kata.

Thursday, September 8, 2016

Mob Kata: Cellular Automata in Clojure

At this week's Clojure Developers Barcelona meetup, we did the Cellular Automata kata in Clojure.

We did mob programming and used a mix of TDD and RDD.

This is the code we wrote:

First, the tests using Midje for the rules 30 and 90:

and the tests for the evolution and rendering of automata:

This is the corresponding code for the rules:

and for the automaton evolution and rendering:

Printing on the REPL the result of rendering the Rule 90 automaton evolution during 15 steps, we obtain a nice Sierpinski triangle :

You can find the code in this GitHub repository.

As usual, it was a pleasure to meet and program with Clojure Developers Barcelona members.

Friday, September 2, 2016

Kata: Varint in Clojure using Midje and test.check

In last week's Barcelona Software Craftsmanship Dojo we did the Varint kata created by Eric Le Merdy.

Since I was facilitating it, I couldn't code during the event.

Once I got home, I did it using Clojure.

These are the tests using Midje and Clojure test.check libraries:

and this is the resulting code:

I used a mix of a bit of TDD, a lot of REPL-driven development (RDD) and some property-based testing.

Basically, the cycle I followed was like this:
  1. Write a failing test (using more complicated examples than the typical ones you use when doing only TDD).
  2. Explore and triangulate on the REPL until I made the test pass with some ugly complete solution.
  3. Refactor the code to make it more readable.
I've noticed that when I mix TDD and RDD, I end up doing bigger steps and keeping less tests than when doing only TDD. I think this is because most of the baby steps and "triangulation tests" are done on the REPL which gives you a much faster feedback cycle.

This way I wrote both encode and decode functions.

Once I had then working with a few examples, I added property-based tests using Clojure test.check library (a QuickCheck like library for Clojure) to automatically explore more examples by checking that the property of "decoding and encoded number returns the number" held for 1000 randomly generated examples.

I think that these three techniques are complementary and its combination makes me more productive.

To document the development process I commit after each TDD green step and after each refactoring. I also committed the REPL history.

See all the commits here if you want to follow the process.

You can find all the code on GitHub.

Thursday, August 25, 2016

Books I read (January - August 2016)

January
- El Eternauta, Héctor Germán Oesterheld and Francisco Solano López
- Barcelona. Los vagabundos de la chatarra, Jorge Carrión and Sagar Fornies
- Rip Van Winkle, Washington Irving
- La guerra interminable (The Forever War), Joe Haldeman
- Maintanable JavaScript, Nicholas C. Zakas
- Ve y pon un centinela (Go Set a Watchman), Harper Lee
- El nombre del viento (The Name of the Wind), Patrick Rothfuss
- You Don't Know JS: Async & Performance, Kyle Simpson
- Sapiens: A Brief History of Humankind, Yuval Noah Harari
- The Principles of Object Oriented JavaScript, Nicholas C. Zakas

February
- The Leprechauns of Software Engineering, Laurent Bossavit
- The Wise Man's Fear, Patrick Rothfuss
- Fundamentals of Object-Oriented Design in UML, Meilir Page-Jones
- Old Man's War, John Scalzi
- Cevdet Bey e hijos (Cevdet Bey ve Oğulları), Orhan Pamuk
- Ringworld, Larry Niven
- Why Nations Fail: The Origins of Power, Prosperity, and Poverty, Daron Acemoglu and James A. Robinson

March
- The Grumpy Programmer's Guide To Building Testable PHP Applications, Chris Hartjes
- The Grapes of Wrath, John Steinbeck
- The Coding Dojo Handbook, Emily Bache
- Fahrenheit 451, Ray Bradbury

April
- Implementation Patterns, Kent Beck (3rd time)
- The Power of Habit: Why We Do What We Do in Life and Business, Charles Duhigg
- How to Win Friends and Influence People, Dale Carnegie
- Understanding the Four Rules of Simple Design, Corey Haines (2nd time)
- La llamada de Cthulhu (The Call of Cthulhu), El horror de Dunwich (The Dunwich Horror) and Las ratas en las paredes (The Rats in the Walls), H. P. Lovecraft
- The Tales of Beedle the Bard, J. K. Rowling

May
- The Slow Regard of Silent Things, Patrick Rothfuss
- Building Microservices, Designing Fine-Grained Systems, Sam Newman
- Man's Search for Meaning, Viktor Frankl
- Manifiesto del Partido Comunista (Das Kommunistiche Manifest), K. Marx and F. Engels
- Web Development with Clojure, Build Bulletproof Web Apps with Less Code, Dimitri Sotnikov
- Patterns of Enterprise Application Architecture, Martin Fowler
- The Checklist Manifesto: How to Get Things Right, Atul Gawande
- How to Fail at Almost Everything and Still Win Big: Kind of the Story of My Life, Scott Adams

June
- Pragmatic Thinking and Learning, Refactor Your Wetware, Andy Hunt
- Testable JavaScript, Mark Ethan Trostler
- The Secrets of Consulting: A Guide to Giving & Getting Advice Successfully, Gerald M. Weinberg
- La desfachatez intelectual. Escritores e intelectuales ante la política, Ignacio Sánchez-Cuenca
- REST in Practice, Jim Webber, Savas Parastatidis and Ian Robinson
- Mindset, Carol Dweck

July
- The Call of the Wild, Jack London
- Weinberg on Writing: The Fieldstone Method, Gerald M. Weinberg
- Dinner at the Homesick Restaurant, Anne Tyler
- How to Solve It: A New Aspect of Mathematical Method, G. Polya
- Object Oriented Software Engineering: A Use Case Driven Approach, Ivar Jacobson
- A Far Cry from Kensington, Muriel Spark

August
- The Difference Engine, William Gibson and Bruce Sterling
- Clojure Applied, From Practice to Practitioner, Ben Vandgrift and Alex Miller
- Vampir, Joann Sfar
- Los mares del Sur, Manuel Vázquez Montalbán
- El océano al final del camino (The Ocean at the End of the Lane), Neil Gaiman
- La Guerra Civil Española, Paul Preston and José Pablo García
- Wiser: Getting Beyond Groupthink to Make Groups Smarter, Cass R. Sunstein and Reid Hastie

MOOCs: Machine Learning on Coursera

I recently finished this wonderful Coursera course by Andrew Ng of Stanford University: I really enjoyed the course. It was very interesting. Andrew Ng did a great job introducing machine learning, data mining, and statistical pattern recognition.

I would like to thank Coursera and Andrew Ng for this great course!

Wednesday, August 24, 2016

Kata: Variation on Lights Out, flipping behavior on the backend

Lately, in Clojure Developers Barcelona's events, we've been practicing by doing several variations on the Lights Out Kata.

First, we did the kata in ClojureScript using Reagent and Figwheel (described in this previous post).

In the last two meetups (this one and this other one), we redid the kata.

This time instead of doing everything on the client, we used the Compojure library to develop a back end service that reset and flipped the lights, and a simple client that talked to it using cljs-http and core.async libraries.

As we've been doing lately, we did mob programming and REPL-driven development.

First, let's see the code we did for the server:

These are the tests:

and this is the definition of the routes and their handlers using Compojure:

We had some problems with the Same-origin policy until we discovered and learned how to use the Ring middleware for Cross-Origin Resource Sharing.

Finally, this is the code that flips and resets the lights (it's more or less the same code we wrote for the client-only version of the kata we did previously):


Now, let's see the code we wrote for the client:

First, the core namespace where everything is initialized (notice the channel creation on line 12):

Then the lights-view namespace which contains the code to render all the components:

The lights-view's code is also very similar to the one we did for the client-only version of the kata.

And finally the lights namespace which is in charge of talking to the back end and updating the lights atom:

Notice how we used the pipe function to take the values that were coming from the channel returned by the call to cljs-httphttps://github.com/r0man/cljs-http's post function and pass them to the channel from which the code that updates the lights state is taking values.

You can find the code we produced in these two GitHub repositories: the server and the client (see the flip-lights-in-backend branch).

As usual it was a great pleasure to do mob programming and learn with the members of Clojure Developers Barcelona.

MOOCs: Networking for Web Developers on Udacity

I recently finished this Udacity course: I found it very interesting. I did it, mainly, because I'd like to start filling some gaps in my knowledge about the stack of networking protocols under the hood of HTTP.

After the course, I've started to read Ilya Grigorik's High Performance Browser Networking book bit by bit.

Thanks a million Udacity!

Tuesday, August 16, 2016

Kata: Lights Out in ClojureScript using Reagent and Figwheel

In a recent Clojure Developers Barcelona event we did the Lights Out Kata in ClojureScript using Reagent (a minimalistic ClojureScript interface to React.js) and Figwheel (which builds your ClojureScript code and hot loads it into the browser as you are coding).

We did mob programming and REPL-driven development.

Once at home I went on working on the kata.

This is the resulting code:

First, the core namespace where everything is initialized:

The lights-view namespace which contains the code to render all the components:

Finally, the lights namespace which contains all the business logic:

You can check all the code in the everything-in-client branch of this GitHub repository.

As usual it was a great pleasure to do mob programming with the members of Clojure Developers Barcelona.

Thanks!

Monday, August 15, 2016

Kata: Bank Account in Clojure using outside-in TDD with Component and Midje

I did the Printing Account Statement subset of the Bank Account kata in Clojure using Component and Midje.

I started the kata in a Barcelona Clojure Developers event.

The truth is that, since I was learning how to use the Component library, I didn't use TDD.

Instead I worked on the REPL to get everything in place and make it work.

Then I wrote the tests I would have liked to write if I had used outside-in TDD with Midje.

I find that, when I'm learning something new, it works better for me what Brian Marick describes in these tweets: Now I'll show you the tests I actually wrote afterwards, in the order I would have written them doing outside-in TDD.

This is the acceptance test I would have started with:

Then I would have written this unit test for Account:

And these are the ones for InMemoryTransactions, ConsoleStatementPrinter and NiceReverseStatementFormat:

You can check the rest of the tests and code in this GitHub repository.

Doing this kata I learned and practiced how to use Component.

I also learned how to use Midje's defrecord-openly and provided macros to mock protocols which helped me correct something I did wrong in another kata.

Tuesday, August 2, 2016

Interesting Paper: "'Claro!': An Essay on Discursive Machismo"

I've just read this wonderful paper by Diego Gambetta this great paper talks about how "Claro!" attitudes in communication, "characterized by strong opinions on everything from the outset of discussion", and the set of beliefs about knowledge behind them can make impossible to get to positive results in group deliberative processes.

A very interesting concept I got to know through Ignacio Sánchez-Cuenca's La desfachatez intelectual. Escritores e intelectuales ante la política book.

Unfortunately, "Claro!" attitudes are widespread in our culture...

Interesting Talk: "Doing data science with Clojure: the ugly, the sad, the joyful,"

I've just watched this interesting talk by Simon Belak

Thursday, July 28, 2016

Revisited Kata: Using Midje's defrecord-openly to mock a protocol in Ohce

Several weeks ago I did the Ohce kata in Clojure using outside-in TDD with Midje (as I explained in a previous post).

In that post I said that I hadn't used Midje's defrecord-openly and provided macros and had instead decided to write my own code to capture the arguments with which the functions of the Notifier protocol implementation were being called because:
... I didn't like having to use defrecord-openly in production code.
Well, I was wrong!

It turns out that it is not necessary at all to use defrecord-openly in your production code in order to mock a protocol.

I understood it thanks to this answer in Stak Overflow: Mocking Clojure protocols.

The only thing I needed to do was to use defrecord-openly to create a fake implementation of the Notifier protocol inside the test code like this:

and then write the tests against this unimplemented fake.

This are the new Ohce tests:

As you can see it's very easy to use Midje's defrecord-openly to mock protocols.

I just misunderstood Midje's documentation the first time I tried to do it...

Friday, July 22, 2016

Interesting Paper: "Why should physicists study history?"

I've just read this wonderful paper by Matthew Stanley This is a gem full of wonderful ideas about diversity, group dynamics, critical thinking and the pursue of knowledge that I think are also valuable to software development and, probably, to any team or community effort.

Tuesday, July 19, 2016

Revisited Kata: Listening to the tests to improve the design of Ohce

A couple of weeks ago, I did the the Ohce kata in a Barcelona Software Craftsmanship event (I wrote a previous post about it).

I wasn't happy with the resulting tests for the Ohce class:

What I didn't like about the tests was that they weren't independent from each other.

When I started doing TDD, they were independent, but as soon as I introduced the loop to request more user phrases, I had to stub a call to the PhraseReader in each test that returned the stop phrase to avoid infinite loops.

This made the tests to be very coupled to Ohce's implementation:

Another problem was a violation of the Law of Demeter caused by asking the Phrase value object, being returned by the PhraseReader, if it was a palindrome.

This made it necessary to stub some calls to the PhraseReader returning dummy phrases to avoid getting null pointer exceptions.

These problems in the tests were a signal of problems in the design (see What the tests will tell you).

I think there were two main problems:
  • Ohce code had too many responsibilities.
    • Controlling the dialog with the user.
    • Responding to the user inputs.
  • Ohce code was too procedural.

How could I fix them?

Well, I started thinking about a metaphor in which Ohce was having a dialog with the user and responded to each user phrase, and how this dialog might be infinite unless the user made it stop by introducing an stop phrase.

This made me realize that there were some missing abstractions.

So I decided to explore this metaphor of an infinite dialog comprised of responses to each user phrase:

InfiniteDialog only had the responsibility of going on reading and responding to the user phrases until told to stop.

Going on with the metaphor, each of those responses to the user input might be seen a sequence of two responses: one that reversed the user phrase and another one that celebrated when the user phrase was a palindrome.

To compose several independent responses, I used a decorator:

Then I just needed to separately code each concrete response:

Notice how all the tests in InfiniteDialogTest, SequenceOfResponsesTest, ReversingResponseTest and PalindromeResponseTest were just adaptations of tests that were originally in OhceTest, only that now they were much more focused and simple.

I regard this as a sign of design improvement.

Finally, I refactored the code to make Ohce start using the InfiniteDialog by applying parallel change. It was a very smooth refactoring during which no tests were broken.

I think that this smoothness was a special case, because all the expectations in old Ohce's tests were also satisfied using InfiniteDialog. Using InfiniteDialog just added some new layers of abstraction over old Ohce's collaborators, but behind those layers the old collaborations were still happening.

In a different case, I might have probably broken some Ohce's unit tests, but that wouldn't have been a problem because the behavior would have been still protected by the end-to-end tests. So, I could have just deleted the broken unit tests and written a new one for the collaboration between Ohce and Dialog.

These were the new tests for Ohce:

And this is its new code:

We've seen how listening to some problems in Ohce's tests, led me to find some design problems, that once fixed produced much more focused, clearer and less coupled tests, and how having used mocks didn't suppose any problem at all during the whole refactoring process.

--------------------

You can find all the code in this GitHub repository.