Sanity Checks: Assumptions and Expectations

Assertions and unit tests are all well and good, but they’re too narrow-minded in my eyes. Unit tests are great for, well, testing small units of code to ensure they meet the basic requirements of a software contract – maybe a couple of typical cases, a couple of edge cases, and then additional cases as bugs arise and new test cases are created for them. No matter how many cases you create, however, you’ll never have a test case for every possible scenario.

Assertions are excellent for testing in-situ; you can ensure that unacceptable values aren’t given to or by a piece of code, even in production (though there is a performance penalty to enabling assertions in production, of course.) I think assertions are excellent, but not specific enough: any assertion that fails is automatically a fatal error, which is great, unless it’s not really a fatal error.

That’s where the concept of assumptions and expectations come in. What assertions and unit tests really do is test assumptions and expectations. A unit test says “does this code behave correctly when given this data, all assumptions considered?” An assertion says “this code assumes this thing, and will not behave correctly if it gets another, so throw an error.”

When documenting an API, it’s important to document assumptions and expectations, so users of the API know how to work with your code. Before I go any further, let me define what I mean by these very similar terms: to me, code that assumes something operates as if its assumptions are correct, and will likely fail if its assumptions turn out to be incorrect. Code that expects something operates as if its expectations are met, but will likely still operate correctly even if they aren’t. It’s not guaranteed to work, or guaranteed to fail; it’s likely to work, but someone should probably know about it and look into it.

Therein lies the rub: these are basically two types of assertions, one fatal, one not. What we need is an assertion framework that allows for warning-level assertion failures. What’s more, we need an assertion framework that is performant enough to be regularly enabled in production.

So, any code that’s happily humming along in production, that says:

Assume.that(percentage).isBetween(0,100);

will fail immediately if percentage is outside those bounds. It’s assuming that percentage is between zero or one hundred, and if it assumes wrong, it will likely fail. Since it’s always better to fail fast, any case where percentage is outside that range should trigger a fatal error – preferably even if it’s running in production.

On the other hand, code that says:

Expect.that(numRows).isLessThan(1000);

will trigger a warning if numRows is over a thousand. It expects numRows to be under a thousand; if it isn’t, it can still complete correctly, but it may take longer than normal, or use more memory than normal, or it may simply be that if it got more rows than that, something may be amiss with the query that got the rows or the dataset the rows came from originally. It’s not a critical failure, but it’s cause for investigation.

Any assumption or expectation that fails should of course be automatically and immediately reported to the development team for investigation. Naturally a failed assumption, being fatal, should take priority over a failed expectation, which is recoverable.

This not only provides greater flexibility than a simple assertion framework, it also provides more explicit self-documenting code.

Be Maxwell’s Demon

Source code tends to follow the second law of thermodynamics, with some small differences. In software, as in thermodynamics, systems tend toward entropy: as you continue to develop an application, the source will increase in complexity. In software, as well as in thermodynamics, connected systems tend toward equilibrium: in development, this is known as the “broken windows” theory, and is generally considered to mean that bad code begets bad code. People often discount the fact that good code also begets good code, but this effect is often hidden by the fact that the overall system, as mentioned earlier, tends toward entropy. That means that the effect of broken windows is magnified, and the effect of good examples is diminished.

In thermodynamics, Maxwell’s Demon thought experiment is, in reality, impossible – it is purely a thought experiment. However, in software development, we’re in luck: any developer can play the demon, and should, at every available opportunity.

Maxwell’s demon stands between two connected systems, defeating the second law of thermodynamics by selectively allowing less-energetic particles through only in one direction, and more-energetic particles through only in the other direction, causing the two systems to tend toward opposite ends of the spectrum, rather than naturally tending toward entropy.

By doing peer reviews, you’re doing exactly that; you’re reducing the natural entropy in the system and preventing it from reaching its natural equilibrium by only letting the good code through, and keeping the bad code out. Over time, rather than tending toward a system where all code is average, you tend toward a system where all code is at the lowest end of the entropic spectrum.

Refactoring serves a similar, but more active role; rather than simply “only letting the good code through”, you’re actively seeking out the worse code and bringing it to a level that makes it acceptable to the demon. In effect, you’re reducing the overall entropy of the system.

