usable in any place a human can be used

Showing posts with label philosophy. Show all posts
Showing posts with label philosophy. Show all posts

20100331

micro-optimization

[caption id="attachment_818" align="alignright" width="277" caption="Yea, I know it\'s on fire, but check it, I almost got Freebird down pat."]nero fiddling as rome burns[/caption]

As all good developers should know, one of the cardinal sins of software development is premature optimization. Premature optimization is bad for a whole host of reasons. But there is another set of optimizations that are in the same realm of bad, micro-optimizations.


I recall learning at some point that in C and C++ it is more efficient to use the pre-increment operator rather than the post-increment operator. Why is this the case, well it's because of the minor difference in behavior between the following two snippets.


[cpp]
int source = 10;
int destination = 0;

destination = ++source;

printf("Destination: %d", destination); //Prints "Destination: 11"
[/cpp]

Compare with this snippet


[cpp]
int source = 10;
int destination = 0;

destination = source++;

printf("Destination: %d", destination); //Prints "Destination: 10"
[/cpp]

WHA!? This is actually exactly what we would expect, pre-increment increments the value BEFORE assignment while post-increment increments the value AFTER assignment. What does this all mean, well basically that if you use post-increment you are executing more instructions, because the compiler has to keep the old value around to return to the assignment. That means that unless you are assigning the value and require the particular behavior that post-increment gives you, you can generate faster code by using the pre-increment operator (this may be handled by compiler optimizations these days).


All of the for-loops that you've written for(int i = 0; i < something; i++) are identical to and SLOWER than for(int i = 0; i < something; ++i). NOOOOO!!!!! Don't worry though, because this is a micro-optimization, its something to not care about, because in reality that one or two extra machine instructions isn't your bottleneck. Micro-optimizations are all those tricks that make code faster that in the vast majority of cases (although not all cases) don't really amount to any actual noticeable performance gain. A new processor can do something in the magnitude of 100,000 MIPS (Millions of Instructions Per Second). Every second it does 100,000,000,000 Instructions, that is 100 billion instructions. every. single. second. Changing from post- to pre- increment saves 1 or 2 instructions, so for every time that gets executed you have saved a 100th of a nanosecond.


Micro-optimizations are rarely worth the hassle, and, as with premature optimization, the solution is to benchmark and trace where your actual bottlenecks are and go about solving those. It doesn't matter if you're screaming through your increments saving a whole nanosecond if your crappy no index having table is taking a whole minute to read because you are doing a table-scan.


But wait, there's more. Micro-optimization, like everything in programming, can be directly applied to life in general. I work with a person who will spend 5 minutes discussing how to save 30 seconds, this is another incarnation of the micro-optimization. It's that shortcut you take home that actually takes longer, or some everyday voodoo that is draining your time without paying you back, or that client that provides you with 2% of your income but eats up 40% of your effort. Micro-optimizations abound all around us, in the little picture they seem ok, but in the big picture they are nonsense. Take a fresh look at the things and obligations around you and examine them for micro-optimizations, see if the things you do make sense in the big picture.

20100208

experience as a force multiplier

[caption id="attachment_701" align="alignleft" width="300" caption="Oh DS cat you lovable scamp, don\'t use up all my healing potions"]cat saying "I weveled up yur guys"[/caption]

Over the weekend I experienced two things, one rather normal for a "computer guy" the other less in my wheelhouse. The first thing was that my girlfriend wanted me to help her register a web domain for her dad for his birthday. I have done this twice before, once for the website you are currently viewing and one other time for http://prosper-lib.com (which just redirects back here for the time being). I remember the first time I registered a domain and carefully read all the forms, making measured decisions, and hesitantly moved from step to step unsure of myself. It took an hour or two and then a few more to set up the hosting and get ftp access, set up wordpress and get everything up and running. In total it took a few hours. I didn't have such a luxury of time, she needed me to get the site up and running, preferably with a custom "Coming Soon" page before lunch, it was 11:00 so I only had around an hour. I clicked over to the site, click click click type type type, and it was up and running. I looked over at the clock to see how badly I had overshot the envelope, 11:15... wait what?


The second experience I had this weekend was tearing up some carpet at my new place. I have undertaken tearing up 850 sq ft of carpet to install new wood flooring in my house. The first night I was able to remove carpet from two rooms in just under 4 hours. It was my first time, and I went slowly following the instructions and making sure that I did everything just right. The second night I worked with an experienced floor guy, we finished taking out the mats, staples, tack strips and carpets from 5 rooms. Over the weekend there was one room left to do, I was able to knock it out, carpet, mats, tack strips, the whole nine yards in about an hour.


After these two events it solidified a point in my head, experience is the best force multiplier. In the first case it was my own hard won experience (not that there is really anything that difficult about registering a website). After performing the task a few times I gained an experience that multiplied my force by an order of magnitude, what once took a few hours now only took a few minutes. In the second case I was able to leverage someone else's experience to augment my own. I learned countless tricks to getting the job done quickly and efficiently, but more importantly I gained a huge amount of confidence. Having someone that already had mastered the task work with me and confirm that I knew what I was doing gave me all the confidence in the world to go in on Saturday and tear up the last room lickety split.


There were two take away points from these experiences. When doing something new seek out someone more experienced than you to pair with, even if its just temporary. Fully participate with them, ask questions, and do not let them do everything for you. This is the best time to fail, you will get immediate feedback from the more experienced party about how you are failing, why you are failing, and how to avoid failure next time. This will give you a foothold to quickly learn by doing. The second point to take away is to experience lots of things, even if you suspect you will fail. Life is full of failures, but those failures impart experience which is the best force multiplier to get to success.


I would be unable to count the number of times I've ruled out some great idea because it took me down some unknown avenue, and I was afraid of failing. I have no experience charging people money, I don't know how to start up a business, I don't know how to make a website. These are all things I've said to myself at one point or another, the thing I realize now is that no one is born knowing how to do these things, there is only one way to get experience, try new things. Don't be afraid to fail, work hard to succeed, and know that no matter what happens the experience is valuable and worth it.

20100205

persist

[caption id="attachment_696" align="alignright" width="300" caption="measure twice, turn once"]semi truck[/caption]

I just witnessed an interesting even unfold in front of my current client's building. Today in beautiful Columbus, Ohio we are experiencing one hell of a winter storm, lots of fun. A semi truck decided that our parking lot was a great place to turn around in, he just apparently forgot to measure. CRASH BOOM and the lamppost has changed from its normal 90° to a more precarious 78ish°. After striking the lamppost and ramming a concrete barrier the semi was fairly well wedged, but the driver continued revving and the engine struggled and moaned. This persistence paid off and after about 10 minutes of maneuvering he was free. Now to call the insurance companies.


This got me thinking about the nature of difficult situations (self-imposed or otherwise). I also had a breakthrough largely due to persistence today, so happy coincidence. After months of working on documentation, being told that I would never be allowed to program the sacred system, the tides have turned (thanks to an excessively high quote) and the coach has called me up, and I'm ready to play under the bright lights.


I've just completed printing out 400 pages of documentation (my weekend is going to be so much fun!) and I will prepare myself for the difficult task ahead. My persistence has paid off, but the bigger realization is that persistence in general pays off.


To borrow one of my favorite quotes from Scrubs, "People are bastard-coated bastards with bastard filling." People don't ever want to think that you can succeed, and they are going to tell you no over and over again. There are two reasons for people to shut down your dreams:



  1. They have tried and failed, the task is impossible, your success would undermine them. If you succeed where they have failed then it isn't an impossible task, they just weren't good enough to do it.

  2. The have achieved it, but only by their virtue of their amazing talents and pure force of will. You don't have what it takes!


This is why it's vitally important to ask people for advice, sage wisdom, realistic assessments, but always keep in mind that very few people actually want you to succeed, especially if its in something they can't or already have. Don't worry though, these aren't bad people, it's human nature, and when you succeed you will act the same way. Success through hardship and against the odds plays a fun trick on the human brain, it makes you believe you pulled off the impossible. This feels amazing and so you will do anything in to hold on to it, and you don't want some dirty unwashed masses pulling off the same feat and diminishing it.


