Sunday, March 1, 2015

Embracing Change

I recently listened to a recording of a webinar put on through the ACM titled "Agile Methods: Agile Methods: The Good, the Hype and the Ugly" where Bertrand Meyer (the Eiffel/Design by Contract guy) gave his interpretation of the agile software movement, and how we may tweak agile thinking. 

A point in particular caught my attention.  He talked about a rephrasing of some of the agile principles as stated in the manifesto, and in particular he talked about rather than "embracing" change, one should "accept" change.  While this might seem like splitting hairs, I think it an important distinction, and one I completely disagree with.  I'd like to elaborate why I feel the distinction matters.

The rationale behind Meyer's thinking was that nobody is happy when they have to throw away work.  Say you built a fancy front end for a payment system and then after weeks of development the customer says "nope, that's not what I want" and you have to throw it away.  You're obviously not going to be happy about that, but given the customer pays the bills (and as such your salary), you have to just roll with that punch and start over.  As such, Meyer paints this picture of the developer who begrudgingly throws away his/her pristine work, all the while muttering under his/her breath about how the customer can't make up their mind and resenting the indecision.

I agree with this in principle (I don't like to waste my time), but it fundamentally misses the point of not only the agile philosophy, but of modern professional software development.  As a developer, I don't want to build things for the sake of building things, I want to build things that solve problems.  In particular, I want to build things that provide value to a user (ideally a user who will pay for such services, but the monetary unpleasantries I tend to leave to the business folk).

That is, if what I'm building isn't what the customer wants, I don't want to build it.

This is important.  I'm a craftsman, so I very much care about, and put my entire energy into writing the best code I can, building the best systems I can, but I fully recognize that none of the stuff that goes into that "quality" equation matters if you're building the wrong thing.  As much I love development, it's value is instrumental, not intrinsic.  If the stuff I create never gets used, then it doesn't matter how good it is.

With this in mind, hell yes, I embrace change.  When a customer gives feedback and says "that's not quite what I want" it's music to my ears because it means I'm now that much closer to building the right thing.

So yeah, don't just accept change, embrace it.  Wrap it around you like a warm blanket, secure in the knowledge that because of that change you're now even closer to building something truly amazing that will change people's lives.

Tuesday, February 3, 2015

Book Review: The Software Craftsman

Book: The Software Craftsman


Author(s): Sandro Mancuso
Publisher: Prentice Hall; 1 edition (Dec 14 2014)
Pages/Sections Read: All, cover to cover
Thumbs up/Thumbs down: Thumbs Down
Link(s): Amazon, Author's Twitter

Summary Of Content Read

This book frustrated me. I once had the fortune of seeing Sandro give a talk at the Software Craftsmanship North America (SCNA) conference in 2013, and found his talk uplifting, and inspirational. As a result of that, when I saw this book had been released it was an "instant buy" for me.

Ultimately though I was incredibly disappointed by this book.

I wanted to like this book. Rather I wanted to love this book. And honestly, much of what Sandro espouses in this book I agree with and believe. But, this book is poorly written and filled with anecdotal "evidence" to support his claims. This is a shame, as there is much well documented, well-researched evidence to support much of what he argues for. See, the thing is when you make empirical claims (ie - if you do TDD you will reduce bugs and therefore reduce costs, or if you pair with other developers you will create a culture of learning which will improve productivity, or if you hire craftsmen your company will be better off), you need to back that up with empirical evidence, not just "I had this job once where we did this & it worked...".

By in large if you've ever followed the software craftsmanship community, you'll have heard everything that you'll read in this book. TDD is great so it's an encouraged practice, but we don't hold practices in a dogmatic way. Pragmatism is key. You can't be a great developer without being passionate. Commit yourself to lifelong learning. The craftsmanship movement is about raising the bar. On and on and on, it's all the standard tropes you hear in conversations about software craftsmanship. I went into this book expecting to see something new, or some deep insights, instead I got a series of blog posts that felt very much like preaching to the choir.

There's also lots of heavy-handed "preachyness" in this book. Lots of defamatory comments towards managers, agile coaches, and architects (though back-pedalled in the appendix), and lots of "if you don't do this, then you're doing it wrong" type rhetoric, which I found surprising. The craftsmanship community is supposed to be about celebrating diversity and being welcoming of anyone, of any skill level so long as they're willing to better themselves and learn more.

There's also lots of inflammatory/adversarial commentary (ex: "QA teams are an anti-pattern", "are you good enough to work on legacy code?", "tech debt items are an excuse to justify bad code", "software craftsmen are never scared to lose their jobs", "only incompetent people fear losing their jobs", "university degrees don't mean anything", etc) that feels very elitist & arrogant. Lots of straw man commentary, painting conversations with Dilbert-esque pointy-haired bosses in a very biased light.

Lots of sweeping generalizations, and little in the way of new insights. There's a lack of focus or coherent theme to the book. Who is this for? Is it for "apprentice" craftsmen? For people who've heard about this software craftsmanship thing and want to know more? For the Bob Martin's of the world? It's so inconsistent, some of it feels written for an audience who's only vaguely familiar with the craftsmanship movement, and other parts feel like unless you've been writing code for decades you'll have trouble relating.

I'm being overly harsh, there are nuggets of really good insights in this book and he certainly knows the craftsmanship movement. The thing is though there's nothing you won't get from simply reading the blogs or books of some of the people in the craftsmanship community. If you've read Clean Coder by Bob Martin, there's no reason to read this book.

Monday, January 20, 2014

Book Review: Java Puzzlers

Book: Java Puzzlers

Authors: Joshua Bloch and Neal Gafter
Publisher: Addison Wesley
Pages Read: all
Sections: all
Thumbs up/Thumbs Down? Up, slightly sideways
Link: Amazon

Summary of Content Read

Java Puzzlers is not so much a book, but a collection of obscure corner cases in the Java programming language.  The author (Joshua Bloch) is well known as the author of "Effective Java" which is widely regarded as the premier text for the language, and furthermore he is one the designers and authors of the Java Collections Framework.  So to say the least, he knows his stuff.

Each chapter of the book features a collection of "puzzlers" centered around a particular section of the language (examples include loops, strings, exceptions, classes, etc).  Each "puzzler" is formulated where a puzzle (typically in the form of a code snippet) is given, and the reader is encouraged to try and predict what the output will be, or why the code is incorrect.  Then an answer/explanation of the puzzler is given.  All-in-all there are 95 different puzzlers across the book, and they range from the fairly common "if you thought about it a bit you'd figure it out" to the extremely obscure "unless you were a Java language designer you'd never have any hope of figuring this out".  The explanations also often include commentary to language designers (ex: "the lesson for language designers here is..."). 

From an academic "curiosity" point of view the book is quite intriguing.  As a fairly experienced Java developer I found myself surprised with the vast majority of the puzzlers.  The programming languages guy in me found this fascinating (ex: wait, so you can have Unicode literals in comments, and those literals are interpreted by the compiler?).

Having said that, the book does reach a point where the puzzles and concepts hit upon by the puzzles are extremely obscure.  For a typical Java developer you'll almost never run into most of the tidbits in this book.  That's not to say that reading it isn't useful, you'll definitely learn a bit about the book, but if you're looking to learn "how to write good Java code" this is not the book for you (again, see Bloch's other book for that).

