Monday, December 12, 2011

Resharper: a refactoraholic's dream come true

So I recently discovered Resharper, and it's a refactoraholic's dream come true. Most of the tedious routine tasks are now automated, just the way they should have always been. Why oh why God did you make me wait so long for this miracle? Why did I have to waste countless hours doing manually what was always meant to be done automatically?

Not sure if your field is used from anywhere else? Resharper already knows and suggests before you may even wonder. Is your naming scheme consistent? Resharper will tell you all about it. Apparently you can even apply a solution-wide code analysis, which I haven't yet tried, but it sounds promising.

It may seem a bit intrusive, popping up with suggestions all over the place, but it works for me, so far most of the suggestions have been very sensible, and it definitely beats the shit out of Visual Assist. Oh and it provides a Unit Testing framework too, while it's at it. Not too shabby.

Thursday, December 1, 2011

Good management vs. bad management

In my relatively short career, I have seen a LOT of bad managers, and relatively few good ones (one of the readers of this blog included in that). The subject has always interested me immensely, since a manager, often to a much greater extent than any of the people that work for him, determines the success or failure of a project. So what are some of the skills that make a good manager?

Area 1: People Skillz. 

A good manager is good with people, at least to the extent that the job requires it. You don't have to be a social butterfly, but you gotta be able to talk to people about what's important. The other important factor here is alpha-ness. It's about being able to ask things of people in a way that would motivate them to take action. It's also about being able to stand up to criticism from higher-ups and insisting on what's right. You need to muscle your way thru opinionated people and convince others of the merits of your case, whether it be on technical grounds or sales numbers, or just plain common sense. You need to know how to make people listen. 

There is also the flip side to that. I have seen too many managers who are too alpha. That means they're too dismissive of their subordinates, they don't listen enough, and they trust their gut instinct too much at the cost of proper decision making. The uber-alpha manager always thinks he/she got things under control, which can be a bad thing (see Area 5). Being too alpha can also mean demanding the impossible. ("We have to do finish this 5-month long project in 1 month and we have to do it perfectly"). Demanding the impossible and not listening enough will also mean losing the respect of the subordinates, who will not take you seriously, or despise you for wasting their time. 

Area 2: Responsibility a.k.a. giving a shit. 

This is a big one. It sounds obvious, but I've seen too many managers lacking passion for the project they're working on. If a manager only cares about having the burndown chart go to zero, or meeting the deadline without getting into the details of what that would really mean, he's a lazy fuck and needs to get some sense knocked into him (which would require someone above to detect the laziness and take action). The manager who doesn't give a shit, will never take responsibility for the project going wrong. The deadline slipping is always the fault of somebody else, "I was watching the burndown chart, and it looked like we were gonna make it, and then Bob put in this extra task at the last minute, so we failed because of him." This type of statement is usually followed up by some hand-waving: "But don't worry we're gonna make it anyway". The irresponsible managers also tend to socialize with each other at the cost of the team, to give each other a pat on the back when everything goes to hell. A responsible manager admits failure when it happens, and, what's more important, is going to try to do better in the next iteration. It's about the self-improvement attitude. Unfortunately, it seems like some managers are in it for the Manager at the XXX Corp title. Once they got the title, their job is done. I know I'm being silly, but sometimes it feels like that's how things work. 

Area 3: Time Management

This is the classical thing they teach in school and is covered extensively in books. How to manage your time and the time of your team. How to do project planning: estimates, burndown charts, how to handle the complexity of a project. Unlike Area 2, this is not a personality trait, but a skill, and most managers tend to have some idea what to do here. The problem comes later when (surprise!) the estimates don't reflect reality and something needs to be done. The manager inevitably needs to get into the details, as time management skills in and of themselves will only get you so far. This skill can improve with (management) experience.

Area 4: Technical Skillz and having a clue. 


You need to be able to know what the hell is going on. An art manager needs to know something about art, a programming manager needs to know something about programming. You need to know what estimates make sense for a particular employee or department.You need to know when people are throwing dust in your face, or (when they're throwing dust in their own face).  This bullshit-detector cannot be purchased at Walmart, and comes only with (technical) experience.

Area 5: Knowing Where the Project Is and where it needs to be

It's about really having a clue whether the project is 6 months from completion, or if it's 5 years away (as well as knowing what "completion" really means). Sounds easy, but this is the area where most of the bad managers I've seen failed completely. At least in the few places where I've worked, managers seem to get into the state of denial with unprecedented ease. Often an indicator of a manager who is bad at Area 5 is the following situation: when they declare a deadline, everybody on the team immediately knows they're not going to make it. The manager himself will continue insisting that that's where the deadline is and the scope won't change, until it's too late. You can blow dust in people's face, but you should always know that you're doing it and not kid yourself about making a deadline. The deadline is important, but just as important is the scope. What is it that is going to be delivered? What kinds of adjustments would need to be made to still make the deadline even though not everything is done? What kinds of corners can be cut, and what kinds of corners are too expensive to cut? Does the deadline need to be postponed? If so, will it be just one more week, or are you just kidding yourself again? You can SAY it's one week to sell it to the customer, but you need to know you're lying for your own sake.


Area 6: Knowing HOW to take the project where it needs to be


This is about knowing how to take a project from A or wherever it is to Z, the final deliverable. It will take all of the above skills together to achieve that, and no wonder good managers are hard to find. It's a tough job, but somebody has to do it. 

Tuesday, October 4, 2011

Refactoring and code ownership

So I've been given a pretty big chunk of Perl code to work with. It's about 30 pages of pure hell, all in one file, and considered unmaintainable by some. Of course the word unmaintainable is not in my vocabulary (and apparently not in Blogger's dictionary either), and somebody had to do the job, so the Refactorinator comes to the rescue.

At the surface level, refactoring Perl code is not that much different than refactoring C++.

  1. Identify groups of variables that belong together, and group them into chunks / structs, that can be passed around between files and functions without creating too much clutter. 
  2. Break up the monster functions into smaller functions. Passing data between functions should be easier because of step 1
  3. Break up the monster file into multiple files, and hopefully never look at some of these files again. Hopefully at this point, we have arrived at some self-contained functions (step 2) with relatively short function signatures (step 1). 

OK, I realize there's nothing Perl-specific here, I guess I'll have to make another post about that. But perhaps the lesson I'm learning here is refactoring is pretty universal, as long as the language supports multiple files, struct-like constructs, and basic functions.

Am I regurgitating basics here, being Captain Obvious? Maybe so, but then if the principles and techniques I'm writing about are so basic, then why the hell do I so consistently come across code with exactly the same mistakes time and time again? The short answer is "up front cost". That's a cost a lot of people are hesitant to pay, especially if there are ownership issues:
  • Code has no clear owner - why should i clean up somebody else's code?
  • Code has an unfriendly owner - your cleanup is very much unappreciated, because the owner a) thinks refactoring is a waste of time or b) has a big refactoring plan in mind himself, which he'll probably never get around to, but in the meantime you shouldn't ruin his grand plan
  • Code has another owner - even if he's friendly, why should you do his work. 
  • Code has an owner that doesn't believe in refactoring
  • Code has an owner that believes in refactoring in principle but never gets around to it in practice