If you combine these two effects, you can achieve clean, efficient, effective source. If your review process only allows code through that is as good or better than the average, and your refactoring process is constantly improving the average, then your final code will, over time, tend toward excellence.

Without a demon, any project will be on a continuous slide toward greater and greater entropy. If you’re on a development project, and it doesn’t have a demon, it needs one. Why not you?

Real Sprints

Agile methodologies talk about “sprints” – workloads organized into one to four week blocks. You schedule tasks for each sprint, you endeavour to complete all of it by the end of the sprint, then you look back and see how close your expectations (schedule) were to reality (what actually got done).

Wait, wait, back up. When I think of a sprint, I think short and fast. That’s what sprinting means. You can’t sprint for a month straight; you’ll die. That’s a marathon, not a sprint.

There are numerous coding competitions out there. Generally, you get around 48 hours, give or take, to build an entire, working, functional game or application. Think about that. You get two days to build a complete piece of software from scratch. Now that’s what I call sprinting.

Of course, a 48 hour push is a lot to ask for on a regular basis; sure, your application isn’t in a competition, this is the real world, and you need to get real work done on an ongoing basis. You can’t expect your developers to camp out in sleeping bags under their desks. But that doesn’t mean turning a sprint into a marathon.

The key is instilling urgency, while moderating burnout. This is entirely achievable, and can even make development more fun and engaging for the whole team.Since the term sprint has already been thoroughly corrupted, I’ll use the term “dash”. Consider this weekly schedule:

  • Monday: Demo last week’s accomplishments for stakeholders, and plan this week’s dash. This is a good week to schedule any unavoidable meetings.
  • Tuesday and Wednesday: your 48 hours to get it done and working. These are crunch days, and they will probably be pretty exhausting. These don’t need to be 18-hour days, but 10 hours wouldn’t be unreasonable. Let people get in the zone and stay there as long as they can.
  • Thursday: Refactoring and peer reviews. After a run, athletes don’t just take a seat and rest; they slow to a jog, then a walk. They stretch. The cool off slowly. Developers, as mental athletes, should do the same.
  • Friday: Testing. QA goes through the application with a fine-toothed comb. The developers are browsing the web, playing games, reading books, propping their feet up, and generally being lazy bums, with one exception: they’re available at a moment’s notice if a QA has any questions or finds any issues. Friday is a good day for your development book club to meet.
  • By the end of the week, your application should be ready again for Monday’s demo, and by Tuesday, everyone should be well-rested and ready for the next dash.
Ouch. That’s a tough sell. The developers are only going to spend two days a week implementing features? And one basically slacking off? Balderdash! Poppycock!

Think about it, though. Developers aren’t factory workers; they can’t churn out X lines of code per hour, 40 hours per week. That’s not how it works. A really talented developer might achieve 5 or 6 truly productive hours per day, but at that rate, they’ll rapidly burn out. 4 hours a day might be sustainable for longer. Now, mind you, in those four hours a day, they’ll get more done, better, with fewer defects, than an army of incompetent developers could do in a whole week. But the point stands: you can’t run your brain at maximum capacity eight hours straight, five days a week. You just can’t – not for long, anyway.

The solution is to plan to push yourself, and to plan to relax, and to keep the cycle going to maximize the effectiveness of those productive hours. It’s also crucial not to discount refactoring as not being productive; it sets up the following weeks’ work, and reduces the effort required to get the rest of the development done for the rest of the life of the application. It’s a critical investment in the future.

Spending a third of your development time on refactoring may seem excessive, and if it were that simple, I’d agree. But if you really push yourself for two days, you can get a lot done – and write a lot of code to be reviewed and refactored. In one day of refactoring, you can learn a lot, get important work done, and still start to cool off from the big dash.

That lazy Friday really lets you relax, improve your craft, and get your product ready for next week, when you get to do it all over again.

The Development Stream

I was reading today about GitHub’s use of chat bots to handle releases and continuous integration, and I think this is absolutely brilliant. In fact, it occurs to me that using a chat bot, or a set of chat bots, can provide an extremely effective workflow for any continuous-deployment project. Of course, it doesn’t necessarily have to be a chat room with chat bots; it can be any sort of stream that can be updated in real-time – it could be a Twitter feed, or a web page, or anything. The sort of setup I envision would work something like this:

