Archive for the 'Design' Category

Functional Invasion

Sunday, December 2nd, 2007

If you write software, or even pretend to write software, you have probably heard of functional programming. You may even know what functional programming is. If you do, then bear with me for a moment while I summarize things for those that don’t.

Languages tend to fall into one of three different paradigms. Procedural (c, perl, php, javascript), Object Oriented (c++, java, ruby), and Functional (haskell, ml, erlang). Now, this isn’t to say that a language only follows one specific paradigm. One can take java or c++ and implement code in all three paradigms. Same with almost any other language, but there tends to be a general layout to a language that makes it more suitable to one paradigm or another. So what are these paradigms?

Procedural – This is where you are effectively writing, step by step, what you want your application to do. You rarely have any abstraction, and your code tends to be fairly straightforward. Since everything is explicit, it can be optimized, and run very tightly. However, the responsibility is on you as the developer to make it so. You could just as easily (perhaps more easily) make your code brittle, bug ridden, and slow.

Object Oriented – This is where you have your code logically broken up into areas of responsibility. An object is a component of data, accompanied by the various bits of functionality that can act upon it. This paradigm tends to result in isolated functionality that is reused as the data is reused. This will typically lead to more maintainable projects with flexible abstractions allowing for minimal code doing maximal work. On the other hand, abstraction can be computationally expensive, and result in “magical functionality” that is very difficult to trace through. Again, it requires a responsible developer.

Functional – This is where you are concentrating on functions (in a mathematical sense) or algorithms. You build your program as a series of “data pipelines” that will take a given input and provide a desired output. These functions are written such that if the inputs remain the same, any number of calls to the function will always result in the same output. This paradigm, when properly followed, can allow for a compiler to make certain assumptions about the program being compiled, and can lead to some very radical optimizations. It also tends to discourage some of the more evil behaviors of programmers (such as modifying global data, having one function do many unrelated things, etc). The cost is that it requires a very different mindset when writing your programs. It can also be very tedious to write functionally styled code in a “non-functional” language.

The interesting thing about Procedural vs. Object Oriented paradigms is that they are still related. Inside the functions of an object, procedural code is used to do work. All you are really doing is introducing some forms of organization to the code layout. When you look at Procedural vs. Functional paradigms, you will find they are fundamentally different. Procedural code will lay out, step by step, what data you are using, and what you want to do to that data. In a functional language, this is not really the case. Instead, you will lay out what you want to do, and build compositions of functions to tie into each other. Then you will add inputs to the head of the function. Another way of thinking of this would be like using the pipe (‘|’) in the *nix Bash shell. Given data from some program, you want to transform it using other programs (like grep, awk, or sed) and then capture the results. Each of those utilities are like a function. Given the same inputs, they will always generate the same output. Piping the outputs of one function to the inputs of another is more or less the premise of functional programming.

So, if functional programming is so different than what everyone is used to, why does it matter? Well, it turns out that functions written in this way are typically easier to test. Since each function has no side effects, unit testing can be used effectively. Once a set of functions are well tested, then large majority of errors will be in the composition of functions, and these are easy for a compiler to catch in any relatively type safe language. Reuse can be maximized, resulting in a smaller, better tested, more maintainable code base. If you are using a functional language, then the compiler can do some very interesting things for optimization, and parallelization. Even if you are not using a functional language, many benefits can be had. The STL uses functional programming techniques extensively to allow c++ developers to enjoy some of the benefits. Still, to maximize the enjoyment of functional programming, one must use a functional language. Only then will the compiler leverage the assumptions that can be made about your code. It can, for example see that you always call a certain function with the same parameters every time, and replace that function call with the result directly. It can use cues that you provide to detect that a certain function can be run in parallel and automatically tie a thread-pool to the function.

So if you have looked at any of the functional languages and scoffed at the learning curve. Perhaps consider taking a second look. In fact, sometimes you will find the learning curve to be pretty reasonable. I recently ran across the book Programming Erlang: Software for a Concurrent Worldamazon.com. Once again the Pragmatic Programmers have worked to produce a book that makes learning fun and interesting. The learning curve is manageable, and the examples in the book are more than just trivial exercises. Erlang is an interesting language that makes working in a concurrent environment trivially simple, and on todays multi-core processors, that is becoming important. It can also pave the way to understanding more involved languages like Haskell. It can perhaps even allow you to understand the techniques of functional programming better so you can employ them in your non-functional language more effectively. After all, isn’t being more effective what this is all about?

-Joe

Scalable architectures and Ruby on Rails

Wednesday, July 25th, 2007

Ruby on Rails has been around long enough to get past most of the hype. It is a robust web app framework with a lot to offer. One big drawback seems to be the general lack of performance that many rails apps have. Well, it turns out that there are several things that can be done for that.

First off, go read Charlie Savage’s article on tips to tune your rails app. Charlie discusses profiling your ruby app, and then tracking down the problem areas that are hurting performance. He was able to get his response times down from 7.8 seconds to 0.92 seconds! Wow.

Ok, so what about the case where you’ve tweaked your app, and wrung every last bit of performance you can out of it? But it still isn’t enough. You still cringe everytime your site makes the digg front page. Well, if you have your own servers, you can ensure that you have a scalable architecture. Theo Schlossnagle has a great book on the subject, Scalable Internet Architectures. This book discusses the various issues that a system designer faces when organizing the hardware that a web app will run on. Things like having optimized “static content servers” to stream image assets and css, along with more advanced techniques like setting up a caching proxy for each of your application servers since their CPU time is precious, and should not be wasted shoving content down a slow bandwidth pipe. He also goes into basic database design and advanced logging techniques.

