The elegance of Queues and Stacks

I've been meditating on the beauty of Queues and Stacks. Like Lists, they are collections of objects, but with their own special attributes.

Queues are like a line of customers: the first one in line is the first one you'll serve (FIFO, First In First Out). These could be used for queued up messages that you have to process in order.

Stacks are like a deck of playing cards: the last one you lay on the top will be the first one you draw off the top (LIFO, Last In First Out). These could be used for tracking a sequence of actions that you might need to undo.

You can Peek() at the top item in a Queue or a Stack, but you can't reference a specific item by index. You have access only to the First In or Last In (respectively), and can only add things to the next spot in line.

I like how Queue.Dequeue() and Stack.Pop() both return the next object and remove it from the collection. It seems tidy to do it all in one method. But you're not stuck with that; like I said, you can still Peek() if you just want to see what's next, but leave the object in place.

If you need to deal with your objects in an order relating to how you encountered them, as opposed to sorting by some attribute of the object, then a Queue or a Stack might be a better fit than a List.

Temporary Darkness

Sorry to go dark for a few days. I have more notes from Alt.Net plus some other things I've been doing that I look forward to sharing with you soon. But I'm caught up in a bit of plate-spinning at the moment, which is keeping me away from blogging.

Fail Fast, and Mind the Outs

