All atomic-powered posts from March 2010:



Atomic Object is Honored as a "Michigan 50 to Watch" Company

Writing about how awesome you are, or how great your company is, isn’t effective marketing according to Kathy Sierra (via Joel Spolsky’s recent (and perhaps final?) blog post). Sometimes you’ve just got to ignore this otherwise sound advice. This is one of those times.

I’m delighted and proud that Atomic Object was selected this year as a Michigan 50 Companies to Watch company by the Edward Lowe Foundation. The 50 to Watch award recognizes privately held, second stage companies that have demonstrated intent and capacity to grow. (For more on the award and foundation, see our press release.) Being one of the 300 companies selected over the six year history of the program exemplifies for me the two drastically different perspectives on Michigan’s economy evident since we started Atomic in 2001. On the one hand, we have the gloom and doom portrayed by the national media. On the other, we have world-class, growing companies like Atomic, DornerWorks, and Maestro eLearning (one of our customers, and the parent of Bloomfire). All three of these companies have been recognized as a 50 to Watch company in 2010. It may take a generation for Michigan to fully adjust to the realities of the global economy. I’m very proud that Atomic is a small (but growing!) part of that adjustment.

Atomic is more than the sum of its parts. It’s 10 years worth of learning, 10 years of earning customer trust, 10 years of sharing our innovations with the technical community, 10 years of figuring out our business on the fly.

But mostly Atomic is people.

Atomic today is 28 people. My co-founder Bill Bereza, without whom I might not have had the irrational confidence needed to start the company. Our first apprentice, Mike Marsiglia, whose broad talent now helps me with sales and finance. Karlin Fox, responsible for many internal innovations and holder of critical viewpoints. Micah Alles, who stepped up to the critical role of system administrator while maintaining his development leadership. Dave Crosby, our passionate and humorous first software craftsman, who was nearly there from the beginning and has mentored so many. Mary O’Neill, our business manager and my wife, who so adeptly wears many hats, all taken at one time or another off my head. Shawn Anderson, who always knew he’d return to the fold. Mike Swieton, one of our most flexible and thoughtful talents. Shawn Crowley, who’s moved us so effectively into product development practices, and who stepped up at a critical time. Mike Karlesky, who spearheaded building up our embedded work. Scott Miller, the first person with significant prior work experience to figure out Atomic was a good bet. Matt Fletcher, who shares my academic bent and has such high standards for himself. Patrick Bacon, with his incredible skills, steadiness, and positive attitude. Justin DeWind, who can tackle any problem, and inspired me to learn something about economics. Dustin Tinney, who codes with the soul of an artist. Drew Colthorp, who never acts like the smartest guy in the room, even when he probably is. Greg Williams, king of our embedded realm. Andrew Witte, our boy genius, all grown up. Greg Pattison, who so effectively expresses the critical project worry gene. Ryan Fogle, unflappable and productive like few others. Melissa Bugai, the first person in our office to carry the banner of exploratory testing forward. Michael Harrington, the most persistent apprentice applicant we’ve ever met, and thank heavens for it. Andrew Bellenir, keeping us safe from attack. Marissa Christy, proving the dictum of hiring brains over experience and spreading the word. Samuel Bowles, who is leading our growth in design. Kyle Gibson, the latest young developer to start down the path of craftsmanship with us. And finally, Paul Hart, who gives us a design pair and has already started teaching us.

I’m humbled and honored by the people I work with at Atomic. Being recognized as a Michigan 50 company is an acknowledgment of their abilities, hard work, perseverance and attitude.

Software GR March: Charles Nutter on JRuby, JVM Languages, and InvokeDynamic

Last week Software GR was lucky enough to host Charles Nutter. Charles is a principal on the JRuby project and has worked on JRuby for more than 4 years. This was a fantastic and in-depth technical talk ranging from an overview of the JVM’s “other” languages and then diving deep into the guts of what makes JVM languages work.

We looked at JVM bytecode and Charles showed us some of the strategies JRuby uses to achieve good performance and how that will change with Java 7 and cool new dynamic language-supporting features like method handles and invokedynamic.

Don’t sweat it if you missed this talk: there is more coming up! Check out the Software GR web site for the latest schedule. The rest of the year is going to be great!

IE8 CSS Rendering Order


