Recently I've attended the event that I planned to attend year after year and never really did it. This year it finally happened. You can read more about the event itself here. What I want to write about here is what I've learnt during the event. And (to my surprise) there was quite a lot of it.
These were:
Another thing that stroke me was that Visual Studio has evolved and matured as an IDE. It no longer is just a simple text editor with ability to build your program. It has now a lot of smart code generation available and a lot of shortcuts built-in (even without ReSharper).
I also learned that I like "var" keyword (even though I'd actually prefer "val" like in Scala) as it allows me to avoid a lot of the verbosity and duplication that Java forces upon you.
You should only add something if it really is solving the problem at hand. In the simplest possible way. Don't add stuff for future. Add it when the moment comes as you never know what future brings. Evolve when business needs it.
I consider myself to be quite familiar with my primary language (Java) and the IDE of choice (IntelliJ IDEA) and I could feel a huge difference in the productivity when I could completely focus on solving the problem using given constraint instead of spending lion's share of time typing in the solution or trying to understand why this syntax/library/shortcut doesn't do what I want it to do. I could see other people struggle to get anything done when they chose to try something they were not familiar with. But I think that it was part of the lesson for them as well.
Another thing is that No matter how much "karate" you know, someone else will always know more. I had a chance to experience that. And I've learned some useful shortcuts (ctrl-shift-enter).
One last thing: keyboard is very important. Trying to use unfamiliar keyboard for typing fast is like programmer's worst nightmare.
When you are developing an application for regular business, you, more often than not, have a defined interface that your users want to be facing. Be it a standalone desktop application, command-line interface or a web-browser, you usually don't have a problem with knowing what the expectation is.
In our case we had no idea what interface we have and what is the interface that we want to provide our imaginary user with. How do you write an acceptance test in a situation like this? And do you need an acceptance testing framework for that?
We've decided that simplest possible thing should be enough for us (we were returning a printable string representation of the universe). We obviously still had problems implementing an acceptance test for multiline strings, as can't be too easy, but eventually it turned out to be a satisfying solution.
The truth is that instead of getting the same big thing done much faster you should try to focus on getting much smaller chunk of functionality delivered in the same 3 minutes but in a more relaxed way. Obviously most of the time it is very difficult to come up with really small chunk of shipable code but that is another story.
quarrelingdiscussing
the approach you want to take or just staring at the other person
typing and waiting until the session finishes. The truth is that your
approach is just one of many that will make things work and it may only
be a good approach in some cases. If you remain open and try to
understand what (and why) the other person is trying to do you might
actually end up learning something new and useful that will extend your
toolset.
I feel really happy that I've decided to dedicate almost 10 hours of my life to self-improving. It was a really intensive and tiring experience but pros outweight the cons in my opinion.
One decision that I made during the event is that I'm going to spend much more time getting hands-on experience with the stuff that I'm interested in, instead of just reading about it, if I really want to get anywhere with it. That means a lot more of deliberate practice.
Format and constraints
You can read about the format of the code retreat here. In our case we had 6 sessions, each with different constraints.These were:
- no constraints - get familiar with problem
- use acceptance tests instead of unit tests
- TDD as if you meant it
- Tell Don't Ask
- immutable data and static functions (FP-like)
- no mouse or baby steps
What I've learnt
All of those various constraints and pairing with six different people exposed me to different tools, approaches and problems. Sorting it out obviously lead to learning and here's what I've learnt.C#
I used to write some C# code in the past and I was fairly familiar with the syntax and available tooling. After a few years of break I've found that it's now very difficult for me to read that code as the syntax and standard library allow you to do so many different things that were previously not possible. One of those things are indexers. I haven't seen it before in C# and for sure haven't seen it in any other language (Scala's apply() method could potentially be used this way but it has many more usages whereas indexers are only there for exactly one use case). I still have mixed feelings about it...Another thing that stroke me was that Visual Studio has evolved and matured as an IDE. It no longer is just a simple text editor with ability to build your program. It has now a lot of smart code generation available and a lot of shortcuts built-in (even without ReSharper).
I also learned that I like "var" keyword (even though I'd actually prefer "val" like in Scala) as it allows me to avoid a lot of the verbosity and duplication that Java forces upon you.
Unrelated code - YAGNI
When working on a new problem or using a new approach it's really easy to get a bit overwhelmed, retreat and do something that you are good at or famililar with. This often can sidetrack you and lead to dealing with completely unrelated code that doesn't add any value for the exercise and the solution itself. This not only slows you down (as you are writing unnecessary code and can get into problems that you the try to solve even thoug the issue that you are trying to fix is completely unrelated) but is also overcomplicating the problem. If you persist long enough, you don't, even remotely, touch on the sole purpose of the exercise in result getting nothing out of it.Simplest thing that could possibly work
It's easy to come with really sophisticated data structures and algorithms if you've been in the software industry long enough. Also seeing some similarities to the problems you solved in the past can lead you to creating stuff that you "know you will eventually need". Problem with this is that you can overcomplicate your code because of inadequate abstractions and bloated solution. Most of the time there is enough complexity in the problem itself and adding additional stuff is going to make the whole thing difficult to understand, reason about and extend.You should only add something if it really is solving the problem at hand. In the simplest possible way. Don't add stuff for future. Add it when the moment comes as you never know what future brings. Evolve when business needs it.
Know your tools
Trying out new languages and tools is great. It's even better when you can try many of those in a short space of time and decide which one you like and which you don't. But to do it effectively the person that you are pairing with has to be a real expert in what you are trying out as you are there to focus on new approach. Otherwise you completely defeat the purpose of the whole exercise (constantly getting sidetracked by details of language/syntax/libraries/tools) and make it a waste of time for your partner. If you both are somewhat familiar with the language/tool but none of you has enough experience, the experiment might be a waste of time as you are trying to understand why something really basic doesn't work as you expected. I think that to fully appreciate everything the event has to offer you should focus on the constraints and try to get familiar with languages/tools on your own in your own pace at home.I consider myself to be quite familiar with my primary language (Java) and the IDE of choice (IntelliJ IDEA) and I could feel a huge difference in the productivity when I could completely focus on solving the problem using given constraint instead of spending lion's share of time typing in the solution or trying to understand why this syntax/library/shortcut doesn't do what I want it to do. I could see other people struggle to get anything done when they chose to try something they were not familiar with. But I think that it was part of the lesson for them as well.
Another thing is that No matter how much "karate" you know, someone else will always know more. I had a chance to experience that. And I've learned some useful shortcuts (ctrl-shift-enter).
One last thing: keyboard is very important. Trying to use unfamiliar keyboard for typing fast is like programmer's worst nightmare.
Acceptance testing
Some of the challenges we've faced when going through our first constraint might've seemed somewhat silly but they actually were a problem for us.When you are developing an application for regular business, you, more often than not, have a defined interface that your users want to be facing. Be it a standalone desktop application, command-line interface or a web-browser, you usually don't have a problem with knowing what the expectation is.
In our case we had no idea what interface we have and what is the interface that we want to provide our imaginary user with. How do you write an acceptance test in a situation like this? And do you need an acceptance testing framework for that?
We've decided that simplest possible thing should be enough for us (we were returning a printable string representation of the universe). We obviously still had problems implementing an acceptance test for multiline strings, as can't be too easy, but eventually it turned out to be a satisfying solution.
TDD as if you meant it and evolving the design
Limitations imposed upon us during the session number 3 felt really debilitating to me. I'm very much used to coming up with abstractions pretty quickly and using them to speed up my work towards the goal. Having to express all of my ideas first as a bunch of code that only operates on primitives, loops and is just a big ball of mud felt like a nightmare to me. Waiting until the design is going to evolve from that mess instead of just putting that in place orderly from the very beginning felt really frustrating. It's possible that I'm too used to well abstracted code. Or am I over-designing? I'll have to think about it a lot more and go through this exercise few times more to really understand what all of this means.There is no silver bullet
Constraints that were the theme of sessions 4 and 5 gave me a real insight into my preferred way of solving coding problems. Tell Don't Ask felt like home while trying to use static method calls everywhere and not being able to use polymorphism felt like a real limitation. That said, I feel that using a different language (e.g. Scala, we used Java) would give us much better results, as it might lean more towards functional programming paradigm and have built-in ways of dealing with some of the implications of our constraint, overcoming which in our language of choice felt really quirky. I think that current proliferation of paradigms and languages only proves that some tools are better for some approaches and that you have to always expand your knowledge of what is there and how to use it wisely.Baby steps = stress?
The last exercise was really interesting. It's goal (at least to me) was to prove that you usually are trying to achieve too much at once. Unfortunately it proved to me that when you are very familiar with your language and tooling you can achieve quite a lot in a really short timespan (3 minutes). This can obviously make some people feel pressured to be much faster than they usually are, make them make more mistakes, get mental blockage, get frustrated and stressed out.The truth is that instead of getting the same big thing done much faster you should try to focus on getting much smaller chunk of functionality delivered in the same 3 minutes but in a more relaxed way. Obviously most of the time it is very difficult to come up with really small chunk of shipable code but that is another story.
People are different
Pairing with 6 different people during one day gave me a nice exposure (that I don't usually get in a workplace) to:- 6 different ways to understand the problem
- 6 different approaches to solving it
- 6 different styles of programming
- 6 different favourite workflows
- 6 different ways of communicating
Knowledge sharing
Throughout the whole day I had a chance to learn a lot from others and to share some of my experience and knowledge. In some cases it came to me as a surprise that some things which are obvious to me are something completely new to others. Being able to elaborate on that and make someone's toolbox richer felt really great and very rewarding. That's something that I definitely should do more often!Summary
I had some reservations about spending almost all day with a bunch of people that I don't know. I didn't know how much I'll get out of it.I feel really happy that I've decided to dedicate almost 10 hours of my life to self-improving. It was a really intensive and tiring experience but pros outweight the cons in my opinion.
One decision that I made during the event is that I'm going to spend much more time getting hands-on experience with the stuff that I'm interested in, instead of just reading about it, if I really want to get anywhere with it. That means a lot more of deliberate practice.
No comments:
Post a Comment