I had a learning opportunity on two coding concepts (in C#) yesterday:
  • out parameters are tricksy and not to be trusted.
  • Fail fast. When the world starts getting uncertain and hairy, throw an exception and get out of there.

The setup: I'm retrieving app configuration values from the database, a minimum and maximum allowable threshold. The db table is generic, containing key/value pairs for many purposes, so the values are stored as varchars, but I want integers here. If I don't get a value, I have some defaults we should use. The colleague who would be reviewing my code has declared he is allergic to nested if/else blocks, so I need a direct path through this logic.

Too crufty: One might be tempted to think about the logic this way. If I get a value from the database, but it isn't an int, set it to the default; if I don't get a value from the database, set it to the default. When you say it in English, you can hear the repeated code, violating the DRY principle. It's a small repetition, and in a very localized piece of code, but still icky.

Tripping over outs: Since I didn't want to repeat that default value, and I wasn't happy with those elses, I tried this. The default value is 100; if you get a different integer from the database, use that. But I didn't get it quite right:

[using a data reader]
int max = 100;
if (dataReader.Read())
{
Int32.TryParse(dataReader.GetString(0), out max);
//This is wrong.
}
return max;

Can you see what I was thinking, though? "If you successfully parse the result into an integer, set 'max' to that value. Otherwise, leave it alone." That was my mistake. What actually happens is, if TryParse can't parse it into an integer, it makes it undefined. From an msdn article, "The value of an out argument will not be passed to the out parameter."

What I really needed to do there is, "if not int.tryparse, then set it to my default value." I should check the boolean return value whenever I use TryParse.

Hold on, cowboy: But what does it mean if the configuration value in my database isn't an integer? Somebody typed something screwy. And they probably did it by updating the database, not using the admin screen. The world is in an unknown state, society is breaking down—cats and dogs, living together...

I don't want to set any default value. I want to throw an exception and get the heck out of there. So the final version is:

[using a data reader]
int max = 100;
if (dataReader.Read())
{
max = Int32.Parse(dataReader.GetString(0));
//Fail fast and make your escape.
}
return max;

This achieves three design principles, which is why I wanted to write it down and reinforce my learning:
  1. Find the most direct path through the logic. Elses are a smell.
  2. Don't repeat yourself. Even though the repeating here was trivial, it caught my attention and made me think through what should really happen, which led me to...
  3. When you start getting unexpected behavior, hiding it and swallowing it will cause worse problems. If you get a "that can't happen" scenario, throw an exception.

Serving Kool-Aid

[From the Creating Passion, Spreading the Word session]

Tips collected from the discussion on spreading one's values into the rest of the organization...
  1. To convince someone of a solution, you need to help them first see that there is a problem.
  2. Pick your battles: Work on only the highest priority changes, to avoid overwhelming your audience.
  3. Build credibility. Start with a small change, and let its success build your argument for the next change.
  4. Start a forum where team members can share their ideas. Avoid being the lone pontificator on the mount, and instead create a lunch-n-learn atmosphere, where you can be one of many presenters.
  5. Lead not through addition (adding followers), but through multiplication (creating leaders).
  6. Experiment on your side projects. You'll never convince people to risk a wacky new methodology on their huge, stressful, already late, career-defining project.
  7. Build relationships first. Show that you care about the team's success, that you are a member of the team, in order to build trust. One-on-one contact can convey this valued trust—I want to share this with you.
  8. You've followed many steps to come to a conclusion. You need to help your audience down that path, too. Simply handing them the conclusion will not be compelling or convincing.
  9. Passion may start a revolution, but persistence and perseverance are required to see it through. You may get tired of fighting, but lasting change requires more time than you think, so you have to keep fighting.
  10. Remove friction to adoption. Make it easy to do the right thing.
  11. Let your audience ask for "what's next?" Give them a taste of it, and then step back and wait. Let the quest for improvement become their idea.
  12. Discuss ideas, not tools. Teach critical thinking.

Lessons at the End of my Rope

The universe was conspiring to prevent me from climbing tonight—and trying to demoralize me, to boot—but I would not be deterred. After the rather manful weekend of Alt.Net, I needed Ladies Night at the gym, to get some hang time with the girls and scuff a layer of skin off my callouses.

I am reminded of two lessons that will dog me until I learn them.

If I climb only once a week, I will never improve. Whether it's muscles or brain waves, repeated, consistent practice is the only way I'll advance. For strength training, this is intuitive, but it also applies to programming and any other cognitive skill.

A Radio Lab article on sleep explains that, while we sleep, our brains gently wash away the memories of the day, turning down the volume on all of them until only the loudest remain. The next time you practice a skill, you reinforce its memory, amplifying it back up. If you practice a whole lot on one day but then drop it for many days before your next practice session, the practice is all but washed away. If instead you invest a moderate amount of practice every day, you will be able to build on your previous practice.

Which is all a way of saying: I gotta hone my craft every day. And climb three days a week.

The second lesson is about fear. I am so frustrated with the limitations I let fear put on my abilities. To nail the last move on a route, I needed to launch myself, just jump for it, let both hands leave the wall and pop. My legs would not comply; I was holding back.

Why? Well, 30 feet up is part of why, but really. I was safe and capable, and had nothing to fear but a scrape or a wrench or a bruise. Just some "naw, I don't wanna" in the back of my head, until I got angry enough to lunge past it.

Scott Bellware suggested that what differentiates the Alt.Net mindset is a willingness to be comfortable with fear, in the interest of improving. This stuck with me because it let me be proud of my fear; instead of a weakness, it is the indicator that I'm pushing myself and growing.

It wasn't all suffering for my art, by the way. I totally kicked the ass of a project I've been working for weeks, after collaborating on it with two other ladies. (Collaboration? Another lesson here? Sheesh, enough already.) The answer lay in reaching around instead of over, that one inch making all the difference.

My arms are burning, my hands are raw, my cuticles are filthy, and I'm a little bit wiser. It was a good night.

BDD without Friction?

[From the Behavior-Driven Development session]

I could not discern a clear why from this session. Despite that, I think I agree with the tenets of capturing user stories using business-y language and executable code, at least to give your project an executable to-do list.

The debate swirled around whether codifying user stories was better than note cards, should replace note cards, or was just a way to translate human language into something developers could understand (which left me wondering what species developers are, then). I can't speak to BDD's relative merits, but I know a thing or two about having conversations with humans.

Above all, we want to avoid the scenario where the business user says they've changed their mind (their process, their requirements...), and we roll our eyes. We express frustration with their so-called indecisiveness because we're mentally translating that into a big pile of work. A note card has nothing invested in it—throw it away! whatever—but code, a test, a requirements doc, these things all introduce overhead. Overhead = friction = resistance to change = not building the highest priority thing. Your strategic advantage hinges on your ability to change.

Where is the middle ground here?

Because I can surmise benefits in favor of BDD. I love automated unit tests and the confidence they give me to refactor and create code with speed. I'm not alone in hating the maintenance of requirements docs, so they invariably become out-of-date and worse than useless. Executable requirements sound like an appealing alternative. Thinking in the business domain while coding, bringing code and user needs closer together, sound like important contributors to success. I get the impression that BDD brings a change in paradigm that is too subtle to explain to someone not experiencing it, but profound in the way it overhauls your perspective. But I just don't know yet.

Beginners, Speak Out

[From the Creating Passion session]

Beginners to a given topic (TDD, BDD, NHibernate, whatever) should recognize the value of their own voices on that topic.

Brad from University of Phoenix complimented Jean-Paul on the quality of one of his webcasts, but lamented that it was at such a high level. We need a more introductory overview of the concepts. I would suggest to Brad (if I could get a word in edgewise, but that's my own problem) that Brad should make such a webcast.

Those who have just learned a concept, or are exploring and actively learning a new concept, are uniquely qualified to explain it to other beginners. You're close to and you still remember what was challenging about learning it, and what concepts you needed presented to you in what order.

As someone else in the session mentioned, when you are well versed in a philosophy, are a believer in a concept, you followed many steps to reach those conclusions. When you are teaching someone else, you can't present the final synopsis and expect them to ingest it and agree. You need to lead them down the same path.

Those who have most recently walked that path have the best memory of the steps, twists and turns, and points of interest. Beginners have a valuable perspective, and should feel encouraged to toss their voices into the fray. I am reminding myself in this as much as anyone else.

Ladies Night at the Dev Con

Attended the kick-off and agenda-setting of the Alt.Net conference this evening, and I'm already enthusiastic. The guest list is such a who's-who of the development community, there are many topics I'm looking forward to, and the Open Spaces format affords interesting social observations.

I'm the only woman, out of 100+ attendees. I'm relatively used to these ratios—when you're a developer, a rock climber, and a sci-fi geek, you spend a lot of time with boys—but I'm still puzzled as to why. This evening was unusual because someone actually commented on the imbalance; it's usually the Awkward Unstated Obviousness that seems too gauche to acknowledge.

I've been formulating some guesses about why there are so few women at software conferences. Do you have any ideas?
  1. This was only the kick-off. Two or three more may show up tomorrow. This doesn't really change the point, though.
  2. The programmer community is not as gender-balanced as I had thought. The multitudes of women around my workplace are actually managers, project managers, business analysts, test leads, dev leads, and administrative assistants.
  3. Women don't hear about the conferences. (I'm only starting to tap into the info channels, myself.)
  4. Women feel less entitled to ask their employers to fly them to an expensive conference. (Although this one is free. But, in general.)
  5. It takes courage to jump in and be the only girl. When all of a conference's featured speakers are men, you know most of the attendees will be, too. (I was heartened to see Wendy Friedlander on the organizers list of Alt.Net; I hope I get to meet her.)
  6. Women prioritize relationship-building over career development or skills growth, and so do other things with their weekends.
  7. A roomful of men can be tiresome. They shout a lot, often fruitlessly and without seeming to listen to anyone else.
  8. Math is hard.
One nice thing about being a programmer: I can go to a large event and not have a line for the bathroom.

I don't blame the men. If anything, they are guilty only of being men. I always find them to be polite and inclusive. When they're shouty, it's because it's their nature to be shouty, and you need to shout right along with them (They like that.), or communicate with your own quiet confidence (They'll listen.). You don't have to be like a man to hang out with men. You don't have to be like a girl, either. You can just be a developer, be a thinking person with ideas, be yourself.

But you have to show up.
Dark thunder and sun.
Ponderously foreboding.
A dog barks in kind.
We're live!
Which means, now the work begins.