Book Review - The Clean Coder

Book: The Clean Coder - A Code of Conduct For Professional Programmers

Author: "Uncle" Bob Martin
Publisher: Prentice Hall
Pages Read: all
Sections: all
Thumbs up/Thumbs Down?  Up
Linky: Amazon

Summary Of Content Read

This book is largely a follow-up to Martin's other very well known book "Clean Code".  Whereas that book focuses on the artifacts (code) we developers produce this book focuses on the developer his/herself.  How should we as professional developers act?  What is the difference between a commitment and estimate?  What are our responsibilities?  When can we say no & how do we do it?  When are we obligated to say yes?  How do we get better at what we do?

Martin tries to distill his nearly 40 years of experience into some hard fought lessons.  While it is very much appreciated to hear "tales from the trenches", the book does have a fairly heavy-handed "do as I say" tone.  Don't do TDD?  Well then you're not a professional.  Do you create ambitious estimates?  Well then, you're not a professional.  From a rhetorical point of view, the book does rely on this "proof by appeal to professionalism" approach, rather than give solid evidence and data to back up many of the arguments he makes.  For example, the TDD chapter has the passage:
Yes there have been lots of controversial blogs and articles written about TDD over the years and there still are.  In the early days they were serious attempts at critique and understanding.  Nowadays, however, they are just rants.  The bottom line is that TDD works, and everybody needs to get over it.
I feel like the paragraph should have ended with "QED".  Hardly a conclusive argument in favour of TDD, and the off-hand dismissal of any critiques of the practice really does hurt the point he's making.