The big lesson here though is persistence, the most successful people in the world are those that were willing to have the door slammed in their faces 1000 times before making that sale. This is what you need to do, steel yourself for the struggle, prepare to be emotionally drained, and realize that this is what living is. Life is a stream of people telling you no, with the occasional yes. What separates the successful from the mediocre is that the successful are willing to wade through all the noes to get to the sweet succulent yes.


I've been paying my dues on this project for 3 months, and finally I get to go back to what I love the most, coding. There are a hundred stories of people trying and failing and trying and failing and trying and failing to finally succeed. It is definitely the path less taken, but it will make all the difference.

20100204

finite

[caption id="attachment_689" align="alignright" width="300" caption="all that eggnog caught up to him... the cocaine addiction didn\'t help either."]santa claus' tombstone with child crying[/caption]

Here's something unpleasant to think about, you are finite. Think about it deeply, drink it in, sit with it, feel like you've come to understand it, then wake up in a cold sweat thinking about it some more. There is only one certainty in this life, it will end. It gets worse, your time, your effort, your experiences, they are all finite. It's one of those big huge things in life that is too inconvenient to think about, so we don't. This is the core reason why most religions exist, coming to terms with one's own limited nature is terrifying. I've always been an Atheist, intimately connected to this notion that one day the unique thing that is me will be no more, just as for billions of years before I popped into existence I wasn't yet. It's something I tell myself I have come to terms with, but it is a daunting challenge and one that must be revisited from time to time.


As an aside: although I'm more than happy to discuss my personal spiritual beliefs I attempt to keep such charged matters off of this blog, if you would like to chat about it just post a short comment indicating so and I will contact you. I am an Atheist but I respect others' belief systems and don't intend to offend anyone.

I was driving home the other day and an interesting story came up on the radio. The main point being that as we age we sense that time is moving faster and faster. This is the spark that has led me to revisit one of the least comfortable aspects of our shared humanity. I've been pondering it for the last few days, thinking about my very real finiteness and trying to evaluate if I'm acting like a man with an expiration date. It was a mixed evaluation, in some ways I am, in others I am not, not a terrible fate by any stretch.


In my personal life I feel like I'm running full steam ahead. It might be the last week or so of 14 hour days working on getting my new house ready to move into. (After years of snacking and typing my body isn't as suited to the tasks of tearing up carpets and fixing walls as it once was). I've set real goals in terms of building skills, building relationships, and creating code I can be proud of, and I'm exceeding my expectations. I finally feel like my wheels have caught solid ground and aren't just spinning anymore.


There are still some areas I'm not happy with, I'm taking stock and taking action to address these. On the whole though, I feel like I'm spending my limited time here the right way for now. There are a thousand and one clichés about this subject: live each day like it could be your last, what would you do if you knew you would die tomorrow, etc. The problem is that they all take an outlook that is far too limited. No one could live each day like it could be your last, that's fucking stupid. If I knew I was going to die I'd spend all my money and live with complete abandon, you can't do that everyday of your life. It is the routine of life that makes this so difficult.


Life is finite but there is also a whole big pile of it. We like to think that we can wait and do something next week, month, year, etc. This is where all that "I always thought we'd have more time together" thing comes from. Want to open a bakery, learn to play the drums, fight a bear, there's no time like the present. If you are unhappy, you have to fix that. Other people that aren't you are probably going to tell you that you are foolish for trying to fight a bear, well those people can waste their lives while you're out punching Yogi in the mouth.


Don't let anything stand in your way, take it personally because nothing could be more personal. This is your precious finite life and its ticking away. If you are unhappy or feel like it's being wasted, do something about it. Nothing could be more important. It's not comfortable, and it can be frightening, but take stock of your life today and the whole time keep in mind, I only have so many days left, is this how I want to spend them.

20100203

bureaucracy

[caption id="attachment_677" align="alignright" width="300" caption="Wait until he meets the Undersecretary for Reduction Planning and Appropriation\'s new Assistant"]pentagon bureaucracy cartoon[/caption]

Bureaucracy, long the scourge of people who want to git-r-dun. There are some people out there that hate bureaucracy with a passion I can only really muster up for the pending zombie apocalypse. Make no mistake about it, I dislike bureaucracy, I think it is a wasteful but sometimes necessary evil. I've found myself ensnared in a bureaucratic nightmare for the last few months so I thought I would jot down some observations on bureaucracy.


Zombie Bureaucracy


(Wow lots of zombies in this post so far) A Zombie Bureaucracy is a bureaucracy that had some reason (however flimsy) for existing in the past but no longer needs to exist. Not unlike a zombie this bureaucracy manages to live long past its usefulness shambling into the future pointless and frustrating. This is caused by the ease that more bureaucracy can be created, at the stroke of an email someone can dream up a committee or process, but the difficulty in disbanding bureaucracy. It is disproportionately difficult to reduce bureaucracy because it looks like work, and people don't like having their work taken away, it reduces their sense of job security.



Dev: Why do I need 3 developers to sign off on every commit?
Mgr: Because 4 years ago two of the lead developers got into a pissing war over code formatting
Dev: Why didn't they just work it out?
Mgr: Because they had huge egos and management was too scared to fire either one
Dev: Is this still going on?
Mgr: No, Frank left 3.5 years ago because he didn't want to put up with Mark anymore
Dev: So why do I still need 3 developers to sign off on every commit?
Mgr: Because 4 years ago.... I guess it doesn't make much sense anymore.... That's the way it is!

Just like misery, bureaucracy love company


Bureaucracy is an attempt to control something, to take organic chaotic processes and make them orderly. The problem that often arises is that bureaucracy is its own organic chaotic system, that then requires more bureaucracy ad infinitum. If you've ever been in a meeting where all you decided was the schedule of meetings, congratulations, you are in the Matryoshka doll hell of bureaucracy.


Meetings


I loathe meetings, a bunch of people talking about the work they could be doing if they weren't in meetings all the damn time. Meetings are seductive, they sound and feel and look like work, but they are occupational masturbation. No one has ever brought a product to market because they were able to make it to 10 meetings a day. Meetings have almost no value, sometimes they are necessary, but not nearly as common as corporate culture would have you believe.


And the rest...


[caption id="attachment_683" align="alignleft" width="289" caption="Forgot to file the A34C-Bh amendment releasing liability for tongue trauma"]hot tamales candy box[/caption]

I could go on and on, but I will cut the rant short and get to the point. Bureaucracy at its core is about trust, or more importantly the lack thereof. I don't have my girlfriend fill out the A34C-B form (Confirmation of Confection Purchase Agreement) before running to the store to ensure that she understands that I would like her to pick me up some Hot Tamales. I trust her at her word, there is no need for such ridiculous formalities.


When an organization has enshrined itself in a monument of bureaucracy what it is really saying is, "We've been burned before and now we don't trust you." We don't trust you to deploy your code correctly, we don't trust you to design things properly, we don't trust you to do X, so let's get a bunch of people together to review it. This is fine in small doses, frankly I want people to review my code and my designs, I make mistakes like everyone else. But when taken to the extreme it takes a toll on your motivation, on your creativity, and on any preconceptions that you knew what you were doing. Bureaucracy is the surest way to crush your workforce into a homogeneous mix, you will catch the awful at the expense of the great.

20100202

stupid ideas

[caption id="attachment_671" align="alignleft" width="263" caption="No caption needed"]stupid burn[/caption]

I want to be honest with you for a minute, I have lots of stupid ideas. I have them all day, in the shower, while eating a sandwich, while writing my blog posts, stupid ideas come streaming into my head. I used to just ignore them, "No one needs a peanut powered lawnmower" I would tell myself. The interesting turn was when I started writing these stupid ideas down.


Some stupid ideas will always remain stupid ideas, some though will change over time. That dumb idea might actually just be so brilliant it looks stupid. It might be so big and scary that you've convinced yourself it's stupid. It might not be a bad idea at all, after some careful reflection. It might even be a wonderful idea.


Why do we throw away our stupid ideas? Is it because we don't have time for them, bah, that can't be it, you are currently wasting precious time reading the stupid things I have to say. Is it because we are so swamped with brilliant ideas that we have to prioritize, probably not, or else you'd be sipping margaritas next to your perpetual motion machine. No, the answer is much simpler, its because we are afraid or failing. Stupid ideas are failure babies, a dumb idea grows up to be a hairy ugly failure, and we have learned in the school of life that failures are bad, so we avoid them.