Everyone on the engineering team – developers, testers, managers, the whole lot – stay signed in to the stream as long as they’re “on duty”. Every time code is committed to a global branch – that is, a general-use preproduction or production branch – it shows up in the stream. Then the automated integration tests run, and the results are output to the stream. The commit is deployed to the appropriate environment, and the deployment status is output to the stream. Any issues that occur after deployment are output to the stream as well, for immediate investigation; this includes logged errors, crashes, alerts, assertion failures, and so on. Any time a QA opens a defect against a branch, the ticket summary is output to the stream. The stream history (if it’s not already compiled from some set of persistent-storage sources) should be logged and archived for a period of time, maybe 7 to 30 days.

It’s very important that the stream be as sparse as possible: no full stack traces with error messages, no full commit messages, just enough information to keep developers informed of what they will need to look into further elsewhere. This sort of live, real-time information stream is crucial in the success of any continuous-deployment environment, in order to keep the whole team abreast of any issues that might be introduced into production, along with when and how they were introduced.

Now, what I’ve described is a read-only stream: you can’t do anything with it. GitHub’s system of using an IRC bot allows them to issue commands to the bot to trigger deployments and the like. That could be part of the stream, or it could be part of another tool; as long as the deployment, and its results, are output to the shared stream for all to see. This is part of having the operational awareness necessary to quickly identify and fix issues, and to maintain maximum uptime.

There are a lot of possible solutions for this sort of thing; Campfire looks particularly promising because of its integration with other tools for aggregating instrumentation data. If you have experience with this sort of setup, please post in the comments, I’d love to hear about it!

Truly Agile Software Development

Truly agile software development has to, by nature, allow for experimentation. In order to quickly assess the best option among a number of choices, the most effective method is empirical evidence: build a proof of concept for each option and use the experience of creating the proof, as well as the results, to determine which option is the best for the given situation.

While unit tests are valuable for regression testing, a test harness that supports progression testing is at least as useful. Agile development methodologies tend to focus on the idea of iterating continuously toward a goal along a known path; but what happens when there’s a fork in the road? Is it up to the architect to choose a path? There’s no reason to do so when you can take both roads and decide afterward which you prefer.

Any large development project should always start with a proof of concept: a bare-bones, quick-and-dirty working implementation of the key functionality using the proposed backing technologies. It doesn’t need to be pretty, or scaleable, or extensible, or even maintainable. It just has to work.

Write it, demo it, document what you’ve learned, and then throw the code away. Then you can write the real thing.

It may seem like a waste of time and effort at first.  You’ll be tempted to over-engineer, you’ll be tempted to refactor, you’ll be tempted to keep some or all of the code. Resist the urge.

Why would you do such a thing? If you’re practicing agile development, you might think your regular development is fast enough that you don’t need a proof. But that’s not the point; the point is to learn as much as you can about what you’re proposing to do before you go all-in and build an architecture that doesn’t fit and that will be a pain to refactor later.

Even if it takes you longer to build the proof,it’s still worth it – for one thing, it probably took longer because of the learning curve and mistakes made along the way that can be avoided in the final version, and second because again, you’ve learned what you really need and how the architecture should work so that when you make the production version you can do it right the first time, with greater awareness of the situation.

This approach allows much greater confidence in the solutions chosen, requiring less abstraction to be built in to the application, which allows for leaner, cleaner code, and in less time. Add to that the value of building a framework that is flexible enough to allow for progression testing, and you’ve got the kind of flexibility that Agile is really all about.

Note: Yes, I understand that Scrum calls prototypes “spikes”. I think this is rather silly – there are already terms for prototypes, namely, “prototype” or “proof of concept”. I’m all for new terms for things that don’t have names, but giving new names to things that already have well-known names just seems unnecessary.

HTML5 Grid Layouts

I have to take issue with the swarm of “responsive grid layout” systems that have been cropping up lately. Yes, they’re great for wireframes and prototypes. No argument there. And yes, they take care of a lot of the legwork involved in producing a responsive layout. Great. But in the process, they throw semantic markup and separation of concerns out the window.

