Talks

Hurting Code for Fun and Profit

Help us caption & translate this video!

http://amara.org/v/FGkh/

GoRuCo 2008

00:00:13.080 Hello, my name is Ryan Davis. I'm with the Seattle Ruby Brigade and I'm one of the co-founders. As you've heard, I'm with Engine Yard now, working on Rubinius. A couple of notes: I'm getting over a cold, and I'm on the East Coast, which is three time zones away from home. This is about the time I usually wake up, so I'm a little out of it right now. I apologize if I fumble.
00:00:24.400 I gave a version of this talk at RubyConf 2007 and I received a lot of great reviews from that experience. I was really proud of that talk because it encompassed my message and mission as lucidly as I could state it. Unfortunately, the recording of it was lost, so I'm really grateful to be here today to give this talk. I'm going to be discussing what I call 'Ruby sadism', 'Ruby aestheticism', and 'introspection-driven development'. To set some expectations, I have 142 slides and 45 minutes to deliver this talk, so it's going to be fast. I'm very much focused on signal versus noise, so hopefully, I will go quickly enough to have some time at the end for questions.
00:01:01.160 This talk is a departure from the usual type, as it’s more about self-improvement than about writing code. Many of my usual talks are filled with code, runtime, and demos; however, this isn't one of those instances. So let’s start with a story. Once upon a time, there was a developer who went to a new place. This new place could be a new job, a different department, or a completely new project. The important point is that the developer came across Legacy code. As we all know, Legacy code is any code you haven't written yourself, and every company has tons of it, even startups. In fact, I should amend that definition: Legacy code is any code you haven't written in the last two weeks.
00:02:01.240 The developer sits down at his shiny new workstation, opens the editor, and starts going through the code to learn. He uncovers a rat's nest, and this makes him angry. Unfortunately, he does the only thing he thinks he can do—he kills everyone who was guilty of that code and promptly goes to jail. The alternative is that the developer sits down, opens the code, examines it, and uncovers the rat's nest. Instead of getting angry, he pulls out his toolbox and addresses the problems one by one until he has shown the code who is boss, and then he is happy. The moral of the story is quite simple: people will press charges if you hurt them, but code won't. So, hurt the code and stay out of jail.
00:03:33.280 This talk is a coming-out event for me. My name is Ryan, and I like to hurt code. Why hurt code? For me, hurting code is a lot of fun. It can make you a better tester and a better developer, and I believe we should all strive to be both. Hurting code can lead to cleaner, clearer, and easier-to-maintain code, and it can even make it run faster. Ruby sadism is the tendency to derive pleasure from inflicting pain on software, especially bad software. It’s a different perspective on software development.
00:04:02.840 Anyone who has paired with me knows that I laugh with delight every time I find code that I can punish. Some of you are in this room right now. It’s about changing your perspective on bad code. When you make it fun to hunt it down and fix it, you’ll find yourself doing it more often, and ultimately you’ll wind up with better code over time. Ruby sadism can come in many forms: killing a bug by writing a new test, reading overly clever code and itching to rip it to shreds, and cleaning up bad design to improve performance, among others. Can anyone come up with any additional examples of hurting code?
00:05:05.000 As an example, I was working on what should have been a two-month social media Rails project that dragged on for about twelve months. One of the main problems was that they were trying to tie ActiveRecord to WebDAV for scaling. The issue was that WebDAV is a transport serialized over HTTP using XML, which meant every time a web browser made a request to a Rails app, the app wanted to make a database request. Instead, it had to go through WebDAV, hitting another server with an XML serialized request. This server would deserialize the XML, process the request, figure out the result, serialize it back into XML, and respond. This was needlessly complex and slow.
00:06:13.280 I ripped out WebDAV over the weekend, and the results were dramatic. Initially, our average runtime was around 75 seconds for 622 tests, which really wasn’t that many. After removing WebDAV, we conducted roughly half the tests because I had eliminated a lot of the tests on the web side, but we were running those tests 15 to 20 times faster. Over time, you could see that prior to addressing the design, our tests didn’t consistently run, and we had to fix that. Once we established some consistency, we spent time profiling and optimization, which helped significantly. There was a drop in runtime after those changes, and it became apparent that we could add a lot more tests because the code was now more usable.
00:07:49.080 For some reason, people love complexity; they revel in it. The Ruby community is not unique in this regard; I think it’s a human trait. I used to be one of those people, but I got better, and you can too. I have a graph here of my programming history. The years are on the x-axis, and my programming capability is on the y-axis. I’ve had my ups and downs—I've done basic programming, C, and even got really good at those. It wasn't until I fully embraced object-oriented programming and had my epiphany in '91, and began to embrace smaller, lighter scripting languages, that I really started to grow. You can see my journey with Perl, Python, and Ruby. The sadism and aestheticism helped me grow non-linearly.
00:08:49.000 Ruby aestheticism suggests the practice of severe self-discipline and abstaining from all forms of indulgence. Aesthetics in any context require a strong sense of self-discipline, and this relationship is evident in software development. Virtually all major religions have had aesthetic subgroups, and one of the best-known is the flagellant movement. Many of you are already practicing various elements of aestheticism without knowing it. For instance, test-driven development (TDD) is a form of self-discipline—when you stick to the practice of writing your tests first and then implementing your code, you facilitate a more aesthetic approach to your development.
00:09:57.600 The practice of 'YAGNI' (You Aren't Gonna Need It) embodies the principle of self-restraint. In real life, we issue material possessions, while in coding, we issue unnecessary complexity. In reality, people practice self-discipline to achieve higher spirituality, while as developers, we practice discipline to achieve a better understanding of the code itself. But what does indulgence entail? It involves needless complexity over clever code — having features or design elements you don't immediately need. This is what I call the 'whatabouts.' Does anyone here know what I'm referring to with 'whatabouts'? They are the tangents and excess code that you don't require at the moment but often get suggested by others. I can't tell you how many times I've paired with someone and every ten to twenty seconds they bring up another whatabout.
00:10:50.440 Technical debt, a term coined by Ward Cunningham, refers to the idea that skipping or deferring design is like borrowing money. When you write code, you take on a debt, and the principal can be repaid later—but the interest you pay is the time spent dealing with the complexity you accumulated by deferring that design. Start thinking about every time you cut a corner as an investment; this perspective shift alters how you approach writing code. The Pareto principle, known as the 80-20 rule, states that in most systems there's a severe imbalance. Often we find that 80% of excessive time is spent on just 20% of the code. Using this tendency to focus our efforts efficiently can help us manage our time and improve our coding processes.
00:12:00.200 It's about focusing on what's essential—not so much on the code itself, but on your process and how you handle your work. Clear out clutter and minimize interruptions; that will allow you to focus on the real task at hand. One of my best managers often reminded me, 'Big alligators, little alligators, swamp.' It means that before you build a castle in a swamp, you need to deal with certain issues in an appropriate order. If you drain the swamp too soon, you’re going to encounter problems.
00:12:59.999 Ward Cunningham beautifully stated that a developer's obligation is to ensure that the code as written makes the clearest possible statement about how the solution was understood at the time. This perspective considers the evolving clarity of a developer's understanding of the problem at hand. To provide an example of aestheticism, testing frameworks like Test::Unit and RSpec are essential, but they are quite large and complex. I maintain Test::Unit but often hesitate to work on it when bugs are reported; it’s a daunting task due to its complexity. In contrast, Brian Ford of RSpec created a smaller, compatible framework called Mpec, which is much more elegant. Other developers have produced minimalist alternatives as well. I’ve built a tool called MiniUnit which has been significantly extended to include test specs and mocks, and it totals less than a thousand lines of code.
00:14:06.800 Here, I've graphed the library size of Test::Unit, Mpec, and RSpec. These libraries are measured side by side, showcasing their magnitude. The y-axis goes up to 15,000, demonstrating the disparity in size and complexity. The comparison empowers a reduced view on the y-axis where you can see that these new tools are smaller, simpler, and cleaner. I believe that Ruby sadism and aestheticism can be incredibly powerful, though getting there is not easy. It requires you to understand both yourself and the code deeply.
00:15:25.120 That’s where introspection-oriented development comes into play. It involves asking yourself a plethora of questions: How can I improve? How did I overlook that bug? Where am I lacking clarity? How can I use my tools better? Where am I wasting time? How do I focus better? Where am I holding myself back? Am I wrong? Can anyone else think of other questions to ask yourself?
00:16:01.600 For example, two weeks after writing some code, it is not uncommon to ponder: 'What was I thinking?' You look back at something and wonder if it made any sense. These self-questions are crucial for continuous improvement. Other forms of improvement come from reading. One nerd book a month is twelve times the industry average, which is pretty pathetic when comparing that to standard practices. If you can manage to do this trivial task, you are soaring above the average in our field.
00:17:04.320 One of the best wikis out there is the original CW.com, along with other wikis with contributions from bright individuals. Accessing expert knowledge through these channels is important. Read 10 to 20 smart blogs that resonate with you, being discriminative in which learning resources you choose. Ignorance isn’t bliss; it can lead to complacency. The New York Times reported on Dr. David Dunning's work at Cornell where he studied students attempting tests. The results showed that those who performed poorly often felt quite confident in their abilities while others who excelled were more critical of their performance.
00:18:20.000 The message is clear: people who perform poorly are often supremely confident, while those who do things well tend to feel less certain. Therefore, the more you teach yourself, the more you become aware of what you don't know, which propels your growth. Stay away from forums that devalue the profession or marginalize your capabilities. Trim the noise and maintain focus on what truly adds value to your knowledge.
00:19:04.160 Stephen Covey created an interesting framework regarding prioritization and how activities can be categorized. It’s split between important and not important, as well as urgent and not urgent. It’s essential to engage in activities that lead to balance—winding down is healthy for fighting burnout, so not all your time should be spent on urgent but unimportant tasks. Instead, focus on what is indeed vital and prioritize on constructing proactive plans and systems, aiming to curtail the potential for burnout.
00:20:18.960 This same manager also encouraged me with the phrase, 'Do you want to be right or do you want to be effective?' Eventually, I figured out I wanted to be effective. Commit to growth; aim to learn one new programming language a year. Learn your tools deeply. I’ve been using Emacs for fifteen years and still, I am learning new things and refining my skills.
00:21:22.600 Pair with others to code; it’s a beneficial way to explore contrasting styles and methods in development practices. Additionally, study non-coding areas. Collaborating with individuals from diverse backgrounds in fields like physics or music can introduce fresh perspectives and serve as an enriching factor in coding.
00:22:34.360 Another important practice is to write more code consistently. Produce junk code if necessary, experiment, and emphasize quantity over quality initially. An instructive pottery teacher introduced the idea that the volume of pots made would determine the quality of the final piece; one class learned through making many unsuccessful pieces, thus developing skill, while the other class theorized about creating the perfect pot but neglected practice. This highlights that even failed attempts are valuable lessons.
00:23:36.719 Lowering the cost of failure is essential; engage in many tasks without fear of creating 'bad' work. This may accelerate your ability to learn and iterate. In regard to testing, unit tests reduce the cost of failure. They encourage developers to conduct their own verification instead of relying solely on a QA team. The feedback loop has been condensed from a lengthy process into instantaneous results when you write your tests.
00:24:51.440 Be competitive in your work, challenge the status quo, and scrutinize existing methods. There’s often room for improvement. Don’t let emotions cloud your decisions, but do allow them to guide your understanding. Despite the complexities of developing in Ruby, the community thrives on creating good developer tools.
00:25:32.840 Engage with feedback consistently, and always seek it out—from your code, co-workers, or personal evaluations. This feedback loop is fundamental to refining your work. Strive to find a balance between action and reflection.
00:26:06.800 Tools can facilitate improvement; for example, autotest is a significant resource that embodies aesthetic principles while acting sadistically towards your code by rigorously testing it every time you save. This tight feedback helps you understand changes in a rapid cycle. Another example is Flog, which evaluates complexity in code and provides useful metrics on how to manage it effectively. Just remember that while numbers can be insightful, they should be considered relatively.
00:27:46.520 The clarity of your code matters. Every piece should communicate its purpose effectively. If code becomes convoluted, take steps to unravel it into a more understandable structure. Consider what tools and practices help maintain clarity and performance in your code.
00:28:55.280 In conclusion, embrace the process of hurting bad code; enjoy the experimentation and discipline it takes to accomplish quality code. Develop an introspective approach to your self-awareness and be diligent in your methods. Lastly, be passionate about your work because that passion translates into the quality of your outputs.
00:29:29.000 Frank Herbert might have been wrong; fear is not the mind-killer, but rather apathy is. You need to care about the code you create. Indifference towards the craft leads to mediocrity. I encourage you to nurture the code you love, or if you feel differently about bad code, hurt it. Be passionate about your coding journey.
00:30:02.840 Now, does anyone have any questions?
00:30:37.799 One audience member inquired about how I integrate the tool Heckle into my daily development. I shared that I run it when I’m feeling adventurous, and it has a plugin that allows me to integrate it with Autotest to specifically target a module or class.
00:31:06.800 Another person asked how Heckle indicates a problem. I explained that it modifies pieces of code in real time, running test cases to reveal which modifications lead to failures. You will see the original and modified code side by side for comparison. This process is integral for identifying potential blind spots in your testing.
00:31:48.000 I reflected on the ongoing journey of self-awareness and integration of new ideas into my programming processes. Many questions can drive improvements, reaffirming the need to recognize both strengths and weaknesses as part of our practice. Thank you.