Have you ever talked to a 4 year old? I have on various occasions, interesting little buggers those 4 year olds. They will tell you every little thought that bounces into their overly energetic little brains, no matter how wrong or foolish. They don't mind failing over and over again, they will insist the moon is made of mashed potatoes and not feel bad at all when you tell them the truth. And most importantly they learn a ton of information.


Now don't take this the wrong way, I don't think you should just go around like some half-cocked lunatic spouting off every little thing that pops into your head. There was a time for that and if you go into the board room now insisting the moon is made of mashed potatoes you will be roundly mocked and rightfully so. What I am advocating is the preservation and analysis of your stupid ideas. Let's take a look at some stupid ideas quickly to see why this is useful.



  • Idea #1: A blanket that has arm holes and you wear it backwards or something... yea like a backwards robe! Pretty fucking stupid, but better known as the Snuggie, which has become a huge success and sold tons.

  • Idea #2: Instead of executing the code on this machine, let's build another machine that doesn't actually exist and have that fake machine live on the real machine and have code execute on the fake machine.... What? What are you rambling about Jenkins, get out of my office! Jenkins just invented the Virtual Machine architecture that power things like Java's JVM and .Net's CLR.

  • Idea #3: Wouldn't it be awesome if you could tape together 4 iPhones and have like a really big iPhone. I'm sorry, did you just smoke a bunch of peyote?! That's dumb.... Or its the new iPad.


You get the picture I'm trying to paint here. A lot of the amazing things we take for granted and depend upon everyday, things that seem like great ideas now, all had a moment in time when they were some far-fetched pie-in-the-sky dream. Most ideas start off as stupid ideas. Stupid ideas are important and valuable, not all of them, but there will be some diamonds in those dirt clods. You just have to be smart enough to sift through them.


My advice to you is to jot down those stupid ideas you normally throw by the wayside. Revisit them every once and a while, re-evaluate their "stupidness." Sometimes you will find a diamond in the rough, sometimes a stupid idea can be the spark needed to have a brilliant idea, and sometimes you will just get a good laugh out of the stupid things you think up.

20100201

open format

[caption id="attachment_663" align="alignright" width="300" caption="We\'ll just lock your data up in here, don\'t worry we\'ll open it up later if you need it. This is what a closed format sounds like"]bank safe[/caption]

Back in the days when a computer had 64k of RAM and high-capacity meant you had a double-sided floppy disc, there were these funny little things called binary file formats. We still have them today, they are the "pattern" that a program will write and read to and from disc to save and load a file into a program. Some are open, like image file formats, and some are closed, like Microsoft's binary blob formats for Office. As the world has advanced and storage has become dirt cheap people started looking for an easier way, and whenever there is a problem that we don't have a tool for yet, we reached for XML.


XML is actually not a bad fit for this problem domain, its a little on the ugly side, but that's ok, very few people crack open a raw file to read it. The people that are cracking open files in a text editor to peer inside are probably tech-savvy enough to read a little XML. The big bonus of switching to XML, like ODF or DOCX, is that there are very mature XML parsers and writers for almost every programming language. That means that a determined programmer can grab a copy of your format spec, her favorite XML parser, and write a program that operates on your file format. This is the essence of that oh-so-marketing-speak word synergy.


Now I would love to take credit for this awesome idea, but if you've read The Art of Unix Programming you will recognize this as nothing more than an extension of the Rule of Composition. Now that you've read the Rule of Composition (and you should make the time to read the rest of the Art of Unix Programming, even if you never plan on programming anything for Unix, the lessons within are just in general great to know), you will recognize the inherent advantage of having parsable file formats. Now that I have cunningly converted you over to my way of thinking, what format should you use?


XML


XML (eXtensible Markup Language) is the old standby, it is reliable, standardized by the W3C, well-supported, and there are tons of tools around for playing with XML. XML is "human-readable" for those of you unfamiliar with it here is an example.


[xml]
<book>
<title>Example Book</title>
<pages>
<page>
<![CDATA[
...page stuff here...
]]>
</page>
<page>
...you get the idea...
</page>
</pages>
</book>
[/xml]

Its a bit tag-heavy and that means a slightly large file size, this isn't a huge concern since storage is so cheap, but you should be aware of it. XML has a neat feature called DTD (Document Type Definition), armed with this most parsers will be able to tell right away if a document is well formed. XML is big and clunky but a fine choice for many applications, especially if you need typing information.


YAML


YAML (YAML Ain't Markup Language) is the format of choice for the ruby community. YAML is well supported by most mainstream programming languages, it is a more lightweight choice than XML. Here is the same thing as above in YAML.


[ruby]
book: Example Book
pages:
- page: >
...here goes my page data...
- page: >
...you get the idea....
[/ruby]

YAML uses the structure of the text to indicate the structure of the data. Ending tags are dropped and indentation becomes more important. YAML looks simplistic at first but has a wide-array of functionality hiding below the simple hello world examples. References, hashes, arrays, and much more are possible with YAML. The specification allows you to make concise documents that contain an astounding amount of information.


JSON


JSON (JavaScript Object Notation) is a lightweight way to represent data structures. JSON excels by being incredibly simple to learn and use. There is native support for it in JavaScript which makes it ideal for use in AJAX (which would then technically by called AJAJ), and there are JSON parser available in most mainstream languages. Here is the example from above in JSON.


[javascript]
{title: "Example Book", pages: [ page: "...page stuff goes here...", page: "...you get the idea..." ] };
[/javascript]

Just like in JavaScript everything in JSON is a Hash or Array. JSON is a simple typeless data recording system, perfect for dynamic languages. JSON is a proper subset of YAML 1.2 so most YAML parsers can also parse JSON. JSON's incredibly lightweight nature lends itself for being used when sending data over a wire or when space is at a premium.


BSON


BSON (Binary JavaScript Object Notation) is a binary form of JSON. It is meant to be more space efficient than JSON but maintain the ease of parsing. It is described as "A General-Purpose Data Format" and was devised as the serialization medium for the MongoDB project. It is an interesting format to look at if space is at a premium and there are already parsers for C, C++, PHP, Python, and Ruby.




File formats no longer need to be gnarled, tangled messes. We have new standards that allow us to freely share data created in one program to be analyzed, manipulated, and turned into something new in another program. Being able to freely interoperate is the future of computing, it is the driving force behind web standardizations, micro formats, and open file formats. The next time you need to persist data to the file system, resist the urge to roll your own serialization scheme, and check out one of the technologies presented above. The world will thank you.

20100127

objective measure

[caption id="attachment_642" align="alignright" width="300" caption="this ruler is deep and spiritual, that\'s why it was photographed in black and white"]ruler[/caption]

I've found myself in an odd situation as of late regarding my work, I am a programmer by trade and education but haven't done any professional programming for 2-3 months now. It's not that I'm being lazy and don't want to program, I would jump at the chance to fire up Eclipse right now and start writing mountains of verbose Java code, it's that I'm not allowed to program. "Not allowed?" I hear the shock and dismay in your voice, so let me explain.


My role on this project is to design middle-ware but because of the way the business is set up I'm not actually allowed to program, the programming is all outsourced. Instead of actual programming I get to engage in some weird form of meta-programming where I turn a program into long flowing sentences in a Word document that take about 3 times the effort to write than the program itself so that it can be shipped off and someone else can program it. It is an odd situation indeed, but I am no business man, this project is important, and so I shall continue in this weird meta-programming.


This is not my first dance at the outsourcing-prom and with the economy in shambles I'm certain it won't be my last. I have yet to work on a project where the supposed benefits of outsourcing have actually materialized. I did some research (typed something into Google) to attempt to find out how many outsourced projects fail and saw figures between 25-40%. These seem fairly reasonable to me, and with some statistical hand-waving I will use these as "good enough" figures for the rest of this post. This leads to an interesting question though, if this strategy fails so often why do companies continue to outsource?


I would like to posit that a major reason for the continued use of outsourcing is the gap between subjective and objective measure. Subjective measures come from within, they are personal opinions, things like "Frank is a great worker!" or "Jim is so lazy" are subjective measures. Objective measures are fact-based measures things like "Frank worked 48 hours this week" or "Jim only produced 1 class file this week."


Often, like in the examples above, our objective measures inform our subjective measures. The problem with software development is that there are no good objective measures. As much as we like to think of what we do as a science or even an industry, it is still a craft. In the above scenario we are led to believe that Frank is a "great worker!" because he worked 48 hours this week and that Jim is "so lazy" because he only produced 1 class file. If Frank worked 48 hours doing simple things and just racked up the billable hours is he really "working" harder than Jim who wrote a full web server in one week (monolithic in design so it was only one class). Getting to the heart of the value that someone produces is a difficult process and is by its nature subjective.


Here in lies the problem, software development can really only be measured subjectively, which is hard. Objective measures are much easier though, and so those are often used as a proxy for doing the difficult work of subjective measures. There have been many attempts to make sure people are performing up to par, lines of code, commits, bugs, hours worked, etc. None of these are really ideal, together they can begin to form a picture of the subjective nature of the situation, but they are not nearly enough.


Objective measures are also very seductive because you can perform calculations on them, they are easy to compare, they are easy to play out what if scenarios with. No one balks at answering the question which child is taller, but ask them which one they love more and watch them squirm. Objective measures are great because you can throw them in excel and analyze them, this is also a weakness. It's easy to draw up a spreadsheet with your in-house assets pitted against outsourced assets and see that you can save a bajillion dollars by outsourcing, but that misses the bigger picture. What are the subjective downsides?


These subjective downsides end up failing some 40% of outsourced projects, communication, quality control, and responsiveness are hard things to chart and graph, but can easily cause a project to run off the rails. What is needed is either some way to make subjective measure easier or some fantastic new unit of objective measure. I would propose ihumanables per hour be the unit if anyone can come up with some really nifty objective system, but I don't see that happening anytime soon, so all that's left is making subjective measure easier, a tall order indeed.


At the heart of making subjective measure easier is really what a lot of the agile methodology is about, stand up meetings, scrums, kanban boards, they are all meant to produce a tight feedback loop so that the subjective nature of the situation is constantly being polled. I'm not going to sit here and tell you all to start running agile projects, although they can be a good bit of fun, but if you are managing people you need to get in the dirt with them. Progress reports and weekly status meetings are meant to supplement not substitute actually working with and understanding what the people under you are doing.


Remember the next time you are making a decision based off of objective measure, if you are "going by the numbers" that there are very real subjective side-effects that you should account for and be aware of. And if someone develops a really killer objective measure for software development, remember ihumanables per hour ;)