Catalog Choice in IE8 with on dialup

Recently on Catalog Choice we started receiving complaints of our login buttons not being visible in IE8. After some investigation we found a combination of a slower connection and IE8 CSS rendering to be the cause.

IE8 would download and render the CSS before images in our CSS file had loaded.

Because we used the Phark Revisited image replacement technique our users were left with link text negatively indented off the screen and no CSS background images.

We were able to simulate the slower connection behavior using an IP firewall, ipfw.

sudo ipfw pipe 1 config bw 28kbits/s
sudo ipfw add 1 pipe 1 src-port 80
sudo ipfw add 1 pipe 1 dst-port 80
sudo ipfw delete 1 (to remove when finished)

This then gave us an environment to simulate the bug without needing to reopen our AOL accounts. To fix the bug we move towards the Gilder/Levin Method.

With Gilder/Levin users on IE8 will still see missing images but the link text is left in place allowing a user to login.

U.S. Students Not Dumb in Math & Science After All

Does the U.S. Produce Too Many Scientists?:
Beryl Lieff Benderly, Scientific American, February 22, 2010

Average scores for K-12 students in the U.S. never top those lists in either science or math (although they do in both reading and civics). On one widely cited assessment … U.S. students ranked between fifth and 12th in math and science—results bemoaned by many as dangerously deficient.

But a detailed study of students’ performance … suggests otherwise. ‘Their point is that the average performance of U.S. students on these comparative international tests is not a meaningful number,’ Teitelbaum says. Far from trailing the developed world in science education, as some claim, ‘on PISA, the U.S. has more high-scoring kids in science than any other country’ and nearly as many in the top math category as top-scoring Japan and Korea, Salzman says.

... raising America’s average scores on international comparisons is, therefore, not a matter of repairing a broken educational system that performs poorly overall, as many critiques suggest, but rather of improving the performance of the children at the bottom, overwhelmingly from low-income families … This discrepancy, of course, is a vital national need and responsibility, but it does not reflect an overall insufficient supply of able science students. Nor do American students lose interest in science once they reach college.

For as long as I can remember, I’ve always known the U.S. to be lagging behind the rest of the industrialized world in technical education. The excerpt above is the first account I’ve ever come across that speaks counter to this notion (and isn’t it interesting that even the average U.S. scores top other countries in reading and civics). It makes sense. As one of the largest industrialized countries (both geographically and by population), statistical effects are sure to skew simple averages and inspire doom-and-gloom headlines.

Incidentally, the primary thrust of the quoted article is to dispel another widely held notion—that the U.S. does not produce enough top-flight technical talent. From the article, however, it seems it’s merely the makeup of the U.S. job market for PhDs in Science and Engineering that creates this illusion.

At the time of this post, Grand Rapids, Michigan is the 114th largest city in the nation (by population). Anecdotally, I believe I can attest to the claims of the Scientific American article. Though Atomic Object is quite selective in whom it hires, we haven’t had a tremendously difficult time finding the Atoms the make up our molecule. In fact, I would say that our employees are some of the brightest and best educated technical people I’ve ever known. And the same goes for many of the very bright employees of our clients with whom I’ve worked and become friends.

(via Delanceyplace)

Why we probably won't sign your NDA

Entrepreneurs and potential customers sometimes ask us to sign non-disclosure agreements (NDAs) as part of figuring out whether we can help them or not. We usually don’t sign NDAs at this stage of a potential relationship for several reasons.

The idea isn’t everything

We want to help entrepreneurs understand that “the idea” is not the critical factor to their success.

We’ve learned a lot from Paul Graham. Here’s what he says on the subject:

An idea for a startup, however, is only a beginning. A lot of would-be startup founders think the key to the whole process is the initial idea, and from that point all you have to do is execute. Venture capitalists know better. If you go to VC firms with a brilliant idea that you’ll tell them about if they sign a nondisclosure agreement, most will tell you to get lost. That shows how much a mere idea is worth. The market price is less than the inconvenience of signing an NDA.

—Paul Graham, How to Start a Startup

The cult of the NDA

We don’t want to perpetuate the cult of the NDA.

Sharing is critical

We believe most entrepreneurs would be better off sharing their idea with everybody and anybody to get feedback.