Having said all this, it is certainly clear that much of what he offers is good advice, and represents an open challenge to developers to be better.  If you put aside the "if you don't do this you're not professional" rhetoric, at its core this book is a call for developers to live up to the responsibility of the job they have been hired to do.  Oftentimes we as developers like to silo ourselves off, focus on our narrowly defined technical tasks, and that is simply unrealistic.  Part of the responsibility of being a developer is to understand the context of the work you do, why it's important and why it adds value to the customer/client/business/etc.  And if that value isn't there, it's up to you to find it.

As such I found this book both refreshing and terrifying.  Refreshing to hear a voice from the agile community who doesn't seem to feel that the PO is the only entity responsible for identifying value. 
Terrifying to think that I, as an introverted software developer, has a duty to do more than just simply write good, clean code.

In terms of structure, the book is divided into 14 different chapters each covering a topic of interest to professional developers.  While there is some technical discussion, it is relatively rare, by in large the chapter topics focus on "soft" skills rather than technical ones.

All-in-all, while heavy-handed and at times "preachy", it is very much a worthwhile read for anyone considering or living a career in software development.

Friday, November 1, 2013

EqualsVerifier

This looks more than a little cool for those of us (like me) who are pedantic about testing out equals/hashcode/compareTo methods:

http://www.jqno.nl/equalsverifier/

Friday, August 3, 2012

Git bisect And Nose -- Or how to find out who to blame for breaking the build.

How did I not ever discover git bisect before today?  Git bisect allows you to identify a particular commit which breaks a build, even after development has continued past that commit.  So for example, say you:
  • Commit some code which (unknowing to you) happens to break the build
  • You then (not realizing things have gone sideways) continue on doing commits on stuff you're working on
  • You then are about to push your code up to a remote master, so you finally run all those unit tests and realize you broke the build somewhere, but you don't know which commit introduced the problem
In a typical environment you'd now have a fun period of checking out a previous revision, running the tests, seeing if that was the commit that broke the build, and continue doing so until you identified the commit that introduced the failure.  I have experienced this many many times and it is the complete opposite of fun.

If you were smart you might recognize that a binary search would be effective here.  That is, if you know commit (A) is bad, and commit (B) is good, and there's 10 commits in-between (A) and (B) then you'd checkout the one halfway between the two, check for the failure, and in doing so eliminate half the possibilities (rather than trying all 10 in succession).

And if you were really smart you'd know that this is exactly what git bisect does.  You tell git bisect which commit you know is good, and which commit you know is bad, then it steps you through the process of stepping through the commits in-between to identify which commit introduced the failure.

But wait, there's more!  There's also a lesser-known option to git bisect.  If you do a "git bisect run <somecommand>" then the process becomes completely automated.  What happens is git runs <somecommand> at each iteration of the bisection, and if the command returns error code 0 it marks that commit as "good", and if it returns non-zero it marks it as "bad", and then continues the search with no human interaction whatsoever.

How cool is that?

So then the trick becomes "what's the command to use for <somecommand>?"  Obviously this is project dependent (probably whatever command you use to run your unit tests), but for those of us who are sane Python devs we probably use Nose to run our tests.  As an example, I often organize my code as follows:

project/
     +--- src/
             +--- module1/
             +--- module2/
             +--- test/

Where "module1" contains code for a module, "module2" contains code for another module, and "test" contains my unit tests.  Nose is smart enough that if you tell it to start at "src" it will search all subdirectories for tests and then run them.  So lets say we know that commit 022ca08 was "bad" (ie the first commit we noticed the problem in) and commit "0b52f0c" was good (it doesn't contain the problem).  We could then do:

git bisect start 022ca08 0b52f0c --
git bisect run nosetests -w src

Then go grab a coffee, come back in a few minutes (assuming your tests don't take forever to run), and git will have identified the commit between 0b52f0c and 022ca08 that introduced the failure.  Note that we have to run git bisect from the top of the source tree (in my example the "project" directory) hence we need to tell nosetests to look in src via the -w parameter.

Thursday, June 7, 2012

Handy Python tip #1

The other day I was adding the rich comparison methods (the ones for operator overloading) to a class I had defined.  Like many Python programmers before me I wondered "why is it that if I define a method for equality, I still have to define a not-equal method?" and "if I define a comparison method, why do I have to define the other comparison methods?"

And then low and behold, while looking for something completely different, I stumbled across the functools.total_ordering class decorator.  With it, you can define just the __eq__ method, and any rich comparison method (__le__, __lt__, __gt__, etc), and it provides default implementations for all the others.

Very handy stuff.

An example can be found in my MiscPython examples collection on Github.