20100126

when in rome

[caption id="attachment_624" align="alignright" width="300" caption="Trust me, you want to do what the Romans do, I mean... have you ever built a Collisium?"]collisium[/caption]

Ah the cliché of it all, "When in Rome." Although it would be nice to have a post about being in or traveling to Rome, sadly this is not the case. Instead, this post is about following convention and how that can help you learn.


I've been getting into ruby as of late, after learning Smalltalk, Objective-C, and LISP (to varying degrees), ruby hits a nice sweet spot of stealing some of the best bits from each. I was recently approached by a friend who does primarily .Net programming about the best way to go about learning ruby. He had decided that, at least in the beginning, he should use the NetBeans IDE. This seems harmless enough, even logical for someone who spends their entire day in Visual Studio to want the comforting guidance of the IDE. It is also the exact wrong approach.


As he progressed past simple "Hello World" examples and onto his first rails project he found himself battling with the IDE. Odd error messages, the IDE struggling to provide auto-completion on the dynamic models, but most importantly a complete lack of resources. The ruby and rails world to a large degree lives and breathes on the command line, right now if you go to my home computer you will find 4 terminal windows arranged with a mysql shell, script/console, script/server, and one for git. If something goes wrong and I get a weird error, I do what all great programmers do, copy and paste that sucker into Google. I normally find somewhere around a bajillion hits with solutions, huzzah!


My friend on the other hand had trouble doing the simple things through the IDE, like installing gems. I'm certain the IDE was capable of it, and that someone better versed in it would be able to help him out, but the Google-scape was barren to his questioning. All I could say to answer his questions were, "well I'm not sure how NetBeans does it, but on the command line just type gem install [gem]" (Also I can speak in teletype, I just do a robot voice.)


Despite the difficulties, my friend clung to the belief that the IDE was the way to go for beginners. I finally realized the perfect analogy to drive home the point, I asked, "Would you ever advise someone new to .Net to learn it by using the command line tools?" It's a perfectly valid question, I'm sure plenty of people who hang out in vim all day and don't mind doing things like ./configure && make && sudo make install (thanks Jeremiah for pointing out my n00bishness) would feel much more at home on the command line.


I am not free of fault on this either, when I attempted to learn git for the first time, I used TortoiseGit. I was very comfortable with TortoiseSVN and thought it would ease the transition. It sure did, I was able to treat git exactly like svn, and completely miss the point! Once I moved to the command line (and watched some screencasts and read some articles) I felt much more at home with git, and even began to understand why I would want to use it over svn. I had stopped trying to make it something it isn't and embraced the thing that it is.


The point here is that when you learn something new, it's new, don't bring along your technological baggage. If the community all rallies around some IDE (.Net, I'm looking at you) then for flying spaghetti monster's sake, use that IDE. If they rally around the command line (ruby, I'm looking at you) then by the hammer of Thor, use the command line. If they rally around some weird virtual environment machine (smalltalk, I'm looking at you) then have fun and realize you are never going to be able to use that at work (just poking fun, I <3 smalltalk).


The point here is that learning something new is often times uncomfortable, you have to feel like a tourist for a while. When in Rome though, do as the Romans do. Embrace the methodologies, naming conventions, and tools that are the community standard. Give it a few weeks, if you still find yourself hating it, then maybe that particular technology isn't for you, it's ok, we can't all love everything. Life is about trying new things and figuring out what makes you want to get out of bed in the morning, for some people it will be .Net, for some ruby, for some COBOL (just kidding, no one likes COBOL).


You never do yourself any favors by half-way learning something, because you will either hate it because it was poorly shoehorned into an inappropriate paradigm, or you will learn to love it. "That second thing doesn't sound too bad" (I can sense your thoughts), and at first blush its not, until you want to start participating with the community by using others' code and sharing your code. Then you will have to unlearn all the bad practices you've adopted and have a difficult transition into the community, attempting to erase months of muscle memory. Save yourself the difficult task of trying to unlearn something and simply embrace the technology in full to begin with. It's a steeper curve, but the payout is the depth of understanding.

20100125

api

[caption id="attachment_618" align="alignright" width="142" caption="oh creator of hot pockets, we praise thee!"]samsung microwave[/caption]

I remember being a young lad preparing myself for university I was given a gift from my mother, "C++ for dummies." The vote of confidence on my status as a "dummy" aside, I read the book with great interest. There was an analogy the author used to explain the idea of classes and what functions they should expose, I'm going to shamelessly steal it (paraphrasing as I don't have the book with me).


Imagine your son comes up to you and says he wants to make some nachos. You tell him that its fine by you, just go cook them in the microwave, and there is nothing controversial about this statement. Microwaves are actually boxes full of high energy radiation being produced by cavity magnetrons or waveguides, to the end user, the microwave is just a magic warming box. It exposes a very simple interface, some buttons that allow you to enter the amount of time you want to cook something.


This is the essence of an API (Application Programming Interface), wrapping up something complex and possibly dangerous in something safe and easy to interact with. When building code that you intend other people to use someday, it is the part that is most important part, and the part that is easiest to overlook. The problem is that we are often too close to something and too concerned with our use case. If you want to design code for others to use, it requires significant time and effort, and even then you probably still won't get it right.


Prosper is still undergoing active development, I'm currently agonizing over how I want to expose various execution modes. The solution, no matter what I pick, is trivial to implement, but the api is the most important part. A great api exposes a consistent concept, something that is easily grasped and allows the end user of the api to declare what they want to do without having to worry about how its going to get done. Since good programmers write good code and great programmers steal great code, I've modeled the api for prosper extensively off of jQuery. And why not, let's take a look at two different APIs, the browser dom api and jquery.


[javascript]
//Let's barber pole a list by coloring every other element blue
var list = document.getElementById('the_list');
var highlight = false;
for(var i = 0; i < list.children.length; i++) {
if(highlight) {
list.children[i].style['backgroundColor'] = '#FF0000';
}
highlight = !highlight;
}
[/javascript]

Fairly straightforward implementation, but it concerns itself heavily with the "how" of what its doing. Manually traversing to pick the elements it wants, eww.