Almost all of the techniques that Schlossnagle talks about are for larger installations, however he also spends time talking about scalability. Particularly the need to be able to scale down as well as up. For example, let’s say you are a fresh new startup, flush with VC cash. You go buy twenty servers, and fill ’em all up with world changing web 2.0 goodness. Six months later realize that the money will run out four weeks before the next version is ready to launch! wouldn’t it be great to be able to consolidate everything onto one or two servers, sell the others, and keep yourself in business a bit longer, until you can get version two out the door? If you designed your software and hardware with both kinds of scalability in mind, you might just stick around long enough to see version three.

So how does all this fit into Railspace? Well, first off, design your application so different bits can be spun out onto separate application servers. Perhaps even allow for logical breaks in the database. Tune your app to get as much bang for each buck as possible. Look at bottlenecks, both at a software, and hardware level. Know the difference between performance and scalability. Know that tuning your software helps with performance, but that scalability is what handles the digg effect. With this knowledge in place, you can be better equipped to handle all the traffic your heart can desire. Ruby on Rails is perfectly capable of handling anything that comes its way, but it does require planning, and work. Building a scalable architecture for Rails to sit on allows all the benefits to shine.

-Joe

Pragmatic approach to programming

Monday, February 26th, 2007

I recently had to move my rather extensive library of tech books. In doing so, I marveled at how clumped my library was. Now, in ten+ years of development experience, I’ve worked on a large number of projects. Lots of java, lots of perl, lots of c++, some php, and currently python and ruby. My library does not reflect what I’ve worked on, nor does it really reflect those topics that I worked on the longest. Why do I have four books on ruby on rails, yet only one on python? I use python in my day job, and rails is for my personal projects. There’s lots of documentation out there explaining how to use rails… why four books then? One answer is because I discovered the Pragmatic Programmers. The books from this publisher have been some of the best and most rewarding technical books I have read. The writing style is light, but not overly so. The techniques are described in a logical order. Time isn’t wasted on explaining things over and over. Non-trivial examples are used to boost the subject matter, and display the power of what is being taught.

All in all, the Pragmatic Programmers live up to their name. They teach pragmatic techniques to software development. They teach you what you need to know to get a solid foundation, and develop good habits. From there, you learn enough to get the job done. By the end of the books you may not be an expert, but you have a solid understanding of what is going on, and how to apply it to your projects. If you haven’t discovered these fantastic books, I strongly suggest you put them on your list.

-Joe

Users don’t want to think, and they shouldn’t have to.

Wednesday, February 14th, 2007

Steve Klug, author of Don’t Make Me Thinkamazon.com, has some sage advice for those of us who create user interfaces. When putting ourselves in the users perspective, realize that no matter how nicely we craft something, the user isn’t going to look at our presentation. He will glance at it for cues directing him to where he wants to go. She’ll scan it for relevant information. But no matter how flashy the page is, no matter how much time and effort went into positioning everything, no matter how long we took writing out the content, the user won’t look at it. Don’t get me wrong… content and presentation are extremely important, and should be given plenty of attention. But when the user hits your webpage – or application for that matter – they have a specific task in mind. They probably have a few keywords in mind that they are scanning your page for. As soon as they find a word that could be interpreted as relevant, they’ll click it, or the closest seemingly relevant link. In order to demonstrate this, go over to a casual computer users house, and watch them browse the web, or use email. They will probably drive you crazy… not use any keyboard accelerators, type instead of copy & pasting, click through the menu instead of clicking the toolbar button, etc.

What does this mean to us, the software developers? Should we drop all of the nicely crafted stuff that we work so hard on? Should we limit our pages to one or two links, and a picture? Should we hang it all and go bag groceries? I’d hazard a guess that the answer lies somewhere between the groceries, and no. Specifically I think that the hand crafting is important on pages that are end points. These are the articles, blog posts, help screens, etc. Navigation pages, or task screens should probably have a lot less content on them than they do now. The content is being wasted, in time, pixels, downloads, and everything else.

Don’t Make Me Thinkamazon.com discusses several tips and tricks for handling the dillema, and is worth a read… but the easy and obvious tips are:

  1. Limit the amount of information the user needs to scan
  2. On navigation pages, keep link descriptions to one or two clear, non-gimmicky words.
  3. On content pages, give the user a hand… break the content up, leave plenty of whitespace, and have bold keywords sprinkled throughout the content to help identify potentially relevant areas of information. I.e. don’t force the user to read the entire page – or really, any of it.
  4. Adapt, adapt, adapt. Go watch someone use your app, or website. Don’t have them test it, but have them use it. You may be surprised at how differently they react to the interface. Remember, they are heading over there for a reason, you probably don’t know that reason, but as you learn it, alter your site to accommodate it.
  5. Realize that the user is going to click on the wrong thing, give them a clear way to get back, using the back button, and otherwise.
  6. Read Don’t Make Me Thinkamazon.com, to learn how to get into the users head.

Ultimately we, as developers, need to create something of value and use. Unless we are the ones using it, we have to accommodate the quirks of human nature. Our users time is precious to them, and they will only give you what they feel they have to spare. In order to maximize the value you provide, that time has to be well spent. An intuitive interface is the best way to ensure that. The only way to make an intuitive interface is to know what intuition drives people to do. Given some small changes in how we design applications and websites, we can make life easier for our users, and that can make life easier for us.