Sentence three of Paul Graham’s Startups in 13 Sentences is “Let your ideas evolve.” That can and should start before you’ve spent a dime on development.

Listening to our lawyer

NDAs are serious legal documents. Our lawyer says it’s a bad idea to sign one before we know the party well and understand what we’re promising not to disclose. He’s particularly not fond of NDA’s that are broad and general. We try to listen to him.

In the rare event that a potential client has genuine intellectual property that hasn’t yet been protected by filing for a patent (or maybe even a provisional patent) we can usually still have a valuable conversation without getting into trade secrets. We’re happy to sign the proper legal documents once we start working together.

Lazy thread-safe collections in Java

I recently needed to update some Java code that was frequently making unecessary calls to an external web service. Depending on the particular UI component, or the item being displayed in that component, a large set of the data being retrieved ended up not being displayed. My task was to update the code so that it only made external calls to the web service when the data was going to be displayed.

My first thought was to pass along a flag from the view layer that would indicate whether or not to retrieve the data in question. This would require updating all of the UI classes that displayed the data, as well as passing the new flag through several additional method calls to prevent the data from being collected when it wasn’t needed.

I did not care for this solution because it meant changing several classes so that details of the view could be passed down into the data retrieval logic. Instead, I came up with an alternative solution, the crux of which is a generic, thread-safe, delayed evaluation Map.

Instead of the business layer service returning a fully populated Map of data, it returns a Map that will contain that data, if it is accessed. If no user interface components request the data for display, the data will never be retrieved. This meant that I did not have to change any code outside of wrapping the logic for populating the Map with a new LazyImmutableMap. Here is an example of how it is used:

1
2
3
4
5
6
7
8
9
10
11
public Map<String, String> getData(final Integer id) {
  return new LazyImmutableMap<String, String>(
    
    new Callable<Map<String, String>() {

      public Map<String, String> call() throws Exception {      
        return externalService.getSomeData(id);
      }
    
  });
}

The call to externalService.getSomeData() will only be invoked if something tries to access an element in the LazyImmutableMap. Implementing the class itself turned out to be extremely simple with the help of Google Collections’ ForwardingMap (see this previous post for more on Google Collections) and the standard Java concurrency class FutureTask.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public class LazyImmutableMap<K,V> extends ForwardingMap<K,V> {
  public static class AccessException extends RuntimeException {
    public AccessException(Throwable cause) {
      super(cause);
    }
  }

  private final FutureTask<Map<K, V>> task;

  public LazyImmutableMap(final Callable<Map<K,V>> eval) {    
    task = new FutureTask<Map<K,V>>(new Callable<Map<K,V>>() {
      public Map<K, V> call() throws Exception {
        return ImmutableMap.copyOf(eval.call());
      }
    });
  }

  @Override
  protected Map<K, V> delegate() {
    task.run();
    try {
      return task.get();
    } catch (InterruptedException e) {
      throw new AccessException(e);
    } catch (ExecutionException e) {
      throw new AccessException(e.getCause());
    }    
  }
}

The constructor creates a FutureTask that when accessed will return an immutable copy of the Map provided by the passed in Callable.

Extending ForwardingMap means that I only needed to implement the delegate method to get a fully compliant Map class. The FutureTask takes care of preventing the passed in Callable from being executed more than once, and it’s thread-safe, so any number of threads can access an instance of the map simultaneously.

Unfortunately Java’s checked exceptions add quite a bit of clutter to an otherwise very clean and simple class. The AccessException is needed because the normal Map interface does not allow for checked exceptions to be thrown. The get() method on a FutureTask can throw two different types of exceptions. They need to be handled differently, so they are both caught and properly wrapped in an AccessException (a subclass of RuntimeException) and re-thrown.

Using this technique I was able to retrieve the external data if and only if it was going to be displayed to the user. And I was able to do it without breaking the separation between the view and the business logic.

Filed in: Languages, Tips

Environment Configurable

During our last big rails project, Bloomfire, we found ourselves integrating with all kinds of external services. Because of this we had a diverse set of environment dependent configuration variables. A consistent pattern started to arise where we would extract our configuration variables into a YAML file and then wrap the configuration using a small class wrapper. This eventually gave rise to Environment Configurable, a library that makes environment dependent configuration easy in rails.

Read the rest of this entry
Filed in: Technologies, Tools