[javascript]
//Same thing using jquery
$("ul#the_list li:odd").css("background-color", "#FF0000");
[/javascript]

jQuery is definitely magic, but this code is great because it let's you focus on the "what" of what you are doing. How does jQuery go about selecting the right elements and all that? I don't care, and the great thing is I don't have to care, and if in the next version of jQuery they find a way to do it faster, I win without having to do anything.


Writing a great api is difficult, you have to divorce yourself from the concrete problem you are solving and look at it in the abstract. Put yourself into the shoes of someone trying to figure out how the api works, and then ask the questions they are going to ask.



  • Why do I need to build up this context thing and pass it in?

  • How come there isn't a sensible default for these arguments?

  • What dumbass made this thing?


Answer those questions, and keep working at it, strive for elegance and consistency, because then it will be easy for people to learn and use. If your code is easy to learn and use, people are going to want to use it more, and they are going to want to tell their friends about it. Then you can get some lucrative ad campaigns with Nike because of the boffo library you write in FoxPro.


There is a more subtle lesson in all of this though. Any code you write is exposing an api to someone else. "But only I am ever going to use this code!" I hear the naysayers warming up their keyboards for the comments section. This may be true now, but the six-months-from-now-you is going to look back at the you-of-today and wonder what the hell he was thinking.


Get in the habit of making your code easy to use, and expose a nice api. This will endear you to your fellow programmers and help make maintenance easy. Strive to be that guy on the team that writes functions and classes people want to use. Make life easier for your fellow developers and even if they don't return the favor, maybe they will take you out for a beer. People notice over time that your code is the best to work with, they internalize it, and they start to think of you as a great programmer. That's a pretty great api to expose to the world.

20100122

hustle

[caption id="attachment_613" align="alignright" width="299" caption="That time was so much more glamorous"]do the hustle[/caption]

A realization has been dawning on me as of late, one that I've always known, but that is easy to forget, easy to misplace, easy to neglect. The best way to learn anything is to do it, to struggle through, to forge on, to fight and gnash teeth and curse at. There is no knowledge as highly regarded as that which you have to work for.


I'm not even particularly certain how this all came about, it seems to have been a culmination of things. I didn't intend to but somehow I ended up putting on my plate a bunch of new stuff to learn around the same time. Git, ruby, rails, blogging, prosper, hosting my own domain, and testing (Testing being a decidedly late addition). This blog was the genesis of a lot of it, that and just being curious.


I had my first post back on October 2nd of last year, as of writing this 112 days ago. At that point I didn't really know anything about the 7 topics above, I started the blog using Google's Blogger platform, it was an easy onramp.


After a month or so, I was encourage by some friends to move the blog to my own domain, which you are now at. I also kicked off the prosper project around the same time as starting this blog. I played around with ruby and a crazy friend convinced me to try out rails. I moved prosper to GitHub and began learning git. Now prosper supports 19 backends and has gained over 100 unit tests in the last few days.


Here's the kicker though, I don't know what I'm doing. I never really did, I just started doing stuff, and have been running ever since. There have been days when I've gotten 5,000+ hits on this site, several days with several hundreds of hits and I've been steadily increasing the daily reader count. I don't know how I did that, I just kept writing, I liked it, I promoted it over twitter and hacker news if I thought I had written something insightful, and I guess that is working. The same thing with prosper, I saw a need for something that didn't exist, I had a vague idea of how to make it, and I started coding. I've rewritten and refactored it piece by piece to the point that it supports all kinds of things I never thought it would. It's due for another architectural change after I finish these unit tests.


If there is one key thing I could convey to anyone reading this is to hustle. You will never be prepared for the things you are capable of doing. You will achieve your greatest accomplishments not by building up a grand framework of skill and then deftly creating something glorious, but by starting small and persevering in making it better and better. It is never an easy road and you will gain a grand framework of skills, but you have to push your boundaries to grow.


This came together for me last night, I was working on a rather tricky bit of rails and broke something. I hadn't gone too far into it and so I typed rake db:rollback and git reset head --hard and was back to a working application. I stopped myself for a second and thought about what I had just done, how improbable it all was from where I was just a month ago. I then thought about what I was doing in rails, and thought about how earlier in the day I was wrapping up prosper functionality in unit tests and finding regressions, and how I would have to write some cucumber tests for what I was doing, and I realized that 112 days ago I didn't have the vaguest idea of any of this.


I would love to put a triumphant "I'm just so damned smart and talented and handsome" paragraph here, but that's not the case. I just steeped myself in this stuff, I worked in git daily, I read about it, watched screencasts, I bought agile web development in rails, I got design patterns in ruby, I hustled. And you can do it too, take the first step today.


The first step that you should take is to invest yourself in something non-trivially. Want to learn rails, then go buy agile web development in rails, want to learn github, move an active project out there, want to learn linux, reformat your machine so that's all you have. You have to invest yourself, it plays a trick on your brain that makes it want to not waste that "investment" by quitting. If you can burn your boats (Hernán Cortés reference) all the better. I had no choice but to learn git or else I couldn't keep working on my project, and as a side bonus I got the joy (and frustration) of working in git everyday.


Get out there and hustle, learn something new, do something that scares you, reach beyond your grasp.

20100121

unlicense'd

[caption id="attachment_606" align="alignright" width="300" caption="Freedom has never kicked so much ass"]colbert portrait by lockwood[/caption]

I wrote yesterday about the importance of open source software. I got one comment saying that prosper would be awesome if it were in the public domain. Here is the comment from Arto Bendiken


Prosper looks *sweet*. It’d be awesome if Prosper indeed were in the public domain. I think such a move would make for a decisive selling point over the numerous competing PHP libraries, setting Prosper clearly apart from the herd and allowing it to be easily embedded into any new emerging PHP web frameworks.

It’s worth mentioning that a key reason that SQLite, which is in the public domain, has prospered (no pun intended) has been the fact that it can be so easily (both technically and legally speaking) embedded into any other software. The end results of technical excellence combined with singularly liberal licensing speak for themselves: http://www.sqlite.org/famous.html

I think a lot of these same benefits could come into play also in such a potentially key higher-level web app infrastructure piece as Prosper. It certainly seems that you have the technical side of things well in hand, already, so here’s hoping for a bright and prosperous future.

Well I completely agree with Arto and want to clear up any confusion about prosper and its license. Prosper was original hosted on Google Code, which requires you to choose a license, at the time I selected the MIT/X11 license based off of my belief that it was the most free. A little further down the road I saw the WTFPL - Do What The Fuck You Want To Public License and thought about switching to that. There is a bluntness to the ideal of that license that appealed to me.


The problem with the WTFPL is of course its name, I want prosper to power lots of things and that means taking into account a wider audience. While hackers and rock star programmers can easily adopt something with WTFPL, I didn't want to be responsible for some corporation turning their back on an otherwise useful library because they were squeamish about a word in the license.


[caption id="attachment_607" align="alignright" width="220" caption="I always thought people just hated the letter C... then I found out this means no copyright"]no copyright[/caption]

Then I found this post on Hacker News (ironically by the same Arto Bendiken) and it lead me to the Unlicense. The Unlicense is exactly what I was looking for and simple to adopt. If you go to the GitHub repo you will see that the project is now officially Unlicense'd. The 0.8 release will be the first official Unlicense'd release, and so will every release going forward. I believe in free and open source software and so I'm publicly declaring now that prosper will always be free, open source, and unencumbered. The mechanism that I will use to ensure this going forward will be Unlicense.


What's the big deal, plenty of things are open source, why is this any different? The difference is that I'm giving this away fully, without any restrictions. Want to build a cool new library that uses prosper as the low-level database abstraction layer, go for it. Want to build a proprietary ORM that utilizes prosper, go for it. Want to repackage prosper and try to sell it (as underhanded as that is), go for it. Want to smother prosper with jam and eat it, if you can find a way to, go for it. Want to.... enough already, you can do whatever you like.


It is easy to talk about things like freedom and support them in the abstract, it becomes more difficult when you have something concrete. People could very well take prosper and take it in directions I don't care to see it go, but that is life, that is creation, that is the essence of open source. It is my goal to see prosper provide a solid foundation for building new and better tools and frameworks in php. I want as many people as possible to use it, and so this was a logical choice.


