Participation in GDCR is free of charge and sponsors usually provide food and drinks. As of today, there are 128 GDCR local events planned all over the world. To find a GDCR event near you, go to http://coderetreat.org
A Code Retreat is an entire day of practicing the craft of software development, with no pressure to finish anything.
The goal is to write perfect code and in the process of doing so, learn TDD, unit testing, refactoring, and how to come up with better, simpler designs.
The problem is simple but non-trivial: write a Conway's Game of Life program in whatever language you prefer.
It's a lot of fun, you can learn a lot, meet like-minded people, and best of all, it's FREE!!!
@Tim: Yes, I'm planning to write up an experience report and share whatever I learn from this experience. I facilitated our local event last year and it was interesting to say the least.
I posted some tips for getting the most out of the day in Liutauras' thread about TDD: https://coderanch.com/t/686754/Laws-TDD-Uncle-Bob#3224300
I'm also working on putting up some useful resources for Code Retreat on GitHub. It's not much right now but stay tuned for more: https://github.com/jlacar/coderetreat
Tim Cooke wrote:And now I really must have a go at Conway's Game of Life, it looks like a fascinating challenge.
I first encountered this problem in college in the mid 80s and solved it in Pascal. I wish I still had my program from back then, it would be fun to see how much (or how little) has changed since.
Last year, I had a lot of fun implementing the program in Go. My Go Life program was actually a lot better than my Java version. Go has very nice CLI support and I went a little crazy with the options.
Anyway, the challenge in Code Retreat is not so much to finish a GoL implementation. Haines* and the other guys who started CR actually picked the problem because it would be impossible to finish in the time allotted (45-minute rounds recommended) before you had to delete everything and start over using a different approach. I imagine anyone who practiced sandpainting would be very comfortable with that CR rule. Most developers are trained to finish so it's a little bit harder to let go.
The idea behind not finishing and starting over in each round is to be freed from the pressure to finish. Without that pressure, you can focus on the goal of writing perfect code. If you only write one line in 45 minutes, as long as it's the perfect line of code, then you've learned something. Of course, that perfect line should have been created with much thought and consideration for design principles, have unit tests that drove what and how it was written, and adhere to the Four Rules of Simple Design. Plus it's not just your line of code because you'll be working with at least one other person to create it.
So, yeah, it can be pretty fun.
* Corey Haines got the idea for Code Retreat from conversations he had with a few other attendees of CodeMash 2009 in Sandusky OH. The first Code Retreat was held in January 2009 in Ann Arbor MI. Haines took his experiences from many code retreats and wrote the book Understanding the Four Rules of Simple Design. The only problem discussed in that book is Conway's Game of Life but the insights shared about unit testing, design, and refactoring are incredibly valuable.
My local event was held in downtown Columbus OH at the sponsor's (Pillar Technology) The Forge development center. The facilitator, Mark Holtman, said that about fifty people had registered to attend but only about half that number actually showed up, perhaps due to the poor weather conditions or because the Buckeyes were hosting the Fighting Illini at The Shoe (college football, Ohio State vs. Illinois, for those not in the know). Still, there were more than twice as many people this year than there were in last year's event that I facilitated. From what I've seen in tweets on #GDCR2017, we had a modestly good turnout for Code Retreat.
I'll start with what I can remember from the session retros.
1. Time really does fly when you're having fun so try to spend as little time on project setup as possible. Forty-five minutes goes by really fast. Really. Fast. To save some time, it really helps if you have an empty project prepared beforehand or if you have some way of setting one up quickly, like in a few seconds.
2. Refactoring makes it really fun; try to find something to refactor every time you get your tests to pass. One of my programming partners, Sam, said "That's some sexy code right there!" We were working in Python and had refactored functions like isAlive(), listOfNeighbors(), liveNeighbors(), deadNeighbors(), zombieNeighbors() and test names like check_spontaneous_zombie and check_cell_dies_of_loneliness. If you're wondering what's the deal with the Zombie thing, the facilitator gave us additional rules to implement that involved zombie cells.
It has been a couple of years since I learned Python so it was good to be able to get a refresher on comprehensions and other Python language constructs and idioms.
3. Refactoring helps people quickly see the benefit of doing TDD. TDD is still a rigorous discipline that can be difficult to learn. However, with the right mindset and introduction to it, you can quickly see its benefits. Sam had not done much TDD before yet he seemed to settle into the Red-Green-Refactor rhythm pretty quickly. I think the focus we had on refactoring and choosing good names really helped him. He said "I like it!" quite a few times after we did some simple Rename method/function refactoring.
@Sam: If you're reading this, I had a great time pairing up with you and John this afternoon and it was nice to see you settle into TDD as quickly as you did. Great job today.
4. Don't get stuck on writing that first test. Most first tests suck anyway, so get over it and just write one down.. The first test is always the hardest one to write. Don't agonize over what that first test should be, just write it down, no matter what it is. Having a failing test within the first five minutes is WAY better than having nothing but a bunch of cool ideas. There's something about actually being able to see a test, any test, that makes it soooo much more valuable that just having an idea floating around in your head or being bounced around in a discussion.
The problem of getting stuck on that first test is actually pretty easy to solve: Just write a test, ANY test! It doesn't even matter if the test sucks or is outright wrong. Seeing sucky test code seems to put your brain into a higher gear and the suckier the code you see, the more you'll probably want to change it.
WARNING: The following linked video is probably not suitable for viewing at work or in the presence of anyone who may be offended by coarse language.
Don't be like the indecisive lioness shopping for dinner. I think this whole getting stuck on the first test thing comes from a combination of the fear of getting it wrong / desire to get it right and feeling a bit overwhelmed by the number of options you have. So, be more like the lion in that video when it comes to writing that first test. Believe me, you won't regret it.
5. Practice your communication and collaboration skills, too. Try to explain what you're doing or where you're coming from / going to with an idea and be mindful of how your partners are reacting. I was paired up with Seth and Derek in one session and there were things I definitely could have done better, communication-wise. I think Seth and Derek would agree. I think it would have been nice to bring up that aspect of the pair/mob programming experience in the retrospectives. More on this later.
6. Keep it Simple. This one is worth reiterating: Remember the KISS principle. Especially, don't get hung up on setting up an initial state of the game or on having a visual way to inspect the state. Trust your unit tests. Facilitators can help here by providing sample configurations and progressions. I have some here: https://github.com/jlacar/coderetreat/blob/master/resources/ConwaysGameOfLife.md and this link was shared with participants in the room but I doubt anybody actually used it. This either means our participants didn't need it or that they used up more time not coding for other things. I hope it was the former.
Unfortunately I was unable to attend this year myself, because had booked very first swimming session with my child (3.5 months old) - "swimming with dad", which I didn't want to miss no matter what, and I don't regret it!
But I will try my best to attend this workshop next year.
7. (For facilitators) Try to start off with a brief history of Code Retreat, who started it and what the goal is so that all participants have a clear idea of why they're there. Overall, our hosts and facilitator did great but one thing I was hoping they'd do in the morning briefing was give the participants a bit of that high-level information about GDCR before jumping right into the mechanics of the sessions, etc.
In hindsight, I should have suggested that as last year's GDCR facilitator, I could have done a five-minute welcome and introduction, then handed it over to this year's facilitator, who would then go into all the details of the mechanics of Code Retreat. As it turned out, by the time I realized that it was our facilitator's first time in that role, he had already gone through the mechanics part so it seemed a bit too late for me to jump in and offer to give the overview. I did manage to sneak it in sometime later in the day during one of the retrospectives.
So, here are a couple of suggestions to facilitators for the morning kick-off briefing:
1. Get a past facilitator to give a quick welcome and overview (optional), then hand off to the current facilitator. I think this is a nice informal "passing the torch" ceremony and gives a sense of continuity and connection to past Code Retreats. If a past facilitator is not available, the facilitator should start off with a brief history of Code Retreat and a statement of the main goal(s). I've watched some videos of Corey Haines doing his morning kick-off spiel and I think that the following points he makes are worth repeating at the start of every code retreat:
2. Prepare some visual aids and put them up where everyone can see them. The #GDCR2017 Twitter topic has many pictures of visual aids that were used at other locations. I really like these:
On the other hand, I had volunteered to bring some of the aids I still had from last year's event but ended up forgetting to bring them with me. I could have helped out here but dropped the ball. I also don't know how useful the resources I put up on a GitHub repository were. I think visual aids that are right there on the walls would be hard to ignore though.
I still think our GDCR2017 experience was great though. Two thumbs up to Mark Holtman, RJ, Corey, and everyone else who helped make the GDCR2017 event in Columbus OH a success.
A couple of thoughts that our facilitator, Mark Holtman, shared during the retrospectives:
1. Identify participants who have TDD experience and try to spread them across pairs. This can help make for a better overall experience for participants who don't know TDD that well or have never done it before.
2. We're trying to go back to the basics and get better at them at Code Retreat. I wasn't very surprised when our facilitator mentioned that he was a martial arts practitioner (Tang Soo Do) and that he saw Code Retreat as a good way to practice the basics of programming, how it was like martial arts in that if you have a solid grounding in the basics and made all the movements part of your muscle memory, you could take your skill to the next level of expertise, etc. These are all things I have talked about many times in the past here at the Ranch, like Shu-Ha-Ri and the importance of Ikkyo (the first technique) to students of all levels in Aikido.
Jeanne Boyarsky wrote:Sounds like it was fun!
Yes, it was a lot of fun. One of the day's high points for me was hearing my pairing (actually we were a mob of three) partner, Sam, say "That's some sexy code right there!" and our third, John, smiling and nodding in agreement. We also got to put our code up on the projector screen during the session retro so everyone else in the room could see how sexy it was.
Liutauras Vilda wrote:I'm jealous. Thanks for sharing your experience, Junilu.
My pleasure. I don't think it beats a day of dad swimming with baby but it comes in as a pretty close second. I hope you get to do one of these soon.
GDCR is a day to practice and learn. Since the skill levels and backgrounds of people who participate in Code Retreat can be all over the board, developers can learn all sorts of things.
1. One person I paired with learned more about arrays in Java. She had never worked with nested arrays in Java before and was surprised that you could do this:
On my part, I learned that I should be careful not to assume too much about partners at Code Retreat. My surprised reaction to finding out that she hadn't worked with arrays much before could very well have put her in a defensive mood. That would have changed the whole dynamic between us for the rest of the session. Lucky for me, she was a sweet kid who was only being honest about her lack of experience and didn't seem to mind what could easily have come off as a lack of equanimity and grace on my part.
2. Another partner learned about De Morgan's Laws. He was driving at the time and had written this:
I said that he should use || instead of && and we spent a couple of minutes discussing which expression was correct. He had really meant to write:
I told him, "Yeah, that's De Morgan's Law..." and repeated it when he just looked at me blankly, at which he said with a little bit of exasperation in his voice, "You say that like I'm supposed to know what it is and go 'Oh yeah, it's De Morgan's Law!"
Oops. Again with the assumptions. I had forgotten that he had mentioned during the break that he had just graduated a year ago with a liberal arts degree so he hadn't learned that much about boolean algebra in school. I was again reminded of the truth about what they say happens when we ASSUME too much. As basic as it may seem, this kind of lesson is hard for an old dog like me to learn. My luck from before held out because he was a really nice kid (we had a few participants who were apparently very fresh graduates) and he quickly accepted my apology.
On his part, my partner learned how (!(i == 0 && j == 0)) is equivalent to (i != 0 || j != 0) and that this was one of De Morgan's Laws.
My personal takeaway from this: I need more polish in my collaboration and communication skills. In other words, I should try to get better at not being an ass when I'm working with other people face-to-face.
But before going of, let me say a big "Thank You" to the sponsors of this day, especially Bol.com, where the meeting was held. But having said that, I must say an even bigger "Thank You" to Thodoris Bais, a very friendly man from Greece, and to the two assistants Joost and Patrick, both working at Bol and who helped us enourmously in times of trouble.
Not to forget: the whole day we had plenty of food and drinks, all for free, we were nurished like babies. In the picture below, you can see the bananas in abundance.
So again, a very big "Thank You" to all that made this day possible.
But then it was time to do a little TDD.
Junilu had already told us what the subject would be that day (the well-known Conways Game of Life) and what form the day would have. In a short introduction we were being told about the principles behind TDD, the red-green-refactoring pattern, the 4 elements of simple design, and some other things that I had never applied myself. One person was protesting: how on earth could you start with a test, if you did not know what it was that should be tested. Well, that actually was my problem too, and so I was very curious how round one should go!
I did not worry by the way: I had written Conways life already (albeit it was of the form 'main is a pain'), but now I would have a nice 2D boolean array, with streams, and as many Threads as possible to determine the next generation with the help of a CyclicBarrier, and two beautiful BufferedImages of which one was being drawn upon and the other to be used by paintComponent, so actually why on earth would I need something called TDD? But I was in for a big shock: we were to have an infinite 2D world! So mentally, I said goodbye to my 2d array...
There were four rounds in total, and the first round was simply to form teams of two, so you had to go and find a mate. We started off with a group of three, since we had an odd number of participants.
We had Frans the Scalaman, Echedey from Spain, and me the amateur. Yes, how to start? Echedey wrote a test:
(yes, from round 2 we would be using meaningful names for these tests!). Hmm, that test failed miserably, but that should be the case as we were told. The penny dropped a little: if we had to make this test pass, we would need something called 'Cell' that had a method called 'isAlive()'. Ahhhhh, how simple! So we made a class calle 'Cell' and a method 'isAlive()' that returned 'true' for now, and indeed: the test passed!
Yeah, what was all this fuzz about TDD taking years to master! I managed to become an expert in 5 minutes! (well, the real noob speaking here...)
But hang on for a second: where does the method 'isAlive()' get its answer from? Hmm, another test that failed and we incorporated a boolean 'isAlive' that would be returned by that method. But that was only shifting the problem: what was it that set the value of 'isAlive'? And then it occurred to us: do we need that status in the first place? If you see a person walking on the street, would you ask that person whether he was alive or not? The mere fact of seeing that person would be enough information. So, out went the 'isAlive()' and we envisaged a List (well, I was thinking of a HashSet) of Cells that had all the living cells. It was time to come up with the World.
So, here came the World class, with an initially empty list of cells. Then we devised a test 'world.transaction()' that would deliver the next generation (I wasn't particularly pleased with this name, but that was something for later). Now, to get such a method up and running was a very interesting challenge of course, and I thought already about some algorithms. But we were taking a too big step. How did we get some cells into our world's list? We needed some suitable contructor for this. And what about out Cell class? What was it representing now that we removed the isAlive business? And how could we determine a cells neighbor?
And what on earth was left from my beautifull version of this game? Hmmm, I thought that we were on a very interesting path, and I looked very much forward to how this project would end, so I couldn't care less about my home made code. But as Junilu said, it is unbelievable how fast the time passes by, and we had to stop our eforts here, to go into the evaluation.
Well, it was an incredible experience, and I had the idea of getting a sense of what this TDD is all about. You solve a test, but then your head floods by the ideas you suddenly get.
I teamed up with Vinayak, a Big Data specialist if I interprete his "cv" on the website of JUG Utrecht.
This second round was titled 'ping pong' and for a good reason. One would start writing a test that failed, then the other one had to make this tesd pass and come up with another test that failed, et cetera. A very interesting idea! So the cell.isAlive() returned, and 30 minutes later, as a result of a test I put in, my partner totally disagreed with the idea behind my test, and so we had a very intense discussion about our ideas. And so the time went by, without producing any code any further. But that was okay, I felt very pleased with how things were going: speaking and discussing with some real professionals, that was completely new for me. So, no code but a very worthwile experience for me.
We had a luxury lunch with many things to eat and drink, that was LazyDeliciousLand as we say in Holland ("luilekkerland"). And Joost told us much about his daily work at Bol.com, how they managed to get such a fluent website working. Very interesting.
They made it even more interesting. Again we would be doing the ping pong version, but this time any communication with your teammate was forbidden. Now, that was interesting. I formed a team with Ahmed, and that turned out to be a feast! He started off, but I found it suspicious that it took him so long to come up with a test. Hmmm. And when he gave me the laptop, I realized the reason: a pretty difficult test to get it passed! So that took me some time, but then I mumbled 'revenche' and since body language was not forbidden, I gave him the middle finger. Don't worry, both of us were so laughing out loud, that everyone stared at us. But I pointed out that the most important thing today was: have fun, and we certainly managed. As I said in the evaluation: two things became apparent: since no communication was allowed, I certainly had the feeling we were making more progress than in round two, where much time was spent on discussions. And, secondly, you had to be very careful not to make too big steps. If you devise a test that takes quite some methods to get it pass, then chances are your mate will be unable to get it pass, or even to get an idea of what your intentions were. So you certainly had to feel very responsible in what you were doing. Don't make the tests too easy, but don't make it too hard too. A very rewarding experience.
To my shame, I must confess this round was completely beyond me. It was even so bad, that at some point I asked for this big conic hat with the big donkey ears, to sit quietly in the corner. But they had just abolished this practice, and tarring and fethering was also a thing of the past.
It was about writing tests and solving it within two minutes, or else your partner should go along. If you did manage, then you were supposed to commit the code somewhere to GitHub. Well, I do have some code in my GitHub account, but since I never program in teams, I use it so seldom, that I always must have a look at the turorials again. So, this experiece taught me to start practising GitHub more. My partner was not very familiar with GitHuB too, so Patrick came to rescue, working from the Git Bash, typing in those commands that I could never remember.
The final evaluation
We had to answer three questions
1) what did you learn today?
2) what things surprised you most?
3) what would you take to the office, "tomorrow"?
When it was my turn, I answered
1) that this TDD was much more fun and made a lot more sense than I always thought, always thinking after reading one of Junilu's many posts about TDD, "yeah, sure, but I don't need TDD, my own way of doing is good enough'. It was certainly an eye opener. But nowhere did we get anywhere close to a working version of Conways Life.
2) What really surprised me was that I found it easy to get a hang of this TDD, and how it somehow worked miraculously. What also surprised me was that coming up with some sensible tests is not so easy as it looks. But what struck me most (and actually I found it a little shocking) was that after round 1 I hardly thought about my 'great OOP version' that I brought from home, and from round two I had completely forgotten my home made version.
3) now, that was not so easy to answer. The modelling part of my work (the coding of our models) has been trqnsferred to our 'Business Intelligence' department, and to be frank, I never heard any of these poeple ever mention TDD, and the actuaries at my department will certainly have never heard of TDD. One participant said that it was a beautiful opportunity to incorporate the TDD ideas into our monthly reporting. But the department delivering the reports is a huge department, with some 20 people, specialists on things like IFRS (2, 4, ... 17) and Solvency II, and to go to there people teling them to start using TDD starting tomorrow.... But being one of the very few not involved in daily programming, the question might not be relevant to me.
All in all, I had a wonderful time, and I really advise to go to such a meeting whenever you have the opportunity.
One picture of me, and one from the location. I'm the person with his back to the camera, second from the left.
I'm glad you enjoyed yourself at GDCR2017, and thanks for sharing those pictures of yourself and the group you were with. That's about as many as I had show up for GDCR2016.
From what you described of your round constraints, you had an experienced Code Retreat facilitator. That's awesome. We didn't get to try our hand with any of the constraints you did although we did try to modify the GoL rules a little bit with "zombie" cells. The facilitator and I exchanged emails this morning and based on feedback he got from other participants and myself, they're going to consider sponsoring more of these code retreats before next year's GDCR event. Hopefully, that will encourage people to attend regularly and maybe there will be enough experience in the room to get to the more advanced constraints like "Ping Pong" and "TDD like you mean it" in GDCR2018.
The quote below is exemplary!
Piet Souris wrote:If you devise a test that takes quite some methods to get it pass, then chances are your mate will be unable to get it pass, or even to get an idea of what your intentions were.
That seems to be a very accurate estimation about the design's simplicity or complexity.
I hope this thread will expand every single year!
Indeed, as I hope it is clear from my report, I enjoyed it very much.
And I had already experimented with say, if a living cell had three living neighbors, then it would be random whether it survived, with some parameter 0 < p < 1. But I had it not tried out enough to see if it had much impact. Well, complete bookshelves of books have been written about this game, so anyone interested will not be disappointed.
Saturday a little, but yesterday much more, I was thinking about the question: how did I develop my micro projects up till now? After long thinking I found some pattern:
1) I get some global idea of a project
2) then, with the help of the IDE GUI builder, I would devise a complete UI (only the form, without content). That will give me a very good insight in what my application should be capable of doing.
3) from this, I get an idea about the classes that I need.
4) If I write some code, for instance an actionListener, I use methods that aren't there yet, but the necessity of the presence is apparent.
5) of course, the IDE will raise a lot of errors this way, and I start to implement the missing methods, finding out the parameters I'll be needing, what variables shoud be members, et cetera.
6) I test it a lot by using single steppers, using println statements, et cetera
7) and usually I get to some working application that is satisfying
And I compared it to what I was doing saturday. And stil thinking what the differences are and what similarities.
What I did regret Saturday is that nowhere near did we come to a working version, not even one that was only working internally, without any command line output.
So, what I would additionally like, is the voluntary home work:
send a complete working version, with TDD, to some GitHub account, for all participants to judge, within four weeks.
Next time, I probably will make such a remark.
But Junilu, thanks again for pointing us to this event, and from now on I will read your posts about TDD with other eyes!
As for the finishing part, Corey Haines and other pioneers of Code Retreat wanted to remove the pressure of wanting to finish from the equation. They wanted participants to focus on practicing the design, refactoring, and test-driving aspects of writing code. If you only write one line of code at the retreat, as long as it is perfect, then you've achieved the goal of Code Retreat.
Like I said before, it's like sand painting. When you're done creating your masterpiece in the sand like this guy did, you just leave it for the wind to blow (some will purposely erase everything, just like what you're supposed to do at code retreat).
I had the idea, as I'm sure many other people have, to use version control to save my work. This is also useful if you want to go back and review what you did, like how good athletes watch film of themselves so they can see what they can do better. There are facilitators, however, like ours and even folks like J.B. Rainsberger, author and another Code Retreat pioneer, who will allow pairs to stay together in the afternoon and allow them to keep going on from the previous round so they can get further along and explore other aspects of the problem.