Engineer Thinking, Making People Feel Like Idiots & The Failure of Empathy

Matt Legend Gemmell on Engineer Thinking:

All too often, when faced with a decision about how to implement certain functionality, engineers take the extreme position that:

  1. A feature must be exactly what 100% of users want.
  2. If the above isn’t true (and it almost never is), the feature must be configurable.

This binary approach is gravely wrong, and unjustly offloads decision-making onto the user of the software. We’ve all seen where this approach ends up: multi-row sets of tabs, scrolling panes of checkboxes, nested radio-buttons and a general overload of configuration.


Matt Linderman (37signals) saying Computers shouldn’t make people feel like idiots:

For those of us surrounded by the minutiae of computers all day, it’s easy to forget there’s a world of people out there who just don’t get it. And it’s not their fault. It’s ours.


Mike Monteiro (Mule Design Studio) on The Failure of Empathy:

As an industry, we need to understand that not wanting root access doesn’t make you stupid. It simply means you do not want root access. Failing to comprehend this is not only a failure of empathy, but a failure of service.


(via ignore the code)

Don't forget the basics: opening keynote of the Michigan Agile and Beyond conference

The Michigan Agile and Beyond Conference brought 450 people together this weekend in Dearborn, Michigan to teach, learn and debate the broad subject of agile software development. The “beyond” part of the theme bothered me a little, for the same reason that it irritates me when I hear companies explaining that they do “practical agile”. Both statements miss the point that agile is about nothing more than delivering valuable software frequently and regularly. What can be more practical than that? Why do we need to move “beyond” that?

Ron Jeffries & Chet Hendrickson offered the best advice I heard all day in their opening keynote. Namely, to go beyond, you must travel through. Their point was that if you’re not in the “agile space” now, successfully using the core practices, then get there before you start tinkering or adapting. It reminded me of the debate in the early 2000s of whether you had to use all (then) 13 practices of XP to claim you were doing XP. Someone (might even have been Ron) responded that you’re doing XP when you’ve mastered all 13 practices and figured out which ones you need and how to use them on your project.

Chet cut straight to the chase when he said it matters what you do, because “agile isn’t any damn thing.” Ron followed that by quoting Emerson Codd: “The truth isn’t like a bunch of puppies running around where you chose your favorite.” Their talk was as casual, funny, and inspiring as always. They shared some of the simple truths about software development:

  • Software development is all about people (Funny Ron quote: “When I got into computing, it was not with the intention of hanging out with other people.”) Tools can’t replace or compensate for people.
  • Requirements need to get into the heads of the people building the software. Documents are a poor way of doing this.
  • If you can’t ship working software every month, try two weeks. If you can’t do it in two weeks, try one week. You learn to build software by building and shipping working software.
  • Waterfall doesn’t give you accurate information until it’s too late.
  • If your software isn’t bug free, you can’t trust your velocity.
  • If you’re manually testing everything your need for testers grows at least linearly with the number of iterations. You’ve got to automate some of those tests.
  • If you can’t refactor, you can’t do evolutionary design.

They summarized by identifying the three non-negotiable core practices to being agile:

  • Ship software regularly
  • Test as you go
  • Refactor to evolve the design

While their message, at least to me, was fundamentally one of “don’t forget the basics”, Chet and Ron also addressed the “beyond” part of the conference. They cited relationship to management, human resources, and dealing with projects that don’t fit in a single room as challenges that are still beyond the scope of accepted agile thinking. Ron called out Pillar Technology and Atomic Object as examples of companies pushing the boundaries of agile. They also reminded us that we have an obligation to share our experiments, both our failures and successes, to grow the body of agile knowledge. Chet added that these experiments push agile into new territory, but are still grounded in the simple statements of the Agile Manifesto.

Responsible Estimation Tool

Many times during the sales process we are asked to give a cost estimation based on our early understanding of an application’s core features. In order to responsibly and efficiently estimate, we conduct a 50/90 range analysis. We use this technique because we want to establish a responsible middle ground between our optimistic and pessimistic estimates. Our estimate is appropriately buffered for the risk we see in the defined tasks.

This spreadsheet is the tool that we use to conduct our analysis. Tasks can be estimated in any time duration that you choose (i.e. hours, days, weeks). At the start of a large project we generally estimate tasks in days or weeks.