The next time you have some useful chunk of code lying around and you want to give it to the public domain for the good of the public, think about using Unlicense. I can't say it any better than they can so I will just quote their section about why you should use Unlicense. "Because you have more important things to do than enriching lawyers or imposing petty restrictions on users of your code."

20100112

who cares?

[caption id="attachment_573" align="alignright" width="300" caption="I shot who in the what now?"]man shrugging[/caption]

It's one of my favorite questions to ask during a technical discussion. Who cares? Some others I like to throw out our, why should I care? why does it matter? and I don't care! Am I some sort of raging lunatic completely out of my mind and trying to pick a fight with everyone I meet? Yes, but that's not why I ask these questions. I ask these questions because as great as the big picture is we sometimes have to drop complexities to get stuff done.


When you have a big flow diagram or giant UML Class Hierarchy it can be fun to think about the abstract way that things interact and how you can pass state around and whatnot. This definitely is useful for getting a feel for a new system, but then there comes the worst part of any software developer's job, actually getting things done. You see that's what we get paid for, actually putting our fingers on keys, typing stuff out, compiling it, and shipping a product. Part of this is doing the upfront design work and getting all of our t's crossed and i's dotted, but just as important is actually getting something working.


I talked about this before in my post about simplifying things. This simple question, "who cares?" (you can be more diplomatic about it if you like) is a great tool for getting to the heart of a problem. I like the simplicity and straight-forwardness of the question, it normally catches people off guard and challenges their assumptions.



Frank: So we need to pass this data into the layer
Bob: Who cares?
Frank (taken aback): I care, I care deeply about this data
Bob: But why do you care about it being in that layer, its just going to hand it off to this layer, and that layer doesn't care at all about it
Frank: I guess you are right, we don't need it there

BAM!!! Problem simplified! For anyone that's ever taken any education classes you may recognize this as a rather blunt application of Socratic Method. The point is confrontation, but not between the two people discussing something, between each person and their preconceived notions about a problem or situation.


In High School I took a chemistry class, it is one of the few classes that I really remember in any detail from so long ago, the teacher taught the entire semester in Socratic Method. He would question us, we would experiment, we would reason out why we observed what we observed, he prodded us, and we cherished our knowledge. Anyone can tell you water is composed of 2 hydrogen atoms and 1 oxygen atom, but when you had to work for it, when you had to defend your knowledge of it from scrutiny, it became concrete, it became your discovery.


Applying this to software development is useful, we can get locked into our preconceived notions, and direct, blunt, sometimes even rude questions can spur you to really consider what you are talking about. Software is incredibly fluid, sometimes an idea or concept can become out-dated in a matter of months or a matter of hours. The biggest ones are the most difficult to challenge, because they often have the most dependent code around them, but this makes them the most important to constantly consider.


Keeping your conceptual design, implementation, and solution in lock step with a problem domain often involves some amount of change, that change can be hard to come by though. By challenging our standing beliefs we can find new avenues for exploration or strengthen the existing techniques and gain a better understanding of them.

20100111

grok

[caption id="attachment_565" align="alignright" width="282" caption="necessary part of grokking something"]banging head[/caption]

Computer nerds should be familiar with the term grok while the rest of the populace has no need for such a silly word. You may hear it down at your favorite nerdery, "I don't quite grok this" or "Once I grokked it, I flew through the project." What does this word mean though and where did it come from.


Grok for the non-nerd means, "to understand thoroughly and intuitively." Although this is true it belies what it truly means to grok something. For that we need to realize the origin of this fantastic geek speak, this term is straight out of Robert A. Heinlein's Stranger in a Strange Land. He defined it as follows



Grok means to understand so thoroughly that the observer becomes a part of the observed—to merge, blend, intermarry, lose identity in group experience. It means almost everything that we mean by religion, philosophy, and science—and it means as little to us (because of our Earthly assumptions) as color means to a blind man.

The great thing about grokking something is that it changes your world view, it fundamentally shifts the way that you see, perceive, and understand the world. The bad thing about grokking something is that it is incredibly difficult to get to that point. Let's take a look at a fantastic chart I've whipped up to help us understand this better.


[caption id="attachment_566" align="alignleft" width="300" caption="the graph of grokitude"]grok[/caption]

In this graph we have time and effort along the horizontal and understanding along the vertical. We can spend a great deal of time after "mastering" a subject before we get the epiphany and truly grok something. To really understand a subject on the level that a computer nerd would consider grokking it takes not only a full in-depth knowledge of the function of something, but an understanding of the design, an internalization of the principals, and a familiarity that borders on oneness.


This is the reward for hundreds or thousands of man-hours spent toiling in something, the day when the clouds part and you truly understand something, this has an amazing non-linear effect on your understanding and your productivity. Once you grok something, be it a framework or a library or a concept, your ability to use that and your productivity in it increase in a non-linear fashion.


Although it is important to have a wide breadth of knowledge we must remember the importance of having a few areas of incredible depths of knowledge. These areas will permeate everything else you do, so try to choose wisely. The subjects that you truly grok are the ones that will effect your big picture outlook.


Here are my suggestions for some fundamental things to learn, and learn to a point that it fundamentally shifts the way you look at the world.



  • A Pure Object Oriented Langauge - I would suggest smalltalk for purity, but ruby makes a fine substitute and has more application.

  • A Functional Language - For this look no further than Haskell, and Learn you a Haskell for Great Good

  • A Set Language - Take the time to learn SQL, its a tool most of us use everyday and very few of us take the time to learn properly

  • A Markup Language - HTML + CSS, these are the embodiment of separating data and display, learn them intimately.


Learning these, but more importantly grokking them will color the way you approach problems and solutions. Having a depth of knowledge in a key variety of tools allows you to quickly master new ones, better understand problem domains, and more completely express your thoughts in the abstract.

20100108

limits

[caption id="attachment_558" align="alignright" width="300" caption="its beauty is only matched by its cliffy-ness... or something"]cliff edge[/caption]

I had to make a hard decision today, it was one that I had known I would have to make at some point, and frankly I was just putting it off. I've written about burnout before and I'm no stranger to pushing myself harder than I should. But I like to think that because I'm aware of the danger and am actively working to avoid burnout that I can push myself, and still maintain some sanity.


Part of maintaining sanity is knowing one's limits. I have a full-time job, prosper, and until today 2 side projects. Today I resigned from one of my side projects and I released any code or concepts I had worked on to the other developer. It was not something that I particularly looked forward to doing, but I had to prioritize. I had to dispassionately measure the various aspects of my life and make a cut before I burned out and lost everything.


Now I'm left with a strange feeling, almost ashamed that I let down the other party, but at the same time a sense of relief has come over me. After I made sure that I didn't burn down any professional bridges, another wave of relief. Looking forward in my calendar and seeing all the time I've got to work on Prosper and my other side project, a wave of excitement. The problem was that I was spread too thin, at my limit, I was pushing ahead 110% but not moving anything forward. Now though I feel back in control, pushing ahead and making things happen again.


I've given this new attitude a shot in the arm over the last few days. For the last few days I've been knocking out tasks that have been long outstanding and non-trivial. It's easy to trick yourself into thinking you are being productive by banging out a few quick trivial tasks and checking some stuff off the todo list, but picking long standing non-trivial tasks is important.


My girlfriend's father's computer was the first such task. It's hard drive died, and I've had it for far too long. What should have been a simple diagnostic-swap-reimage was bedeviled by problems. I didn't have the right keyboard to perform the diagnostic (all my usb keyboards were read by the bios but not the ubcd prompt), then the replacement drive I was provided was the wrong type, and the recovery disks were all oddly labeled. The task itself though is not that difficult, get the right drive, swap, get the right disk, click click type, wait 4 hours for reimaging. The giant tower sitting there day after day had become a constant and depressing embodiment of my inability to move tasks forward. Yesterday though I finally hooked it all up, found the right disk (on the third try) and reimaged it. Everything works fine now and the problem is solved.


For the presentation I'm giving at CodeMash I plan on doing a live demo, I needed to pin this completely down to the last detail and do all the boring set up work so the presentation can be all whiz-bang cool. After an hour or two hacking around this is now done. My minimal PowerPoint presentation is well on its way to being complete. Getting these non-trivial roadblocks out of my way is freeing up my mind to think of other things, to begin figuring out how to move other things forward.