The idea of semantic markup is that your document structure, IDs, and classes should describe the content of the document. Separation of concerns, in HTML and CSS, means using classes and IDs to identify what something is (not how it should appear), and using CSS to identify content and determine how it should appear; this allows you to change content without having to change appearance, and vice versa: the concerns of document structure and appearance are kept separate.

That means, as far as I’m concerned, as soon as you put a ‘class=”two column”‘ into your HTML, you’ve lost the game. You’ve chained you structure to your presentation. Can you change your presentation without modifying the markup? Not any more. All we’ve achieved in this is bringing back the days of nested tables for layout, with a pretty CSS face on it. With one dose of “clever” we’ve traveled back in time 15 years. Only this time, there *are* other ways to do it. There’s no excuse. It’s just plain laziness.

Is building a truly semantic, responsive, attractive layout possible? Absolutely. Difficult? Yes. Is it worth the effort? In the long run, I think it is – except for those cases mentioned above, prototypes and wireframes, code that’s meant to be disposable. But any code that has to be maintained in the future will be hamstrung by these systems.

Web development has made tremendous strides over the last 10 years. It’s amazing how far we’ve come in terms of what can be done and how. Don’t take all those advances and use them to regress all the way back to clunky old table-based layouts. Try using them to do something new, and interesting instead. There’s no reason the idea of software craftsmanship should be missing from the web design world.

Assumptions

We all make assumptions. It’s the only way we can get anything done. If every time you found a bug you started at the iron – testing the CPU to make sure every operation returns an expected result – it’d take you months to troubleshoot the simplest issue. So we make assumptions to save us time, when we know that the likelihood of something being the cause of a problem is far less than the time it would take to verify it.

We also make assumptions out of sheer bloody-mindedness. You can spot these assumptions by phrases like “that couldn’t possibly be it” or “it’s never been a problem before” or “I wrote that code, I know it works”. These are the kinds of assumptions that can get us into trouble, and they’re the exact reason why it’s important to have developers from different backgrounds, with different perspectives, who make different assumptions.

Since we all make assumptions, the best way to challenge those assumptions is to have someone who makes different assumptions look at the issue. They’ll bring their perspective and experience to the matter, challenge your assumptions where they don’t make sense, and make you prove those assumptions to be accurate or not. This stands as a strong incentive to hire a team with diverse backgrounds and areas of expertise. They bring not just talent to your team, but a different perspective.

It’s also a good reason to invest the time in learning different technologies, languages, and development philosophies. Getting outside of your comfort zone can open your eyes to things you might not otherwise have considered, and help you to gain new perspective on your work – helping you to challenge your own assumptions.

The Semantic Web: Practical Semantic Markup

There’s been a lot of talk, for many years about the coming of “the semantic web” – all markup will include semantics that automated systems can read and understand for as-yet-undefined purposes, though prognosticators will speculate on all manner of technical advances that could come from semantics. What about the here and now, though? Right now, today, semantic markup can help you. Semantic markup does one very useful thing: it makes building and styling web pages a heck of a lot easier, if done right.

So, how do you do it right, and reap those benefits? Starting from a blank slate, start filling in your content. Don’t even think about layout or styling – worry only about organizing the content in a clean and sensible way. Your headings should be in h* tags, with lower-level headings using lower-level heading tags. Your content should be in p tags, with no br’s. Enclose the main content in an article tag, enclose sidebars in aside tags, and so on. Enclose your header, navigation, and footer in the appropriate tags.

Load the page. It’ll look like crap. All you’re looking for right now is a sensible document flow. The page should read cleanly from top to bottom with no styling. If not, reorganize your markup until it does.

Now that you have a well-organized, semantically-tagged document, start identifying the parts of the page that are specific to your document. Add id’s to unique elements on the page. Add classes to just about every container on the page to identify its purpose – even if it already has an ID (more on this later.) Name your IDs and classes based on what they identify, not how it’s supposed to look. For example, don’t use “small” or “bold” as class names; if you want your copyright footer to be small, name it “copyright” and worry about the appearance later. If you want text to be bold, use the strong tag if it’s appropriate (e.g. a bold segment of body text), or use a class name that says what the thing is that you want to be bold (e.g. class=”announcement” or class=”specialOffer”.)

