warpedvisions.org

ESSAYS, HOW-TO ARTICLES, AND GENERAL MAKERY BY BRUCE ALDERSON.

Merlin Mann asks us why we're waiting to be awesome, as he remembers Steve Job's 2005 Stanford address. It's a good question: why do we wait?

There are all sorts of reasons, of course, but in the end my simple philosophy is: just fucking do it. Sometimes I have to say it to myself out loud, in the voice of the Dude, when things like absurd politics or chunky technical problems get in my way. “Just do it, man.” I need to be reminded to carry on.

...the only way to be truly satisfied is to do what you believe is great work. And the only way to do great work is to love what you do. If you haven’t found it yet, keep looking. — Steve Jobs, 2005

It isn't just doing what you love, you also have to choose to love what you do. Love the hard parts, get off on doing them. There will always be bullshit around what you love, if you choose to see it. Instead, let the noise melt away and get good at your craft. And then do it. Lots of it!

You don't need to wait to be awesome. — Merlin Mann

Don't wait. Don't see the bullshit. Don't even worry about the hard shit, it's the hard bits that really hone your craft. Work through it, do it well, and be proud of what you do. And over everything else, don't wait for a reason to do it. Be awesome.

When you describe a design to a group of people, each person imagines something different. Depending on your story and the individuals, understanding may vary wildly. And if it differs enough, the result is chaotic—unpredictable and often negative.

You need to fit how you show your ideas to different groups of people carefully, and notice when you your story isn't hitting. For your closest team members you can wave your hands and scrawl ideas on a chalkboard. For people you work less frequently, you need more detail: proper drawings and clean wireframes. For non-technical clients you need even more, polished, functional prototypes and pretty drawings.

When you fail to excite people with your ideas you do more harm than good. They imagine something more or less than what you're thinking, leaving them disappointed and confused. You give them a different taste than you intended, which you will have to work to overcome in the future. Instead, you need to spark their imagination skillfully, stirring lively, constructive discussion.

A working example

One of the products I'm working on is a refresh for an ancient financial system. We're working to make it scalable, easy to operate as a web service, and viable as a business for the client. Each of these problems is interesting and fun.

Early in our prototype work I made the mistake of leaking a technical proof to one of our non-technical team members (not the client, luckily). The prototype proved that we could reproduce the legacy calculations accurately, using cheap, common tools and schema design. Technically we were excited about the win, so we showed it around internally.

The problem with technical prototypes is that they lack pizzaz, often intentionally. This piece of the prototype matched the old system design to make it easy to test, but looked dated and out of place in a modern web app. The effect of showing this stage of the work to the wrong people bogged down our shared picture of the product. It killed our momentum and excitement, which took time and energy to recover. The loss was more psychological than literal, but was a cost nonetheless.

The next planned task, of course, was to find the visual styles for these screens, as now we knew that they were technically possible. And the design turned out better than expected, but the win was dulled by the lost momentum and our gains were smaller than they should have been.

More than words

The problem isn't just in the explanation or the path, it's in the combination of people, experience, and approach to the narrative. Each thing you show (and how you do it) matters. Each person's understanding and contribution matters, as they are part of the momentum. Focus what you deliver, think clearly about the presentation, and keep your audience in mind.

There's a bigger win in showing off the right work to the right people: it forces you to deliver better quality earlier. The risk and of miscommunication is real, and the wins—when you get them—are golden. Force yourself to show off better work, make it a personal goal. Challenge your team to show better work too. It pays off in a multiplicative way, and that's good for the things you build.

#Design

Boost's Filesystem library is an incredible resource: it abstracts paths, directories, and stat results. It simplifies coding shell problems in C++, it's portable, and is maintained by a large community of contributors. The one downside of Boost is that some of its newer libraries are poorly documented. ((Something I want to contribute to.)) Until I have time to get involved in the Boost project, I'm going to post examples here.

Traversing a directory tree

This is the coolest feature I've found in boost::filesystem so far. It treats directory elements like iterators, and has a convenience iterator that flattens the problem of iterating through a directory tree recursively. The only examples I found for it were in their extensive test sources, (See convenience tests and operations tests for more examples.) which are a bit light on comments.

#include "boost/filesystem.hpp"
#include <iostream>

for ( boost::filesystem::recursive_directory_iterator end, dir("./"); 
       dir != end; ++dir ) {
       cout << *dir << std::endl;                                    
}

The example starts in the current working directory, and prints all of the file names (and directories) in inode order. ((Later I'll try to post an example that uses the stat features to dump extra information.))

Notes:

  • I don't alias the namespace here (but I recommend doing so in production code, see below)
  • Creating an instance of recursive_directory_iterator sets it to the .end() element by default.
  • The path type supports all standard string paths, including relative paths.

Aliasing Boost namespaces

Here's how Boost's own source recommends aliasing their namespaces:

namespace fs = boost::filesystem;
namespace sys = boost::system;

Other cool bits

I'll write more about these later, but for now here are a few things you'll find in the library:

  • fs::exists( boost_root / "libs" ), a static function to check if a file exists (-e)
  • fs::current_path() that returns the application's cwd
  • fs::create_directories( "xx/yy/zz" ) is equivalent to mkdir -p xx/yy/zz
  • fs::is_directory( "xx" ) is the same as Perl/*sh's -d
  • fs::change_extension("a.txt", ".tex") does the obvious
  • fs::extension("a/b.txt") == "txt" is used to check file extensions
  • fs::remove_all( "x/" ); deletes everything in "x/"
  • ifstream file2( arg_path / "foo" / "bar" ); shows the overloaded / operator!

Things that are great about boost::filesystem's approach:

  • Static functions are used for 'helper' stuff. Take note C++ devs: this is a great balance for types, it keeps the types noise-free while still providing a great deal of utility.
  • It mirrors Perl/*sh functionality, something most developers should know well.
  • It throws errors (filesystem_error), allowing for some really clean, transactional code.
  • And, it abstracts paths that work on Win32, OSX, Unix, and Linux variants.

#boost #c++

Enter your email to subscribe to updates.