My suggestion for anyone feeling overwhelmed is twofold. Be realistic, are you taking on too much, I was, it happens to the best of us. It's never a great feeling to admit that you've overextended yourself, but it's much better than just constantly being overextended. Are there tasks that are constantly at the back of your mind, nagging todo's that you keep putting off, well just tackle them. It's not fun, but when you put them off they start growing larger and larger in your mind's eye. The live demo only took around an hour to code through, even though in my mind it was important and therefore a monumental task.


Pick out one of those tasks that's been on your todo list for a while, knock it out, just having it done is worth the work.

20100105

experimentation

[caption id="attachment_523" align="alignright" width="300" caption="Like most computer related things this type of experimentation will have less blond women"]Female in lab[/caption]

I love my mom, she is a kind, intelligent, funny person. She has worked 2 jobs since I was just a little kid and she still does. For most of my childhood she worked in what we refer to in this country as the "Service Industry." This is a nice euphemism for mind-numbing tedium, the fact that she put in 14-16 hour days to give me the chance to sit here and blog and make good money consulting is a testament to her devotion as a mother. I remember growing up she worked at a Gas Station and at Arby's, sometimes bringing home some tasty chicken sandwiches or Apple Turnovers.


Now my mom works retail and in an office. She gets to work in a nice office and do office work which means that she now has to professionally use a computer. Being the "computer" son I get the calls when there is some task that falls outside the scope of her knowledge, and after all she's sacrificed for me, I'm ecstatic that I get to help her.


The things she needs help with our never very complicated, sometimes its an unfamiliarity with an FTP Client or looking for a way to open up and print multiple files quickly and easily. She normally has figured out or been told some way to get the job done, but it's so slow and tedious that there must be a better way. Normally after a few minutes of explanation we figure out a way that she can do her job faster and easier, and everyone wins.


In my job as a software developer I often have to think about the user, and its an interesting relationship. On the one hand if there were no users then I would make no money and that would be sad, on the other hand the users often end up taking a simple and elegant piece of code and twisting it into a horrible abomination so they can understand it better. The mental images of a slack-jaw fool and a well-meaning bug filer compete in my head. Now though I have a new user mental model, my mom.


I know that she is hardworking, intelligent, and does know how to use a computer for daily tasks. Yet, even with these great user attributes, she still doesn't discover things that I do, and I wonder why.


[caption id="attachment_525" align="alignleft" width="300" caption="Yea that\'s assembly not basic, go complain about it in the comments."]green screen with assembly[/caption]

Perhaps its a generational difference, I can't actually remember a time when I didn't have a computer. I remember distinctly getting the old green and black computer with 5.25in disks that I could play submarine hunting games on from my Uncle Marty. One of the first things I did with this new toy was to get a book from the library full of BASIC games and start typing them here, that's right I've been programming since I was about 6 years old. The thing that no one ever told me was that I could break the computer, to me it was a toy, and the worst thing that could happen is I mess up my disk and have to try again. As I moved up to more and more powerful machines I've always kept that same mindset, the computer is there to accept my commands, there is almost nothing I can do to it that can't be undone.


My mom on the other hand is pre-occupied with the idea that she might break the computer. This is a major difference between computer people and users. Watch a power user trying to figure something out, they will experiment see what happens when they click this or that, issue this command, or right-click in this box over here. A normal user on the other hand normally just uses the program in the way that they've been instructed to, instead of exploring the interface.


In a perfect world everyone would read the user manual, in real life though people don't. Even if people did, it's hard to learn reading, it's easy to learn doing. The power user learns through trial-and-error how something works, once they feel comfortable with the bulk of the application they may turn to the manual to figure out some of the trickier bits. The normal user will never get to a level of comfort to attempt to master the tricky bits. As the power user explores they feel validated and gain a sense of control, giving them a desire to assert their control over the rest of the system. The normal user is simply performing a rote task, the tool is not there to be explored and mastered, it merely performs some function.


Its the difference between becoming a magician and learning a card trick. I can learn a card trick and practice it everyday, becoming incredibly good at the card trick, this in no way makes me capable of sawing a woman in half (and having her live).


Trying to get users to experiment involves a few things



  • Everything your application does should be easily and apparently reversible.

  • Experimentation should be rewarded, never punished

  • The Application must cope well with the unexpected, no nasty error messages

  • Context Sensitive Help


[caption id="attachment_527" align="alignright" width="300" caption="TextMate is full of win"]textmate[/caption]

Case in point: I've recently got my sexy new iMac with the excellent TextMate for coding. It is one of the best experiences I have ever had, but it's not because it is easy. TextMate encourages you to explore and experiment, defining a function, def :tab: will automatically write the end and position you to write the methods. The Bundles menu is quick and accessible, the bundles make it easy to figure out what to do and the reward is instant. All of this culminates to making the software seem usable and easy, even though its very complex.


Turning users into explorers is no small task, but the payoff is great. The more a user feels in control, the more they explore, the more they explore the more in control they feel, its a positive feedback loop. The more in control a user feels the more they associate your project with being easy to use and generally a good piece of software.

20100104

simplify

[caption id="attachment_515" align="alignright" width="293" caption="simplicity is sometimes surprisingly complex"]it's so simple[/caption]

I love abstractions, most people do, they allow us to take complex things and wrap them in simple things and everyone is happy. The thing to realize is that there are degrees of complexity and different goals of abstractions.


Programming is one of those things where more often than not our abstractions are really helpful. The problem becomes one of perceived complexity vs. actual complexity. A good example is network protocols.


Network protocols are these complex beasts that let us talk across networks with some degree of certainty. Its really quite the marvel of engineering prowess, man has taken the various blinkenlights and cables and a big ole' pile of Cisco and now you can watch a video of a cat playing keyboard whenever you like. Network protocols were designed to simplify the process of two programs on physically distant machines sharing information.


When you first try to learn a complex abstraction it can seem daunting, UDP, TCP/IP, sockets and fifos and netcats oh my! Sometimes it can seem overwhelming, but take a step back and realize that no matter how complicated a piece of software is, its just moving around bytes.


Perl has a philosophy that at the end of the day, everything is strings. That's why its the glue that holds together the interwebs, because it's just a really good string manipulation language. At the end of the day that's all the internet is, strings floating around, normally between angled brackets.


Like most of the things I write I'm almost certain I had a point... oh there it is. When I started writing prosper it seemed like an impossible mountain to climb. I wanted to write a library that would bridge the gaps between all supported database backends, to have it be a sort of universal data access object.


[caption id="attachment_516" align="alignleft" width="354" caption="This was much easier to think about than the actual problem"]prosper simplified[/caption]

I had a few false starts on my project until I took a step back, I simplified my problem domain, and created an architecture that worked. Instead of focusing on the end result of prosper I thought about it in a more abstract way, prosper was a mapper from function calls to string snippets. This isn't actually what prosper does today, prosper is in fact much more complex now than I would have ever imagined when I first started out.


The obstacle that stood in my way the most when starting out on prosper was being overwhelmed and unsure. The problem domain I was trying to tackle was too big, even when I tried solving it i ended up painting myself into a corner by focusing too much on how one specific backend acted. I needed a simpler problem that was more easily solvable, but one that would in the end help me reach my actual goal.


As much as I wish I could take credit for this idea, it's not mine, it's something called Minimum Viable Product. I wanted something that at its core would produce cross-platform SQL, so the first iteration was to make something that did exactly that. If you go on GitHub and pull one of the earlier commits you will see that that's exactly what I built. Over time I have added the ability to execute those strings, connection and transaction management, standardized results, prepared statement support, and much more.


I couldn't have accomplished any of this though if I hadn't taken a step back from the problem domain and looked at the simpler problem at the core of what I was trying to do. I stumbled in the beginning, I've refactored again and again, over the break my good friend Ian took a look at the library and found a whole slew of problems, and I thank him for it. Prosper isn't perfect yet, but it is moving toward being something really worthwhile, and to begin moving it required that I have something, anything, to start with.


So here is my suggestion for you for the new year. If you have some project that you've wanted to do but couldn't figure out how to start, step back from the problem domain and try to find the core of the problem and solve it with the simplest thing that could possibly work. Don't worry about the first iteration, or the first 20 iterations, you have to just get started. Once it is started you can iterate and refactor and maybe throw everything away and start again. No matter what the outcome of the first iteration it will be worth it, the best case scenario is that you can use the first iteration as a core moving forward, the worst case is that you learn a bunch about the problem domain and have to try again.