Try to use a consistent naming scheme. I use CamelCase for all classes and IDs, with IDs starting with a capital letter and classes starting with a lowercase letter. This is just what makes sense to me personally; it doesn’t matter what your standard is, as long as you find it intuitive and you stick to it.

After all this, your page looks exactly like it did before. Excellent. Now that you’ve got semantic tags identified with semantic classes and IDs, you’re ready to start styling your document. It doesn’t really matter what you start with, but I tend to start with typographic styling. The reason behind this is that typographic styling will change the font metrics, and many parts of a responsive design will be relative to your font metrics, so starting with typography gives you a solid foundation on which to build your layout.

For typography, start at the bottom and work your way up: start by applying your default font style to body, and then use that as a base to style any other elements you need to style – headers, paragraphs, strong/emphasis, a, blockquote, and so on. Start with the most generic styles, where you can apply the style to the tag globally, with no class name or ID specified. Work your way in deeper, first with those cases where you can still identify with only tag names, but based on ancestry; for example, you may want list elements inside nav to look one way, list elements inside article to look another way, and list elements inside an aside to have a third, different styling. This is still global based on document structure, not based on classes or IDs.

View your document again; the layout still sucks, but the document should be readable, and your typography should be pretty close to what you want in the finished product. Identify the places where certain uses of an element – which should already be identified by semantic classes and IDs – should be styled a certain way, and start defining those styles in CSS. Avoid using IDs in your CSS; identifying elements by class rather than by ID lends more flexibility to your code.

Once you have your typography more or less like you want it (at least the font families and sizes), start thinking about layout. Your document is already well-organized, but the layout is very 1995. Now is the time to fix that. Presumably you already have a final design in mind, but if not, take the time to quickly sketch out a rough layout for the page, where you want everything to be, and how you want the document to flow in its final incarnation.

You should conveniently already have all of the blocks that you want to lay out in appropriate tags with appropriate classes, so it should be easy to identify them in CSS. If not, review your markup and clean it up. Again, start with the big chunks and work your way deeper from there. Adjust the layout of the main page elements: header, footer, body, columns/grid. View your page, and start tweaking the layout of the elements within those main containers; adjust the layout of inline elements like sidebars and images, adjust the layout of your navigation items, and so on.

Now that your typography is set, and your layout is looking good, you can start on the fancy stuff, like borders, backgrounds, rounded corners, drop shadows, spriting, and so on and so forth: all of the interface fluff that takes a site from usable to beautiful. We’re on the home stretch now!

If you’re building a modern website, you’re probably going to be implementing some fancy UI behaviors using something like jQuery. Depending on the complexity of what you want to achieve, this may be quick and easy, or it may be weeks worth of iteration. Regardless, you’ve already given yourself a significant advantage: all of that semantic markup, the careful selection and classing of elements, gives you a huge boost using a tool like jQuery, for a couple of reasons. First, it makes it easier to identify the elements you’re trying to control in your scripts. Second, it makes your code more readable automatically, because you can quickly tell from the way you’ve identified an element what you’re trying to do. “$(‘p.boldRed’)” doesn’t tell you much, but “$(‘p.callToAction’)” tells anyone reading the code that you’re manipulating the call to action paragraph on the page. They know what to look for in the HTML, they know what to look for when they’re looking at the page in the browser, it’s all immediately clear from the identifier used.

This is the basic process for building a semantic web page. This doesn’t cover the finer points of responsive design, which is a whole can of worms that I look forward to opening in a future post.

A Programmer’s Comparison of Java and C#/.NET

I’ve been developing in Java for almost ten years, and in C# for only a few months, so this comparison may not be as thorough as it could be. If I’ve missed something please feel free to comment.

Java is far more portable than C# for one. I’ve built applications on Windows, and ported them to Linux and Mac with minimal effort. With Android running on a Java-based platform, porting to Android is made far easier. There’s no fussing with Mono and the like, no making sure you don’t use any API functions that are only available in .NET.

Java also has a wide array of available IDEs with excellent features, and a huge, active community. There are libraries available for just about any technology you can think of, usually more than one, such that one of the options will likely fit your specific situation.