At the end of the day, it is beneficial that every piece of code, no matter how amorphous or scary, has a clear owner. That owner can invest in cleanup and reap the long term benefits. Or he can choose to not invest and pay the price. It's fair either way. It's most important, however, to never get in a situation where noone invests and everyone pays the price.

Tuesday, September 20, 2011

Tips for debugging

A reiteration of some well-known truth, but it's nice to have a refresher anyway:

Watch it on Academic Earth

Tuesday, September 13, 2011

Short term memory

A few weeks ago I picked up this mobile app, that tests your short-term memory. It's basically the classical "find pairs of matching cards" game that kids always play, just with a lot of variations, and difficulty levels. On the Android store, it's called "Matchup", and I highly recommend it.

Here's some observations I made about this game:
  • It doesn't get that much easier with time. While with many "fundamental knowledge / trivia" games you might end up knowing all the answers at the end, and be quicker, with Matchup, you don't really have much of an advantage, whether you're new at it or have been a seasoned player. 
  • Your skill goes up after a while, and then down again, as you get fatigued and start getting confused
  • It really helps to pronounce the names of objects either out loud, or at least internally. Your short-term memory is better when you connect it to auditory clues, instead of visual ones. 
  • Unfortunately that means that any auditory distractions (and most external distractions are auditory), will have a tendency to throw you off
  • It helps to repeat, and when matching pairs are found, to re-pronounce the list of remaining cards to yourself. It helps to know the names of the objects, or have an internal self-made name for them. I typically play the flag version of the game, and I found that if I don't know the flag names, improvising them on the fly takes up more energy and is more error-prone.
  • The other thing that can throw you off is if you think you need one word to represent the object, but in fact it is not sufficient to distinguish it from other objects. For example if you flip a card with a car in it, the first word that comes to mind is "car", until a car of another color comes up, then it's important to re-pronounce the list with "yellow car" and "blue car" in it.
What I find frustrating about this game is that the skill is not really cumulative,  and doesn't work like IQ tests or math puzzles. Many times math or visual puzzles can be hard, but once you get the trick, your speed can go up drastically. Unfortunately, short-term memory games don't follow this rule. As soon as you lose focus, you'll start missing a lot of points. There are tricks, but they're not automatic, and take effort every time, so how well you do depends on you following the script, more than it does on "getting good".

How does this post belong on the refactoring blog? Well of course short-term memory is very useful when it comes to programming, especially in debugging mode, because you need to keep a lot of details in mind at the same time in order to make sense of the complex state of the program. So play memory games folks, and be a happy programmer!

Monday, July 25, 2011

On getting it right the first time

As I program more and more I'm beginning to realize the following:

There is no such thing as getting it right the first time. In fact, this may even be a bad way of thinking about coding altogether. You can only approach the "correct" solution assymptotically with iterations. The concept of "right" may not even exist as such in the early stages of a project. Trying to "nail it" from the start by up front design, is a misunderstanding of the process. The best you can do is a good first prototype.

Some coders I know go by the principle of "code correctly now, so you have to change less later". At first glance it makes sense, but I would take it with a serious grain of salt. In fact, I would say it could be damaging to software development to think this way, since a philosophy like that leads to being afraid of getting it wrong, and then you run the risk of settling yourself in with a rigid up front design.

Instead I find it best to expect and embrace change. To me, the first iteration is all about getting the result as quickly as possible, on top of any underlying datastructure. The "proper" datastructure will become clearer as the results come in. Rather than being afraid of refactoring, I take it as an integral part of the process, and I expect to do it. It is a process, where the goal is to get it right in the end, rather than at the beginning, it's all about exploration and constant change. Contrary to popular belief, though, this change is not equally distributed with time. Eventually we need to converge to the final product, so the amount of change needs to be less and less as time goes on. If refactoring is taken as an integral part of the process, the datastructures you have at any given moment, reflect a better and better understanding of the system, and the vocabulary of the code converges on the vocabulary of the problem space.