It's the start of a new year, resolve to start your dream project, because that's the hardest part. Once you get rolling momentum has a fantastic way of carrying you through.

20091230

minimalism

[caption id="attachment_493" align="alignright" width="296" caption="minimalist staircase... looks really dangerous"]minimalism[/caption]

I am a minimalist at heart, I like simple things with clean lines and no clutter. This is one of the reasons I love my new iMac, its just a beautiful magic floating screen filled with win. Minimalism is more than just an artistic movement or an ironically expensive interior design style. Programming is by its nature minimalistic, we programmers (as I have said before) are a lazy bunch. No one wants to type the same code over and over again, so we came up with functions, and then classes, and then inheritance, and frameworks, and aspect oriented programming, and so on and so forth. We want to reduce the amount of work that we as the developer has to do.


Here is a simple windows program that pops up a hello world screen using Visual C++


[cpp]
// GT_HelloWorldWin32.cpp
// compile with: /D_UNICODE /DUNICODE /DWIN32 /D_WINDOWS /c

#include <windows.h>
#include <stdlib.h>
#include <string.h>
#include <tchar.h>

// Global variables
static TCHAR szWindowClass[] = _T("win32app");
static TCHAR szTitle[] = _T("Win32 Guided Tour Application");

HINSTANCE hInst;
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
WNDCLASSEX wcex;

wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_APPLICATION));
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_APPLICATION));

if (!RegisterClassEx(&wcex)) {
MessageBox(NULL, _T("Call to RegisterClassEx failed!"), _T("Win32 Guided Tour"), NULL);
return 1;
}

hInst = hInstance; // Store instance handle in our global variable

HWND hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 500, 100, NULL, NULL, hInstance, NULL);

if (!hWnd) {
MessageBox(NULL, _T("Call to CreateWindow failed!"), _T("Win32 Guided Tour"), NULL);
return 1;
}

ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);

MSG msg;
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (int) msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
PAINTSTRUCT ps;
HDC hdc;
TCHAR greeting[] = _T("Hello, World!");
switch (message) {
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
TextOut(hdc, 5, 5, greeting, _tcslen(greeting));
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
break;
}
return 0;
}
[/cpp]

Holy Shit! This is after I stipped all the comments, removed whitespace, and reformatted to 1TB. But here is how much code you need to do something similar in C++ leveraging Qt


[cpp]
#include <QtGui>

int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QLabel label("Hello, world!");
label.show();
return app.exec();
}
[/cpp]

This is great news for the developer, we can accomplish the same result with much less code. We are now much more productive and so we have freed up some precious developer time that we can spend on something else. Our code is much smaller, much more minimalist now, which is good because we are lazy. This ends up being a dual edged sword because there is now the temptation to start coding up more features, because they are so easy to implement now. We have made our code more minimalist but in doing so have enabled developers to make their applications feature bloated and anything but minimalist.


Jeff Atwood wrote a post yesterday, Responsible Open Source Code Parenting, in which he asserts that John Gruber is being a negligent open source parent.



I don't mean this as a personal criticism. John's a fantastic writer and Markdown has a (mostly) solid specification, with a strong vision statement. But the fact that there has been no improvement whatsoever to the specification or reference implementation for five years is … kind of a problem.

The question I had, and still have is why. I wrote this comment on Hacker News yesterday regarding this post



The idea that since markdown hasn't done anything in years its somehow being stewarded improperly is a bit foolish. Look at Gruber's vision statement, he wanted to make an easy-to-read easy-to-write markup.

He did it, it is done, it's called markdown. If Atwood had his way Gruber would have spent the last 5 years filling it up with features and today we would be reading a post about how Markdown went from slim and sleek to fat and bloated.

Gruber set out to do something, then he did it, now it's done. It's a minimalist approach. Atwood would have rather he spent the last 5 years allowing for "open source collaboration" that would help in "moving forward and maturing" Markdown. To what ends?


It is easy to add feature after feature to something with the belief that you are somehow adding value, but the whole world doesn't think this way. Let's illuminate this with an example.












Apple Remote Windows MCE Remote

[caption id="attachment_496" align="alignnone" width="80" caption="There are 7 buttons"]apple remote[/caption]

[caption id="attachment_497" align="alignnone" width="245" caption="The technical term is an assload of buttons"]mce remote[/caption]


That's how the Apple Remote is intended to look, it's not lacking buttons because they haven't gotten around to putting some more on, they intentionally kept it simple. Now I'm not trying to argue that one remote is superior to the other, I prefer the Apple Remote, but the important word there is prefer. Atwood makes the mistake of thinking since something hasn't changed in 5 years its a problem. What if Gruber did the cost-benefit analysis of the new features for the last 5 years and decided that it just didn't need anything else.


People have asked me if I'm going to use Disqus and although I tried it for a bit I decided to just use the simple built-in commenting system. Disqus was all kinds of bells and whistles, it is (in my opinion, which since it's my blog is the only one that counts ;) ) ugly, and it's benefit doesn't outweigh it's cost in my opinion. By the time I took out all the stuff that made Disqus feel bloated to me I realized I basically had the simple built-in comments, just hosted by a third party, so I abandoned it.


There is a cost to every feature you throw into your software, the cost is added complexity. I have decided that complexity better come with some gain for the user, otherwise I won't add widgets and gadgets and features just to add them.

20091223

decompress

[caption id="attachment_472" align="alignnone" width="450" caption="Get ready for the feats of strength"]festivus card[/caption]

The holidays are upon us and no matter what holiday your particular sky god has you celebrate (Festivus for the Rest of Us!) there is one thread of humanity that binds us together at this time, days off from work. When you have some time off of work you can spend it doing any number of worthwhile things



  • Drinking egg nog until you black out

  • Eating your weight in sugar cookies

  • Having that same argument with your family that you've been having for the last 10 years

  • Watching 24 hours of A Christmas Story

  • Spending quality time with friends and loved ones

  • Living through the same day over and over and over, á la Groundhog's Day (Best saved for the actual Groundhog's Day)


If you are reading this blog there is a good chance that you are some sort of programming nerd, its ok, I don't care what the New York Times says. As a proud nerd you have probably heard of some sort of technology that interests you, maybe clojure has piqued your curiosity, or you finally want to learn that "rails" thing all those young whippersnappers keep talking about. I would argue that this can be a great way to decompress, if you do it right.


First off, find something different than what you are used to, if your 9-5 is .Net don't spend your precious free time learning more .Net, that's stupid. Go find something radically different, maybe look at a functional programming language, go find that weird kid in the corner and talk to him, he probably has interesting stories about fire. This might seem like a waste of time at first, but it's not. It's all too easy to get locked into an ecosystem, doing the same thing day in and day out, to get comfortable there and to start thinking that your way is the only way or the best way. Reading about other technology outside of your realm might not have a direct benefit to your 9-5, but you may gain a perspective or understanding that would be incredibly difficult to get from your standard frame of mind.


Second off, this isn't work, this is fun. You are allowed to make mistakes and change your mind. If you work through a tutorial or get done with the first chapter of something and find that you really don't care, then go find something else, the software world is full of interesting things. The thing is, only stop if you grok the subject and dislike it, don't necessarily stop just because you don't get it at first.


[caption id="attachment_475" align="alignright" width="300" caption="What? Caroling? No fuck that, I got some erlanging to do!"]erlang source in gedit[/caption]

Third off, this is just to whet your whistle. Don't ignore your loved ones, squirreled away with your Beginner's Guide to Erlang because you've fallen in love with the idea of massively parallel systems. Take this time to investigate several things, learning the basics and setting up your love affair for the next few months. Then make sure you tell the people you care about that you love them and eat too much food and do people things.


For me this break will be about Rails. I've followed rails for a while, I've always been impressed with it, and I've had a few false starts. I've gone through the Getting Started tutorial more than once. I'm a php guy at my core, but learning how other people do the web is worthwhile. I've started the adventure already and think that this time it might stick. I have a 2 hour car ride up to Cleveland and back that I plan to fill with listening to Rails podcasts.




That's all for now, go relax and decompress, that's what I plan on doing for the next 4 days. As a side note I will probably not update during the holiday break so if you obsessively check or your rss feed gets lonely don't worry I will be back on the 28th.