Java’s runtime generics seem to be easier to learn and work with than C#’s compile-time generics; however, compile-time generics are likely better performing. Java’s overridable-by-default scheme also makes development a lot easier in many cases. While I do understand the idea behind C#’s final-by-default scheme, I prefer a language that leaves those kinds of choices up to the developer rather than enforcing good development practices through language features.

The JVM is also now expanding to support other scripting languages, including PHP, Python, Ruby, Scala, and others.

C# has some excellent language features that I would like to see in Java, however. Extension methods are extremely useful for adding functionality to classes without having to subclass, particularly useful in adding functionality to library classes. C#’s delegate features are really excellent, and beat any workaround Java has for its lack of closures for callbacks and event handlers. The upcoming Java closure functionality looks like it will still pale in comparison to C#’s delegates.

LINQ is something I would love to see come to Java; the ability to query collections like databases is extraordinarily useful and eliminates a lot of tedious code iterating over collections. I’ve yet to use it for querying against a database, but it seems more than adequate for that purpose and likely much friendlier than JDBC. And while porting is more complicated, Mono is a very strong platform, and there’s even a Mono module for hosting web applications through Apache.

Speaking of web applications, I have no experience so far with building web applications in C# .NET, but I have done some research. Based on that research, I have to say I significantly prefer JSP/JSTL/EL over ASP.NET. I prefer the syntax, the workflow, and JSP’s tag library system over ASP.NET, which reminds me a little too much of PHP or old-school JSP (pre-JSTL/EL) for my tastes.

All in all, I can’t say one is superior to the other; like any development decision, it comes down to which option is best suited to the situation and the developer. If you’ve had the opportunity to make that choice, please leave a note in the comments and let me know what you chose and why, I’d be happy to hear it!

Convenience Languages

I’ve come to see the uncertainty of untyped and interpreted languages as something of a curse. In a strongly typed, compiled language, you know ahead of time that the code is at least trying to do what you want it to; you know you didn’t typo any variable, function, method, or class names. You know you didn’t misuse or misunderstand a function, passing one type when another is required. Sanitizing inputs and returns is a matter of checking bounds, not types. Type-safe comparison is a non-issue.

After working with PHP and JavaScript extensively, as well as dabbling in Perl, Python, and Ruby, I miss the basic assurance you get from a language like C/C++, C#, or Java that if it compiles, nothing is completely wrong. Even in HTML, you can validate the markup. But in PHP or JavaScript, you probably don’t know about even a major, simple error until run-time testing (unit or functional).

To me, that’s a nightmare. I miss knowing. I miss that little bit of certainty and stability. With an untyped interpreted language, you may never be 100% certain that you’ve not made a silly but fatal mistake somewhere that your tests just didn’t happen to catch.

These are languages of convenience: easy to learn, quick to implement small tasks, ubiquitous. But they just aren’t professional-grade equipment.

Developing software is both an art and a science. I make an effort every day not to just be a coder, but to be a code poet. That’s hard to do on the unsure footing of a dynamic language. I won’t argue that these languages let you do some neat tricks; on the other hand, I also won’t discuss the performance issues. My concern is purely quality.

Is it possible to write quality code in a dynamic language? Absolutely. Unfortunately, it’s harder, and far more rare – not just because it’s challenging. It’s mainly temptation. Why would the language offer global variables if you weren’t supposed to use them? Why have dynamic typing at all if you aren’t going to have variables and function return values that could have various types depending on the context? Even with the best intentions, you can commit these Crimea against code accidentally, without even knowing it until you finally track down that pesky bug 6 months down the road.

Using (and abusing) these sorts of language features makes for messy, sloppy, confusing, unreadable code that can be an extraordinary challenge to debug. Add to that the fact IDEs are severely handicapped with these languages, unable to offer much – if any – information on variables and functions, and unable to detect even the simplest of errors. That’s because variable types and associated errors only exist at runtime; and while an IDE can rapidly attempt to compile a source file and use that to detect errors, it can’t possibly execute every possible code path in order to determine what type(s) a variable might contain, or function might return.

I know most of this has been said before, and every new language will inspire a new holy war. I’m writing this more because all of the above leads me to wonder about the growing popularity of dynamic languages like Python, Ruby and JavaScript, and the continued popularity of PHP. Anyone care to shed some light on the subject in the comments?