Showing posts with label Clojure Developers Barcelona Group. Show all posts
Showing posts with label Clojure Developers Barcelona Group. Show all posts

Monday, March 25, 2019

Our experience at ClojureBridge Bilbao 2018

ClojureBridge is an all-volunteer organization inspired by RailsBridge that provides free, introductory workshops to increase diversity in the Clojure community. I first learned about ClojureBridge thanks to a talk by Ali King at EuroClojure 2015 in Barcelona: ClojureBridge, Building a more diverse Clojure community. I really liked the idea and we (the Clojure Developers Barcelona) tried to organize one in Barcelona, but failed to actually do it because we lacked the numbers, money and time. So the moment I knew that my colleague at GreenPowerMonitor, Estíbaliz Rodríguez, and the company where she works, Magnet, were planning to organize a ClojureBridge edition in Bilbao for December 1st 2018, I decided to do my best to help.

ClojureBridge 2018 Bilbao introduction

I met Estíbaliz and José Ayudarte at the beginning of last summer, when they started working as ClojureScript developers for GreenPowerMonitor, and it’s been a great experience to work with them. They are part of Magnet which is a cooperative of developers, designers and consultants that work with Clojure and ClojureScript. Magnet’s team is distributed across Europe but most of them live in the Basque country.

I told them I’d like to participate as a volunteer. Actually I had already bought the tickets and booked an accommodation for that weekend before asking them. In the worst-case scenario, if I couldn’t participate in ClojureBridge, I’d at least spend a weekend in Bilbao which is a wonderful city. In the end, everything went well and they told me they were delighted to have me there. I participated in a couple of meetings to know the other volunteers and talk about how the event would be structured, the mentoring and the exercises. Magnet was sponsoring the event and most of its team worked very hard to make it possible.

So, on December 1st I was there trying to help people learn a bit of Clojure. There were many women and girls with very diverse backgrounds: professional developers that were using other languages, teenagers with a bit of programming experience from school or without, little girls and women of all ages that had no programming experience. At the beginning, Usoa Sasigain gave a talk to introduce ClojureBridge's goal of increasing diversity in technology, the important role women had played in the history of computer science and technology, and Clojure. She also talked about her personal history with technology and Clojure, and explained how technology might be a nice career option for women.

ClojureBridge 2018 Bilbao Grace Hopper slide

After the introduction, the participants were splitted in groups according to their programming experience. I was assigned to help the group of experienced software developers. They worked through the exercises in Maria Cloud which is a beginner-friendly coding environment for Clojure and I answered to questions about Clojure and helped when they got stuck. I think they got to appreciate Clojure and the possibilities it offers. We did several coffee breaks during the morning and for lunch in which we could talk about many things and I had the opportunity to meet Asier Galdós, Amaia Guridi, Iván Perdomo and other members of Magnet. The lunch was very nice and sponsored by Magnet.

At the end of the first half of the event, some attendees had to go to have lunch with their families. A funny and lovely anecdote for me happened when two girls of about six or eight years old that had been enthusiastically programming all morning didn’t want to stop and leave with their parents for lunch. I remember with a lot of tenderness seeing them totally engrossed in programming during the morning and celebrating with raised arms every time they succeeded in changing the color or any other feature of the shapes they were working with in Maria Cloud’s exercises.

During the afternoon, we continue working on more advanced Maria Cloud exercises. There were less people, so I changed to work with some women that had no previous experience with programming. It was a very nice experience and we had a good time going through some more Maria cloud’s exercises playing with shapes.

ClojureBridge 2018 Bilbao John McCarthy slide

All in all, volunteering in ClojureBridge was a very beautiful experience for me. I enjoyed helping people to learn Clojure and programming, and met many nice people with many different backgrounds. I learned several words in basque language. I also had some very interesting conversations with Asier, Usoa, José and Iván about Clojure, Magnet’s experience as a Clojure/ClojureScript cooperative and the interesting platform, Hydrogen, that they are building. We also talked about my doing a desk surfing with them, an idea that I was really excited about, but, unfortunately, I haven’t been able to do yet because I recently started working for a new client in Barcelona.

Before finishing I’d like to thank Magnet for making the first ClojureBridge in Spain possible and for letting me help. I’d also like to send love and good energy to Estíbaliz. I hope you recover soon and we can meet each other in Euskadi or somewhere else.

Saturday, March 10, 2018

Kata: Generating bingo cards with clojure.spec, clojure/test.check, RDD and TDD

Clojure Developers Barcelona has been running for several years now. Since we're not many yet, we usually do mob programming sessions as part of what we call "sagas". For each saga, we choose an exercise or kata and solve it during the first one or two sessions. After that, we start imagining variations on the exercise using different Clojure/ClojureScript libraries or technologies we feel like exploring and develop those variations in following sessions. Once we feel we can't imagine more interesting variations or we get tired of a given problem, we choose a different problem to start a new saga. You should try doing sagas, they are a lot of fun!

Recently we've been working on the Bingo Kata.

The initial implementation

These were the tests we wrote to check the randomly generated bingo cards:

and the code we initially wrote to generate them was something like (we didn't save the original one):

As you can see the tests are not concerned with which specific numeric values are included on each column of the bingo card. They are just checking that they follow the specification of a bingo card. This makes them very suitable for property-based testing.

Introducing clojure.spec

In the following session of the Bingo saga, I suggested creating the bingo cards using clojure.spec.
spec is a Clojure library to describe the structure of data and functions. Specs can be used to validate data, conform (destructure) data, explain invalid data, generate examples that conform to the specs, and automatically use generative testing to test functions.
For a brief introduction to this wonderful library see Arne Brasseur's Introduction to clojure.spec talk.

I'd used clojure.spec at work before. At my current client Green Power Monitor, we've been using it for a while to validate the shape (and in some cases types) of data flowing through some important public functions of some key name spaces. We started using pre and post-conditions for that validation (see Fogus' Clojure’s :pre and :post to know more), and from there, it felt as a natural step to start using clojure.spec to write some of them.

Another common use of clojure.spec specs is to generate random data conforming to the spec to be used for property-based testing.

In the Bingo kata case, I thought that we might use this ability of randomly generating data conforming to the spec in production code. This meant that instead of writing code to randomly generating bingo cards and then testing that the results were as expected, we might describe the bingo cards using clojure.spec and then took advantage of that specification to randomly generate bingo cards using clojure.test.check's generate function.

So with this idea in our heads, we started creating a spec for bingo columns on the REPL bit by bit (for the sake of brevity what you can see here is the final form of the spec):

then we discovered clojure.spec's coll-of function which allowed us to simplify the spec a bit:

Generating bingo cards

Once we thought we had it, we tried to use the column spec to generate columns with clojure.test.check's generate function, but we got the following error:
ExceptionInfo Couldn't satisfy such-that predicate after 100 tries.
Of course we were trying to find a needle in a haystack...

After some trial and error on the REPL and reading the clojure.spec guide, we found the clojure.spec's int-in function and we finally managed to generate the bingo columns:

Then we used the spec code from the REPL to write the bingo cards spec:

in which we wrote the create-column-spec factory function that creates column specs to remove duplication between the specs of different columns.

With this in place the bingo cards could be created in a line of code:

Introducing property-based testing

Property-based tests make statements about the output of your code based on the input, and these statements are verified for many different possible inputs.
Jessica Kerr (Property-based testing: what is it?)
Having the specs it was very easy to change our bingo card test to use property-based testing instead of example-based testing just by using the generator created by clojure.spec:

See in the code that we're reusing the check-column function we wrote for the example-based tests.

This change was so easy because of:
  1. clojure.spec can produce a generator for clojure/test.check from a given spec
  2. .
  3. The initial example tests, as I mentioned before, were already checking the properties of a valid bingo card. This means that they weren't concerned with which specific numeric values were included on each column of the bingo card, but instead, they were just checking that the cards followed the rules for a bingo card to be valid.

Going fast with REPL driven development (RDD)

The next user story of the kata required us to check a bingo card to see if its player has won. We thought this might be easy to implement because we only needed to check that the numbers in the card where contained by the set of called numbers, so instead of doing TDD, we played a bit on the REPL did REPL-driven development (RDD):

Once we had the implementation working, we copied it from the REPL into its corresponding name space

and wrote the quicker but ephemeral REPL tests as "permanent" unit tests:

In this case RDD allowed us to go faster than TDD, because RDD's feedback cycle is much faster. Once the implementation is working on the REPL, you can choose which REPL tests you want to keep as unit tests.

Some times I use only RDD like in this case, other times I use a mix of TDD and 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.
Other times I just use TDD.

I think what I use depends a lot on how easy I feel the implementation might be.

Last details

The last user story required us to create a bingo caller that randomly calls out Bingo numbers. To develop this story, we used TDD and an atom to keep the not-yet-called numbers. These were our tests:

and this was the resulting code:

And it was done! See all the commits here if you want to follow the process (many intermediate steps happened on the REPL). You can find all the code on GitHub.

Summary

This experiment was a lot of fun because we got to play with both clojure.spec and clojure/test.check, and we learned a lot. While explaining what we did, I talked a bit about property-based testing and how I use REPL-driven development.

Thanks again to all my colleagues in Clojure Developers Barcelona!

Friday, November 17, 2017

Native/Browser SPA versions using ClojureScript and re-frame talk at SCBCN17

Last month I had the pleasure of giving a talk at the Software Craftsmanship Barcelona 2017 conference about what my colleague Francesc and I have been learning lately while working on the mobile and browser versions of a SPA using ClojureScript and re-frame.

I talked mainly about how re-frame's effects and coeffects, re-frame's subscriptions and modelling a UI as FSMs place you in a pit of success, i. e., a design that, according to Jeff Atwood, "makes it easy to do the right things and annoying (but not impossible) to do the wrong things".

It was my first talk in a big conference and I had some technical problems, so I was very nervous at the beginning. After a while I relaxed and felt better. In the end I received more questions than I expected and very nice feedback.

I'd like to thank Modesto for lending me his computer when mine crashed just before the talk and helping me relax.

This is the video of the talk, (thanks Autentia for recording all the talks and for being so kind to me when I was having technical difficulties). I hope you'll find it interesting:



and these are the slides that I've improved after the talk using Modesto's feedback (thanks!!): .

Thanks to Francesc and all the people in Clojure Developers Barcelona Group, Green Power Monitor and Codesai that contributed to improve the talk with their feedback. Also thanks to my colleague Antonio for "persuading" me to give a talk in a conference.

Finally, I'd also like to thank Software Craftsmanship Barcelona 2017 conference organizers for giving me the opportunity to talk at such a great conference and for all the effort they put to make this conference better, edition after edition.

Thursday, February 9, 2017

Recorded talk about sequence comprehensions in Clojure (in Spanish)

Today we did our fourth remote talk about Clojure as part of our small Clojure/ClojureScript study group.

This time we talked about sequence comprehensions 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 for his help and patience.

I hope you'll find it useful.

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

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, 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.

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.

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.

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.

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.

Thursday, February 4, 2016

Friday, January 29, 2016

Kata: Alphabet Cipher in Clojure

I just redid the Alphabet Cipher kata from the fantastic Carine Meier's Living Clojure book.

I had done it some time ago with Eloi Poch and Rafa Gómez (thanks guys I had a great time) at a Clojure Developers Barcelona event.

These are the tests using Midje:

and this is the final code:

I used a mix of TDD and REPL-driven development committing after each green and each refactoring.
What I did was tinkering in the REPL to get rough versions of encode, decode and decipher functions. This kind of tinkering is getting more and more fun, the more I get used to working in the REPL.
Once I had the rough version I just copied it directly on the code, stabilized it with some tests and started to refactor it until it seemed a bit more readable to me.

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

You can find all the code on GitHub.

Wednesday, August 5, 2015

Kata: Print Diamond in Clojure

Yesterday we did the Print Diamond kata in the Clojure Developers Barcelona group.

I paired with Rafa Gómez. We managed to complete a recursive solution to the problem using our usual mix of TDD and REPL-driven development.

Later, we showed our solution and realize that, even though, it worked fine, we had to improve the names of some helper functions we had created to make our solution easier to understand.

After that, Samuel Lê, presented on the whiteboard (we couldn't connect his laptop to the projector) a completely different and very elegant approach.

I'll try to explain it:

Say, for instance, that you're trying to create the diamond for D.

You first create the following sequence repeating the string "DCBABCD" as many times as lines there are in the diamond:

Only one letter is allowed to appear in each line of the diamond.

Let's represent this in a table:

Now the only thing we have to do to get the correct diamond lines is to substitute by a space (we used an underscore to make it easier to visualize) every letter of the line that is different from the allowed letter for that line:

This is a very elegant approach that only uses sequences functions.

When I got back home I redid the kata again using both approaches: the recursive one and the one that Samuel had explained on the whiteboard.

These are the tests I used to test drive the recursive code (sorry I can't show the REPL history because I haven't found where Cursive saves it):

I'm using an underscore instead of a space to make the results easier to visualize.

This is the recursive code:

Then I deleted the recursive code and started playing in the REPL to build a new solution following Samuel's approach and using the previous tests as acceptance tests to know when I was done.

Once I had it working again:

I refactored the code a bit introducing some helpers to separate responsibilities and make the code more readable and renamed some bindings.

This is the resulting code:

You can find all the code in this GitHub repository.

As usual the Clojure meetup and the conversations having a drink afterwards have been both great fun and very interesting.

We also met Alejandro Gómez which is writing this great ClojureScript book and has recently moved to Barcelona.

Wednesday, May 13, 2015

Thursday, April 30, 2015

Clojure Developers Barcelona: Short talk about sequence comprehensions

Last Tuesday I gave a short talk about sequence comprehensions in Clojure for some of the Clojure Developers Barcelona study group members.

This is the "clean version" of the code I wrote on Lightable to explain it:

As usual I had a great time and learned a lot preparing this talk.

After the talk, we talked about topics we'd like to learn about in the next months and the started to practice in pairs programming the String Calculator kata.

Thanks all for coming!

Saturday, April 18, 2015

Kata: Gilded Rose in Clojure (III) -> Updating conjured items by decoration

After the two previous posts (Clarifying conditional logic and Replacing conditional with polymorphism using multimethods), I had this version of the code:

that was being used from the gilded-rose.core name space:

Then I started introducing the new conjured items functionality using TDD.

These are the new tests for conjured items:

and these is the resulting code of the gilded-rose.item-quality name space:

Notice the change in the update multimethod dispatch function. Now instead of being :name as before, it's the function type-of-item that returns the dispatch value :conjured if the item is a conjured one (i. e., if its name contains "Conjured"), or the type of item corresponding to each item name otherwise (which it looks up in the item-types-by-name map).

I also added a defmethod for the :conjured dispatch values which decorates update by calling it twice passing the not conjured version of the item and modified the other defmethod functions to use the type of item instead of its name. This made possible a better way of removing the duplication for regular items than the previous update-regular-item-quality private function.

This simple decoration made all the tests shown before pass, except the "Conjured Sulfuras is still immutable" one. For this test to pass I had to modify the degradable-item? query in the gilded-rose.core name space:

That's all. You can follow the whole process I've just described having a look at the commits I did after every small refactoring (look at commits from Conjured items quality decreases by two each day before sell date on)

Starting from the polymorphic version of update, we had got through refactoring, made it easy to add the new conjured items functionality as a decoration of update.

Compare this Clojure version of Gilded Rose with the Java version I did some time ago.

This is the last post in this series about the Gilded Rose kata in Clojure:
  1. Clarifying conditional logic
  2. Replacing conditional with polymorphism using multimethods
  3. Updating conjured items by decoration

Kata: Gilded Rose in Clojure (II) -> Replacing conditional with polymorphism using multimethods

At the end of the previous post (Clarifying conditional logic), I had this version of the code:

Even though the conditional logic in the update-item-quality function read much better than the original one, I completely got rid of it using the replace conditional with polymorphism refactoring. I used multimethods which is one of the ways of achieving polymorphism in Clojure.

To start this refactoring, I first renamed the update-item-quality function to update-item-quality-old. Then I created a multimethod called update-item-quality with :name as dispatch function and with a method associated to its default dispatch that called the update-item-quality-old function:

This new version behaved exactly like the previous one and it was a good base to do the refactoring in small steps (one branch at a time) because every dispatch value not associated yet with a function was calling the old code thanks to the default dispatch.

Next I wrote a defmethod associated to the Age Brie item, copied the code from the Age Brie branch in update-item-quality-old into it and deleted the branch and the aged-brie? query helper. After this change all the tests were still passing.

Then I continued eliminating the rest of the branches in the cond of the update-item-quality-old function and their associated query functions.

Once I finished wit all the branches, I had replaced the conditional with polymorphism and could safely delete update-item-quality-old. I also changed the method associated with the default dispatch to make it just returned the received item (this was what got executed for the Sulfuras item and it corresponded to the :else branch of the cond in the old code).

To finish the refactoring I extracted the update-regular-item-quality helper to remove some duplication in some defmethods and moved the code that updated the quality into a separate name space, gilded-rose.item-quality:

You can follow the whole process I've just described having a look at the commits I did after every small refactoring (look at commits between Introduced a multimethod which now it's defaulting to the old update item quality function and Added helper to make all items age one day)

After this refactoring I had a nice polymorphic solution that made it easier to add the new conjured items functionality.

The next and last post will show how I modified the multimethod dispatch function to decorate the update quality behavior when it was updating a conjured item.

This is the second post in a series of posts about the Gilded Rose kata in Clojure:
  1. Clarifying conditional logic
  2. Replacing conditional with polymorphism using multimethods
  3. Updating conjured items by decoration

Kata: Gilded Rose in Clojure (I) -> Clarifying conditional logic

Yesterday I did the Gilded Rose refactoring kata in Clojure which I started working on in the last Clojure Developers Barcelona meetup.

This is the original code that I got from a Mike Jansen's GitHub repository:

First of all I wrote tests following the description of the kata and had to fix several bugs related with items quality inferior and superior limits, 0 and 50 respectively.

These are the tests using Midje:

Once all the tests were in place, I started the refactoring by improving the indentation and using destructuring on the item parameter to eliminate duplication and make the code read better. Then I started to work on the cond branches working my way to have a separated branch for each type of item.

Every time I separated a branch for a type of item, I created a query helper to make the branch predicate more readable.

Once I had a branch for each type of item, I created helpers to increase, decrease and set to zero the quality of an item.

Finally, I removed the destructuring of item that I had introduced at the beginning, since it wasn't necessary any more and created some other helper functions.

This is the resulting code:

You can follow the whole process I've just described having a look at the commits I did after every small refactoring (look at commits between Gilded Rose original code and Introduced explaining helper)

This version of update-item-quality is much more readable that the original one.

In the next post, I'll replace the conditional logic with polymorphism using Clojure multimethods.

This is the first post in a series of posts about the Gilded Rose kata in Clojure:
  1. Clarifying conditional logic
  2. Replacing conditional with polymorphism using multimethods
  3. Updating conjured items by decoration