usable in any place a human can be used

20091231

goals

[caption id="attachment_507" align="alignright" width="240" caption="you have to have goals..."]lifestyle's of the rich and famous motivational poster[/caption]

It's happened again, Jeremiah Peschka has called me out to write a blog post, well you smarmy bastard, here it is. The topic of this post is goals for 2010. Its the end of 2009 and so we have time to look back and reflect, we can also look forward and plan out the next 365 days.


Personal


These are the boring goals that don't have any computers or lasers in them, they are just things I want to accomplish for me.



  • New House - In March I will be moving into my first house with my wonderful girlfriend, Heather. I want to make this house a great place to unwind after a long day, a home filled with love, and, of course, include a badass office where I can program to my heart's content. This last part has been made much more of a reality by the recent gift from my awesome coworker, Carrie Frazier, of two giant whiteboards.

  • Health - I've been focusing a lot on interpersonal relationships and side projects in the last year which has left my once not too fat body in a condition Wii Fit calls Obese. It's been far too easy to pick up a pizza or take Heather out to eat and I have paid for it by becoming a much jigglier Matt. I plan on getting back to the healthy lifestyle I once had, and dropping some of this pizza weight.

  • Ink - Jeremiah mentioned this and so should I, it's been a few years since my last tattoo and I've had an idea for a good one for a while, I plan on getting it done at some point this year, sooner rather than later.


Coding


It's been a busy year and most of my life centers around putting fingers to keyboards trying to make something worthwhile.



  • Prosper - This is my baby that I've painstakingly carved out of php for the last few months. I think it is actually getting to the point where people could use it and not have their entire project fail, it's that good. I want to focus on improving the core of prosper, building the community, and promoting the crap out of it. The ball is rolling on having my awesome friend and fantastic designer Ashley Kruso make a new logo for prosper and at some point in the next year it will move to its own domain. I already have an upcoming event to talk about it (more details in a bit).

  • Blog - This blog started out as a free blogger account, then I moved it to my own domain (which you are currently at) and it runs off of WordPress. The design started off with the zDark WordPress theme which is now heavily modified. There are some things that I've just been too lazy about to change.


    • Better dark-on-light theme - I introduced the dark-on-light theme for people that had trouble reading the light-on-dark theme. It is very much a dirty hack, it does not retheme all the elements, and it is fairly ugly. I've had a better version cooking for some time but haven't had the drive to finish it up, I will strive to do so for the coming year.

    • Wider Columns - It's no longer 1994, we can make a fluid layout with bigger wider columns. The content column is less than 600 pixels, which is pretty absurd. I plan on reworking the layout to take advantage of larger screens while still supporting people living in 800x600 town.

    • Disqus - If you read yesterday's article you may have noticed that I ragged on Disqus as being bloated and ugly. Daniel Ha from Disqus was nice enough to drop a comment on that post and we had a very pleasant email conversation. Since this is still a feature people are asking for I will look into implementing it again, I also plan on producing a how-to for WordPress integration to document it and a review of the service.


  • Ruby - I've fallen in love a lot this year, lisp, smalltalk, and ruby have been my new technology sweethearts. I've been reading and finding ruby to be an acceptable lisp and actually a a not too bad smalltalk. Ruby, especially when coupled with rails, is something I plan on learning intimately and I hope to be able to provide some cool tools for that community.

  • Git - I've been an svn man for a long time now, but I have moved on to GitHub and have been learning the ins-and-outs of git. I am going to strive to really learn git and to work in it enough over the next year to feel as comfortable with it as I do with svn.


Business


As much fun as coding is, unless someone is paying for it you are going to get awfully hungry.



  • Black Projects - I have a few black projects that I'm working on on the side. One of which has, IMHO, great potential. Within the next year I hope to have one of these live in production and at least breaking even cash-flow wise.

  • Professional presence - See what I'm doing here typing at you, making an ass out of myself, this is called blogging. Blogging is a great way to increase your visibility and presence in the world. Now I'm not just, "That guy with the glasses who says weird things," I'm "That guy with the glasses who says weird things... on the internet." Big difference. I love blogging and I want to start giving talks in real life and become more active in user groups in the next year.

  • Relationships - This blog has already connected me to some of the nicest and smartest people I've ever met. I've been building some strong relationships and friendships, this isn't just good for business its good for one's spirit. I hope to continue this trend into the coming year.


Conclusion


This has been a fantastic year for me, first one in a while I won't be sending off with a "Goodbye Stink Town!" I'm looking forward to what 2010 will bring, if the movies of the 80's are right our jetpacks and hooker-bots aren't too far off.

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.

20091229

book review: design patterns in ruby

[caption id="attachment_62" align="alignright" width="226" caption="Go buy this now"]design patterns in ruby[/caption]

I am back from the holiday break and a perfect storm has come together, I'm currently working on a rails project, and I have a wonderful girlfriend who embraces my geekiness and buys me Design Patterns in Ruby. I have been reading this thing for the past few days and can't put it down, I wanted to read a chapter last night before bed, I sleepily set it down 5 chapters later.


Just so you understand something, although I love to read, I am a slow reader, books are hard for me to get through, I also have a ton of things to read and play around with, so you better keep my attention. I have also read the classic GoF book, so I'm coming into this book well versed in design patterns. I've played with ruby a few times before, but nothing too serious (if you look back in the archives you will see that my first post was on ruby koans).


Let's talk about this great book by Russ Olsen. The book does not require you to know anything about ruby, the first chapter is, in fact, a great primer to the language. Olsen comes from a background of 25 years of software development experience, as he puts it


I have been building software for more than 25 years. I’ve done assembly language, FORTRAN, Pascal, C, C++, Python, Java and now Ruby.
  -Russ Olsen

The introduction to ruby feels like it was written for someone with programming experience in a Java-like language. Throughout the book Olsen makes reference to the Java way to do things (which will be easy to grasp for the .Net crowd too). The primer to the language is interesting in that it skips some of the core things that makes ruby what it is (the whole meta-programming, monkey patching, message passing thing). This would seem like an oversight at first, but was helpful for me as a new ruby user. I wasn't bogged down in the different of ruby, so I could focus on the same. This let me feel comfortable with the language and focus on the patterns, as we will see, these parts missing in the primer will be fully explored later in the book.


The book is structured very much like the GoF book, with each chapter focusing on a particular pattern. Olsen opens up the chapter with some example situation, then he moves into how you could solve it with inheritance or ugly code. Then the problem is re-examined, a pattern starts to emerge, and then is described. The pattern is explained in the classic GoF style with example code (in ruby) and UML diagrams, the best part though is the clear, concise, approachable explanation provided by Olsen. The pattern now being firmly understood, the book digs into the pattern and looks at ways that we can ruby-ize it. At this point we are normally treated to some new interesting ruby language paradigm that let's us quickly and easily rewrite the pattern, making it more concise and elegant. There is then a discussion of the uses, and probably more importantly, the abuses of the pattern. Every chapter ends with a nice summary of what was learned and (as I found out last night) an enticement to keep reading as the next pattern is introduced.


[caption id="attachment_486" align="alignleft" width="240" caption="Pure unadulterated rocket sauce!"]rocket sauce[/caption]

The writing is incredibly approachable, Olsen does not get bogged down in technical jargon, he explains everything that's going on in a concise and understandable way. There are copious code examples that are excellent at providing a concrete example to the abstract pattern Olsen is discussing. The author mixes in some humor here and there and will show how other programming languages implement the patterns and historical reasoning for why things are the way they are in ruby.


The overall impression I got from this book is that it is win, condensed down into ink on paper. I have learned a ton about ruby, relearned some great patterns, and gotten a great insight on the ruby way to solve problems. If you find yourself thinking, "Well I don't need to learn design patterns, I'm so smart!" Well you are not, I'm going to use one of my favorite quotes here with a bit of a twist.


Those who don't understand design pattern are condemned to reinvent them, poorly.
  -Matt Nowack (original attribution to Henry Spencer)

Design Patterns are all around you, learning these will help you solve future problems, understand how rails works (in fact there are several occasions in the book where Olsen shows how rails uses this pattern or that one). This book is a pleasure to read, and I suspect will serve as a nice reference for implementing patterns correctly in ruby. I'm glad to have it in my toolbox, and I would suggest you get it for yourself.

20091228

modeling

[caption id="attachment_479" align="alignright" width="225" caption="Just like this, only less beautiful women and more boring data"]america's next top model[/caption]

When solving a problem the most difficult part should almost never be the implementation. Implementing a solution should be fairly straightforward from the solution itself, if it is not, then your solution is incomplete. That doesn't mean that you need to sit down with pen and paper and completely solve a problem before coding, this is an approach taken by some books attempting to teach software development. Some go as far to advocate for an even stricter approach, something along these lines.



  1. Model the problem domain with UML or some other modeling technique

  2. Translate your modeling into pseudo-code

  3. Translate pseudo-code into actual code

  4. Realize 2 month project took 2 years to complete

  5. Go to step 1 (the problem has radically changed since you took so long)


Of course, I'm poking fun at the books that take such a structured route. Here is a news flash for everyone Programmers are lazy. Here is another news flash (and this might actually be news to some people) Being lazy is good. Not all laziness is good, if it causes you to cut corners and fail to deliver a high quality product, than you fail at life. If however your laziness drives you to find an easier way to do things then "Lazy FTW!"


I have the "joy" of programming Java in my 9 to 5, when you write Java for a living you get used to the absurd amount of verbosity in your code, you also have the joy of Eclipse (notice no quotes around joy) that will write most of your Java code for you. Then there are things like Project Lombok that strive to make Java easier and more fun to write. C# got the memo, and let their programmers be lazy, let's take a look at attributes in a few languages


Here is some C# code to make a class called Foo with a string member called Bar that can be read and written
[csharp]
public class Foo {
public string Bar { get; set; }
}
[/csharp]

They realized people are lazy, let's look at the same thing in ruby


[ruby]
class Foo
attr_accessor :bar
end
[/ruby]

Again, concise and simple, let's look at some Java


[java]
public class Foo {
private string bar;

public string getBar() {
return this.bar;
}

public void setBar(string bar) {
this.bar = bar;
}
}
[/java]

Can you hear it? I can, it's the language architect saying "Just don't be so lazy, write those simple functions, it isn't hard." The truth of the matter is that it isn't hard, in fact Eclipse will happily write these functions for you, just hit CTRL-SHIFT-G. I'm sure there is a point here that I'm getting to, and here it is. I don't want to disparage Java or start a language war, what I want to point out is that Java has a different conceptual model than C# or ruby. C# has the concept of properties and ruby has the concept of attributes, Java doesn't have anything like this, classes have members and functions, nothing more.


The point is that the conceptual models your solution adopts will have huge ramifications on the implementation of the solution. There are many examples of unifying philosophies that make things simpler. Unix's concept that everything is a file, C++ concept of streams, Erlang's pervasive share-nothing message passing, ruby's duck typing. These are core concepts that have profound and far reaching consequences.


Working on a new side project I recently was struck by a way to simplify a complex data structure by adopting a new conceptual model. Creating an internally consistent, elegant conceptual model is the most important thing you can do for a project's success.


Conceptual modeling is a hard thing to get right, go into too much detail and your model becomes rigid and brittle, go into too little and the model can be impossible to implement correctly. Making a good conceptual model is like making a good analogy, there are a few hallmarks to a good conceptual model.



  • The conceptual model should simplify the problem domain. Files and folders greatly simplifies the concept of a hierarchical file system by relating it to something commonplace.

  • The conceptual model should not be overly complex to translate into an implementation

  • The conceptual model should be uniform and consistent, if you find parts of the problem domain falling outside the conceptual model or feeling "tacked on" you should rework the model


The next time a project seems stuck or overly complex, instead of refactoring code or attempting to throw another library at it, take a step back, look at the big picture and refactor your conceptual mode.

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.

20091222

early present

[caption id="attachment_468" align="alignright" width="300" caption="open source software, the gift for everyone!"]pink present[/caption]

There is an early Christmas present for anyone using prosper, a new release, Version 0.7! You can get it hot off the GitHub or download here.


Version 0.7 has a lot of exciting new features, the biggest 2 were spurred on by Ian Potter and Jeremiah Peschka. The phpDoc has been updated (if you are still using version 0.6 you can find the old documentation here). The big news is that prosper uses Prepared Statements by default now, gracefully and transparently falling back to string interpolation where Prepared Statements are not available. The second new feature is the introduction of Explicit Transaction Management.


[php]
try {
Prosper\Query::begin();

//Do a bunch of stuff

Prosper\Query::commit();
} catch (Exception $e) {
Prosper\Query::rollback();
}
[/php]

Only some of the adapters support this, the ones that do not simply ignore the call to begin(), commit(), and rollback(). You can use the has_transactions() functions to check if the current adapter supports transactions.

































































































































Database Supported by Prosper Prepared Statements Transaction Support
dBase YES NO NO
DB++ NO NO NO
FrontBase YES NO YES
filePro NO NO NO
Firebird / Interbase YES YES YES
Informix YES NO NO
IBM DB2 YES YES YES
Ingres YES YES YES
MaxDB YES YES YES
Mongo NO NO NO
mSQL YES NO NO
MS-SQL YES NO NO
MySQL YES YES YES
OCI8 (Oracle) YES YES YES
Ovrimos YES YES YES
Paradox YES NO NO
PostgreSQL YES YES NO
SQLite YES NO NO
Sybase YES NO NO
Tokyo Tyrant NO NO NO

Happy Holidays, and Happy Coding!

20091221

impedance

[caption id="attachment_456" align="alignleft" width="300" caption="you can find really cool images searching for impedance mismatch, this one has lazers (with a z)"]you can find really cool images searching for impedance mismatch, this one has lazers (with a z)[/caption]

There is a threat to good software, one that threatens the most promising of software projects. This threat is impedance mismatch. I use impedence mismatch in the sense that Object-relational impedance mismatch uses the term, but make no mistake, I'm not talking about the difficulties of writing an ORM. What I wish to discuss is far more insidious, it is death by a thousand paper cuts, it can spell ruin for any project. Impedance mismatch is born out of the confusing first steps of a project, it can also arise from multiple developers working over time on a large project or from internal disagreements over the optimal solution.


The major problem is that when we go about designing some new piece of software, some whiz-bang solution, we do not fully understand the problem domain. Any good development team will spend days filling up whiteboards with the solution that models the problem domain, but anyone with experience will tell you that once you get into the guts of a problem you realize that things need to be changed. This is fine, in fact this is a sign that you are solving the actual problem and not the ideal one you began with, don't worry about changing your solution to meet the realities of the domain. The problem though is making these changes first class citizens and not some weird third class monster thrown into the mix.


Have you ever been on a project and heard a conversation like this?



New Developer: What is X?
Grizzled Veteran: X is what we refer to internally as Y
New Developer: Why do we call it Y internally but X on the UI
Grizzled Veteran: Time constraints... budgets.... other misc. bullshit
New Developer: *mental note: X is called Y sometimes*

BAMMO! There's some nasty impedance mismatch there. The problem is not so much in what we display to the user, or what our object properties are called, or what the database columns are named, the issue is that we have made our mental model convoluted. At the heart of all these systems we build as software developers is some sort of mental model, at runtime this is expressed in system as an object graph, for persistence it is expressed as a collection of tables and relationships, but all of these things are just a representation of some mental model.


[caption id="attachment_455" align="alignright" width="300" caption="artist depiction: working with an elegant mental model"]artist depiction: working with an elegant mental model[/caption]

When our mental model is internally consistent and simple and elegant, it makes life easy and happy and unicorns shoot out of our monitors and everything is sunshine and puppies. When your mental model gets convoluted it can be an awful and bewildering experience. The problem comes from an increased overhead, instead of the mapping from one representation to the next being clear-cut, the developer has to carry around a hashmap in their skull mapping various representations of their mental model. The difficulty of carrying out even trivial tasks is increased as the mapping from X -> Y -> Z -> Q -> P takes place.


[caption id="attachment_459" align="alignleft" width="200" caption="impedance mismatch vs. coupling: battle to the death"]impedance mismatch vs. coupling: battle to the death[/caption]

So let's just name everything the same and go home, problem solved. Oh, if it could only be so easy, the problem is that on the other end from impedance mismatch is a devilish little troll named coupling. Coupling is the amount that two pieces of software are intertwined, they could be tightly-coupled wherein changing one requires changing the other, or they can be loosely-coupled all the way to the point of being considered decoupled or orthogonal. Orthogonal pieces are nice to work with because you can change one and know that you won't have side-effects on other pieces. Orthogonality goes by some other names: encapsulation, modularity, and decoupled, it is generally considered a Good Thing© and I make no argument against it.


We now have these two seemingly opposing forces, we want to decrease impedance mismatch without introducing coupling, what should we do? There are many ways to deal with this issue, let's look at a few.


Adapters are nice little pieces of code (also called wrappers), that allow two different things to look the same. Let's assume we want to write some code to manage users, users have a name, an address, and an age. The developer of the class decides that this object can be pretty simple.


[php]
class User {
public $name;
public $address;
public $age;
}
[/php]

The database developer decides that he loves structured data and that this should be broken out into all kinds of columns and tables.


[sql]
table user (
user_id int autoincrement primary key,
first_name varchar,
last_name varchar,
addr_street varchar,
addr_number int,
addr_city int foreign key,
addr_zipcode int,
age int
)

table city (
city_id int autoincrement primary key,
city_name varchar,
state_id int foreign key,
)

table state (
state_id int autoincrement primary key,
state_name varchar,
state_abbrev varchar
)
[/sql]

We could create an adapter class that bridges the difference, for brevity's sake I won't include the code for it, but it would basically translate strings into database fields, as the application developer I get to imagine the database as mirroring my object, even though it doesn't.


ORM - ORM's are like automatic adapters. They are not without their faults and some implementations are better than others, but they mask the complexity of marshaling data and reduce the impedance mismatch.


Convention over Configuration - This was made famous by Ruby on Rails. There is some strong convention that you follow that allows for a consistent mapping between domains, an example would be that tables are always named the pluralized version of the class name.


There is no silver bullet to solving the problem of impedance mismatch, but a combination of the above can help limit it. The best thing you can do is be aware of the problem, don't introduce impedance where it is unnecessary, and never be afraid to ruthlessly refactor out impedance mismatch when you find it. Keeping impedance mismatch low increases developer productivity, lowers the bar for bringing on new people, and makes unicorns leap out of your monitor farting rainbows.

20091218

flexibility

[caption id="attachment_446" align="alignright" width="247" caption="fish and grains - vital to our national prosperity"]fish and grains - vital to our national prosperity[/caption]

We all want things, things that we don't have (if we had them we wouldn't want them anymore, because we would have them). To get these things we have to exchange goods and service (this is known as the economy).


To obtain the things we want we have a few choices that we can make in life.



  1. Be born into wealth and luxury, like Paris Hilton

  2. Have your rich uncle die and write a clause in his will that you have to either take $3mil or spend $30mil to get $300mil, just like in that documentary, Brewster's Millions

  3. Through savings, wise investments, and hard work


The way that most of us people bots make our way in the world is by entering into a contract that more or less boils down to this.


I will sell you some of my time for some of your money.

Its a rather simple system, I need some money and have some sort of skill, boss man has some money and needs some sort of skill, match made in paradise. The problem is that no matter how the economy is shaped (and right now its fuck all for the employee end) the power all seems to end up in the boss man's hands, which is why he is called the boss man.


We find ourselves in this situation, called employment, and are required to do certain task, program this, sweep up that, eat this barrel of industrial sludge. As an employee it is important that we have flexibility. It's not always called flexibility, sometimes its called "being a team player," sometimes its called "taking one for the team," sometimes its called "teaming the team's teaminess" (lots of teams in this one). The idea though is the same, you are really good at X, Y is somehow (no matter how tangentially) associated with X, would you please do Y for a while? I have quoted Mitch Hedberg before and I will again, because he so eloquently makes the point.


When you’re in Hollywood and you’re a comedian, everybody wants you to do other things that are related to comedy, but are not stand-up comedy. ‘All right, you’re a stand-up comedian, can you write us a script?’ That’s not fair. That’s like if I worked hard all my life to become a really good chef, they’d say, ‘OK, you’re a chef. Can you farm?’

[caption id="attachment_448" align="alignright" width="228" caption="he\'s mocking angels now"]he's mocking angels now[/caption]

Flexibility is generally a good thing to have, it helps you get along with your coworkers, it keeps you employed, and it let's you grow as a person. The problem comes when professional flexibility bumps up against personal belief. The "would you program software that kills people" question. Would you program software that helps others kill people, would you program software that helps others disenfranchise people, would you program something you consider harmful, or wrong? Its a good question, one that most of us, myself included, have never had to ask themselves, but its one worth thinking about.


Your livelihood is wrapped up outside of your control, what is the line that you would not cross? Is there a line, do you consider yourself personally responsible for something someone else did with your creation. When does being too flexible, bending too much, become breaking yourself. I wish I could provide you some hard and fast answer, if they want to kill people with your software don't code it. What people, innocent people, death row inmates, enemy soldiers, context here is key, even then, even if it were a time machine that would go back and punch Hitler's face off (ignore the many time-space paradoxes this would lead to and the unknowable effects on the time-space continuum) could you create something for the sole purpose of destroying life. It is a question you must grapple with and come to terms, and I would suggest you find your boundary before you are forced to because you might step right by it.


I'm using extremes to make a point, but we are confronted with less extreme examples of this everyday. I run a website, should I put tracking cookies on visitors, should I contact the russian mob and let them put some insidious spywear on my site for a couple of rubles, should I go from tech blog to spam site? Luckily for you I've thought long and hard about these things before the russian mob comes to the door, horsehead in hand, threatening my kneecaps. Is it ok to sell user data, which data, when, to whom? Should I take work doing design for an adult website, or a payment gateway that processes it, or an advertising network that supports Glenn Beck? These are personal decisions we must make, and I would urge you to think about it now, know your boundaries, so that when the time comes you don't make major decisions with the glare of a big payday blinding you to your values

20091217

bing and what?

[caption id="attachment_432" align="alignright" width="300" caption="look a bird, now I\'m deciding I guess"]look a bird, now I'm deciding I guess[/caption]

I keep seeing commercials on TV, I'm sure you have to, where there is one person and another person asks them a question, the commercial then goes something like this:



  • Normal Person: Hey want to get lunch

  • Freakazoid: Lunch from the latin luncha for eating during the daytime

  • Normal Person: Huh?

  • Freakazoid: Oklahoma abbreviation OK, OOOOOOklahoma where the wind goes...

  • Normal Person: I said "huh?" not "ok?" you stupid fuck


These terrible abortions have been shoved onto the world by Microsoft to promote bing. The idea here is that using Google / Yahoo / etc. causes such a delude of useless results that querying a normal search engine is like talking to the freak from our vignette. The alternative bing is a decision engine and by using that you can "stop searching, start deciding".


First off for full disclosure, I'm not the biggest fan of Microsoft, I think they make expensive sub-par software. On the other hand though, I program in .Net and work in XP and Vista everyday, I also own a Mac and have ubuntu installed at home. I use Microsoft products, there are some that I even like, but their corporate culture and quality control bugs me. If you want to write a snarky comment about me being a linux-head or a mac-fanboy or a windoze-m$-hater, feel free to.


The whole "Decision Engine" thing is what pisses in my Corn Flakes, its such nothing market-speak. They synergized outside the box with a shifted paradigm to come up with Decision Engine. Here is the thing though, what the fuck does it mean? Does it mean that it will make decisions for me, is it a big step forward in finding stuff on the internet? So I decided to do a completely scientific comparison of bing and google.


The first step in this was searching the term "ok" as this is the most annoying example from the bing commercial. Here are my completely scientific results.










bing [caption id="attachment_434" align="alignnone" width="300" caption="bing search of ok"]bing search of ok[/caption]
google [caption id="attachment_435" align="alignnone" width="300" caption="google search of ok"]google search of ok[/caption]

Bing's first result is for Oklahoma! Think about that for a second, and now here it is again because it bears repeating, BING'S FIRST FUCKING RESULT IS THAT OK IS AN ABBREVIATION FOR FUCKING OKLAHOMA! You'd think after the commercial they would have thrown something into their indexing algorithm. Google correctly points me to a wiki article about the term "okay" before suggesting Oklahoma. But let's move past the obvious and focus on the fact that besides bing fulfilling their own prophecy, what about bing helps me decide? Nothing, they are the same page layout, they are the same thing, they do the same fucking thing.


But what is there to decide, maybe this is user error, maybe I should ask it something it could actually answer. I want chinese food for dinner, let's see what happens when I search bing and google for "chinese food near me" (note: I made sure to sign out of each so that neither would have an advantage knowing my location from an account).











bing [caption id="attachment_438" align="alignnone" width="300" caption="bing search for \"chinese food near me\""]bing search for "chinese food near me"[/caption]
google [caption id="attachment_439" align="alignnone" width="300" caption="google search for \"chinese food near me\""]google search for "chinese food near me"[/caption]

Here Google clearly wins, Bing thinks I want to know about chinese food in Maine (ME) and proceeds to tell me all about it. Google makes the same mistake but then also uses some google magic to determine that I live in Columbus, OH and provides some chinese food that is actually in this state.


I don't want this to turn into a who's better at this query or that query type thing. Let's take a step back and look at the bigger picture, bing doesn't help you decide, it is a search engine. And that's the whole point of this post, fuck your market-speak Microsoft. Don't obfuscate, innovate. If you want to take down Google go spend some of your money to design something that is actually better. Bing as it stands today is a moderately effective search engine with pretty pictures, nothing more.


There is plenty of room to innovate, there are things people could do to help me make decisions, but Bing doesn't do any of this. Search engines could start leveraging social networking information to understand the person that I am and tailor my results, they could allow the end-user to vote results up and down for a query so that the group prunes the result set, they could do some research and development and come up with something that would blow my mind.


The problem with Bing isn't that its not a good search engine, its that its not a good decision engine, its not any kind of decision engine, its a fucking search engine. Microsoft is famous for and probably makes a ton of money off of sprinkling marketing fairy dust on their shitty shitty products, so they won't stop, it just pisses me the fuck off. Stop with your dumb commercials with annoying fucks rambling like idiots because you've completely revolutionized searching and you no longer present results in a big list sorted by your concept of relevance, until you actually revolutionize searching, like Google did with their pagerank algorithm.

20091216

making a sandwich

[caption id="attachment_418" align="alignright" width="237" caption="sam waterston is getting ready to rip your still beating heart from your chest, then he's going to go do some lawyer stuff"]sam waterston is getting ready to rip your still beating heart from your chest, then he's going to go do some lawyer stuff[/caption]

Disclaimer: I am not a lawyer, I don't even pretend to be one, except after watching law & order marathons where I shout "I object!!" at people and that one time I asked my girlfriend if I could treat my dog Harvey as a hostile witness in the case of me vs. whoever pooped on the floor.


I want you to close your eyes (but don't actually because then you can't read this). Imagine a world, a terrible world much like the one we live in, but lacking a certain invention, the sandwich. A time-traveling goat went back in time to the 18th Century and decided to kick John Montagu straight in the temple before he could ever ask for "meat tucked between two pieces of bread." The world never got the grand invention of the sandwich, humanity's suffering was unbearable.


Then one day as I'm eating a large pile of cold cuts while blogging and I notice that my fingers, slick with deli meat residue, keep slipping off the keys and the hilarious and witty things I wish to share are being turned into unreadable drivel. Spying the bread I keep handy to fend off attack from a flock of pigeons, the feathered rats of the sky, I have a sudden moment of inspiration. I place some bologna between two pieces of white bread and invent, the sandwich!


Being an enterprising young man I decide that this "sandwich" I've invented is quite the big deal, I decide that I should patent it and live the rest of my days fat and happy off the profit. I write up the vaguely named "Methodology for encasement of edible substances within grain derived substrate" and submit it to the US Patent Office. Then I show family and friends alike the delicious culinary brilliance that is me and my new "sandwich" to hearty congratulations and spontaneous ticker tape parades.


Then the darkness comes, swift in the night like a badger attempting to steal your young. An evil so despised that merely typing his name brings a cold sweat to my brow and a burning desire to my punch-him-in-the-face-center of my brain. Jared Fogle.


[caption id="attachment_420" align="alignleft" width="238" caption="his evil can not be contained"]his evil can not be contained[/caption]

Mr. Fogle decides that this sandwich is big money and so takes my idea and open up a sandwich shop where people can buy a foot long sub sandwhich for $5. He begins pulling in big bucks, soon others join in on the fun and profit, Wendy's starts putting their signature square patties between buns, McDonald's hamburg style hand-steaks become "hamburgers" with the addition of a bun, even chipotle starts packing their rice and meat piles in a wrap they call a tortilla. The last straw though is one day, walking down the street, I encounter a young child skipping off to school, after roughing him up and taking his lunch, what do I find?!? A Peanut Butter & Jelly sandwich!?!?! Where is my royalty check you freckled bastard?!


"I invented the sandwich!!" I scream in my head, and then out-loud to the young lad's startled mother. With a "harumph" I head back to my home, stewing with anger. When I arrive I find a letter from the US Patent Office, after 4 long years of waiting, my patent, "Methodology for encasement of edible substances within grain derived substrate" has been approved. A low rumble of laughter begins deep in my belly and it becomes a diabolical cackle emanating with an other-worldly resonance from my maniacal grin, as I pull out my cell phone and begin to dial my lawyer.


[caption id="attachment_422" align="alignright" width="199" caption="PB & Patent Infrigement"]PB & Patent Infrigement[/caption]

The lawsuit with Mr. Fogle's Subway sandwich shop is long and arduous, but thanks to East Texas' interesting take on justice and patents, I'm awarded a $500 million settlement. Arguments abound about how there is prior work and talk of inevitable discovery. These are swept aside in a tidal wave of lawsuits, Wendy's, McDonald's, Chipotle, even that freckled young lad. I begin handing out subpoenas like Tiger Woods picks up women, anytime, anyplace (zing!). My team of high powered lawyers are figuring out ways to sue people I hadn't even dreamed of, I guess a pizza is just an open faced sandwich, sue away my pretties!


My madness grows as I become obsessed with everyone that has ever eaten a sandwich, couldn't they see my brilliance, where are my residuals!? The populace rightly decides that I am a douche bag and I'm roundly mocked on the late night circuit. This darkens my cold heart into a black pit of vengeance, sandwich vengeance. People are wary of making sandwiches at home, what liability have they opened themselves up to? No one can rightly answer, "experts" abound on the internets claiming this or that, but the murky waters are indecipherable. The Patent Office is challenged, people roundly criticize them for allowing someone to patent such a vague and wide reaching concept. They review the patent and decide that it is in fact a fine and upstanding patent, one worthy of their seal of approval.


The nightmare of a world without sandwiches has been replaced by the new nightmare of a world where I control sandwiches.




Thank goodness though that this is not the world we live in, that such insanity would never happen in this day. Oh, fuck

20091215

plain stupid

[caption id="attachment_409" align="alignright" width="136" caption="typical dumbass"]typical dumbass[/caption]

Are you a dumbass? It's an important question to ask yourself every once and a while, especially if you want people to put their trust in you. This has been brought up because of a service called RockYou that recently exposed 32,603,388 plaintext passwords. Then it got even worse when it was confirmed that RockYou was also storing 3rd party passwords, again in plaintext.


Passwords are a tricky thing to store, RockYou clearly never got the memo. I've been at this whole "writing software thing" for a while and I've gone through my own personal journey of discovery about vulnerabilities and best practices. Let's walk through that now



  • Plaintext - This is the first stage, the one that RockYou never left apparently. It is the simplest to implement, take the password, shove it in the DB. Need to check against the password, if(input == password) and done! If you don't see the problem with storing your passwords plaintext, go to the nearest hard surface and slam your head into it over and over again, you no longer need cognitive functions.

  • MD5 Hashes - This is generally the second stage of password discovery. Many languages have a nice built-in function, php does. Store that MD5 hash and you get that warm fuzzy feeling in your tummy that you aren't storing things in plaintext. The problem now is that MD5 has well known weaknesses that can be exploited. Rainbow tables provide an attack vector and reverse look-up tools opens up a ton of exposure.

  • Salty passwords.... delicious - Your users are probably going to pick awful passwords, even if you have a password policy its probably going to end up "password1" You can't rely on them to provide strong passwords, so you can do the next best thing, make it strong for them. Static salting is the act of adding predictable data to a password before hashing. Maybe you append the string "Matt~is~the~best~programmer~7829" before hashing the string. This will defeat most reverse lookup tools (as very few people have bothered hashing "Matt~is~the~best~programmer~7829password1" and putting it into a database of reverse lookups) The problem is you are still open to dictionary and rainbow table attacks. If your database is compromised there is a chance that your source could be compromised as well, and then that string sitting in some configuration file is the key that unlocks everyone's password.

  • Dynamic Salt... deliciously nerdy - Instead of having a static string you can create some dynamic salt. When a user want to store a password, generate some dynamic salt, combine it with the password, hash, mangle, and store. Now every hash is a puzzle, security in layers.

  • Non-trivial calculation times - The problem with MD5 is that its too quick. Use a more complex hashing algorithm like SHA-1 or SHA-256, perform data mangling and multiple encryption sweeps so that turning a plaintext password into a hash you store takes some non-trivial amount of computation time. What's the point of this? It may add 1 second to saving and comparing hashes for you which is normally negligible in terms of user experience. The advantage comes from defending against a brute-force attack where the attacker has to generate millions of hashes. Will Bond does an excellent job outlining this in the rational of the fCryptography class in Flourish.

  • Timeouts - The normal user will have to enter a password once maybe twice if they fat-finger it. Using a quadratic-growth timeout system can help prevent brute-force attacks, or at least slow them way down. A brute-force attack relies on the ability to quickly cycle through thousands if not millions of passwords in an attempt to find the correct one. Let's take a look at how quadratic-growth timeouts defeat this system. Each attempt has a timeout twice as much as the timeout that preceded it, we will start with a timeout value of 1 second.

    • 1st Brute-Force attempt fails server let's the person retry, but they must wait 1 second.

    • 2nd attempt fails, retry in 2 seconds.

    • 3rd attempt fails, retry in 4 seconds.

    • 4th attempt fails, retry in 8 seconds.

    • 5th attempt fails, retry in 16 seconds.

    • ...

    • 10th attempt fails, retry in 512 seconds. (8 and a halfish minutes).

    • ...

    • 20th attempt fails, retry in 524288 seconds (8738 minutes or 145 hours or 6 days)


    Most users will never experience more that 3 seconds of timeout, a cracker would have to wait 35,702,051 years to attempt 50 passwords.


Storing passwords correctly and defending against brute-force attacks is non-trivial. It's one of those things that people a lot smarter than you or I have spent a lot of time thinking about. In a former life I was a mathematician (sometimes I fancy that I still am), I have had the pleasure of picking up a book on formal cryptography, getting about 2 chapters in, and setting it down with a headache. There are a lot of great libraries out there to do this stuff for you if you are too lazy to take the time to do it right yourself.


For php there is Will Bond's fCryptography, for perl there is Crypt (I'm not a perl person so anyone is more than welcome to provide a better alternative), for any language there is normally a high quality cryptography library. If you are not using them, then you are simply being lazy.


Of course you could side-step the whole issue and let someone else do your dirty work. Its all a symptom of a problem that Mozilla Labs is trying to solve, the concept of identity on the web. I think the future will be the browser being the trusted agent instead of third-party websites, but until then we have to be responsible software developers.

20091214

web development today

[caption id="attachment_402" align="alignright" width="128" caption="the internet is so shiny these days"]the internet is so shiny these days[/caption]

I've been playing with my new iMac all weekend and am getting it set-up to start doing development. I'm a web developer by trade, but a systems developer by education. First let me give you some quick background



  • I went to BGSU where we were taught mainly C++

  • At University I worked for ResTech developing and maintaining an Intranet written in PHP

  • My current side-project is prosper a database abstraction layer written in PHP

  • After graduation I went to work for HMB


    • I've worked on 2 projects that were ASP.net

    • I slung Java for Abercrombie & Fitch for just over a year, doing some web frontend and middleware

    • Current project is doing some Java middleware



So my experiences are mostly C-style languages, but I have dabbled from time to time in other languages, ruby, python, haskell, erlang, sql (much more than I would like to with prosper), etc. Being on a new platform though makes you wonder about what makes it tick, I don't particularly have to wonder though as I read Apple's excellent documentation (PDF warning) a few years ago. My subconscious has been mulling over Objective-C development, which looks somewhat interesting, but it has brought up an old friend I was interested in a while ago Objective-J.


A while back I had heard about Cappuccino and the language that powers it, Objective-J. I remember thinking at first how crazy the whole thing was, someone didn't want to bother learning JavaScript so they found a way to make Objective-C compile down to JavaScript. This concern was assuaged some when I read this arstechnica article and realized that anyone skilled enough to write a compiler in JavaScript had to have some vague understanding of its workings. The design decisions behind making Objective-J were sound, they didn't just think my love was ugly.


I've been giving a new look at some of these new web development toolkits, platforms, libraries, etc. They promise to bring desktop quality applications to the web leveraging existing technology. And there are a few I would like to bring to everyone's attention.




    [caption id="attachment_396" align="alignright" width="150" caption="Cappuccino"]Cappuccino[/caption]

  • Cappuccino and Objective-J - Its hard to talk about one with the other. Objective-J is a brand new language for client-side scripting in the web. It compiles down to cross platform JavaScript on the client-side and is used to power cool stuff like 280slides and EnStore. One of the best things about Cappuccino and Objective-J is that they remove the burden of implementation. Is the display made up of input elements, divs, one big canvas? Don't worry about it, that's Objective-J's job to figure out the best way to display things in a given browser. Cappuccino provides a great framework to write web applications in, anyone familiar with Cocoa will feel at home. The biggest downside I can find for Objective-J is its verbosity, but maybe Atlas will help with that


  • [caption id="attachment_395" align="alignright" width="150" caption="SproutCore"]SproutCore[/caption]

  • SproutCore - SproutCore got a ton of press when Apple's MobileMe decided to use it as a foundation for their relaunch. A nod from a big player like Apple can help set aside fears that it isn't ready for primetime. Right now SproutCore is gearing up for their 1.0 release, its still in beta but they've been making great strides as of late. SproutCore is maturing quickly and has some core goals I can get behind: Be easy. Be consistent. Be opinionated. Stay small(ish). When working with SproutCore you will write code in JavaScript and also use a host of command-line tools (à la Rails).


  • [caption id="attachment_397" align="alignright" width="100" caption="GWT 2.0"]GWT 2.0[/caption]

  • Google Web Toolkit - GWT has a lot of good stuff going for it. It's made by Google (they might know a thing or two about the web), it just hit version 2.0, its the juice powering stuff like GMail and the new Google Wave. With GWT you write your code in Java which then get compiled into fast and cross-browser JavaScript. Ray Cromwell has an amazing write-up of all the new cool stuff in the 2.0 release.


All of these frameworks allow you to create a fully functioning web application without mucking with the guts of the web (HTML, CSS, JavaScript). This is a double-edged sword though.

The up side is that if you already know Objective-C or Java then your learning curve is drastically reduced. As technology changes the library can output the latest and greatest HTML without you having to change any code (hopefully). The Google Wave team has said, you can create much more complex applications leveraging the power of these frameworks.


The down side is that you are spending time and energy learning a framework and not web development. If you learn SproutCore backwards and forwards that doesn't transfer to Objective-J or GWT. The other downside of this is it introduces some magic, if you don't understand the foundations of HTML and JavaScript it can be far more difficult or impossible to fix errors. A corollary of that last point is that applications look similar, Objective-J apps look like Objective-J apps, GWT looks like GWT, it doesn't have to but when the default styling is sufficient or, as is the case with many of these frameworks, actually looks nice, its easy to just keep the default.


Web development keeps moving forward, this internet thing is going to be big. As we move more data to the cloud, as Operating Systems become more Web Centric, and as more and more of our lives our spent looking at the web, these development frameworks will become more and more important. It's an interesting time to take a look at some new takes on web development

20091211

shiny new toy

[caption id="attachment_389" align="alignright" width="214" caption="it cuts the roof of your mouth so the chemicals can get into your bloodstream faster"]it cuts the roof of your mouth so the chemicals can get into your bloodstream faster[/caption]

I took a half-day today, got to sit at home this morning waiting for the Fedex man (who turned out to be a woman). A few weeks ago I got the go ahead from my company to buy an iMac for home (HMB has a program where they will pay for half of your hardware purchase, because they are an amazing company). I got the news yesterday via fedex that my package had arrived overnight from Shanghai in beautiful Anchorage. I was told that the delivery would arrive this morning, asked for a half-day off, and this morning leisurely enjoyed a bowl of Peanut Butter Crunch.


Then I heard the thump thump thump of someone climbing the stairs outside of my apartment and a knock on my door. After subduing my dog Harvey I opened the door, signed the Fedex pad, and took a giant heavy package inside my house. The size of the box blew me away at first, here are the specs of my new iMac.



  • 27in Aluminum iMac

  • 2.8GHz Quad Core Intel Core i7

  • 8GB 1066MHz DDR3 SDRAM

  • 1TB Serial ATA Drive

  • ATI Radeon HD 4850 512MB Video Card

  • 8x double-layer SuperDrive

  • Magic Mouse

  • Wireless Keyboard


Now I have played with Macs before, I've spent countless minutes over the last month or two at BestBuy goofing around with the 27in iMac there. I thought I was prepared for how large this beast is, but I was not. It's a heavy machine and it is ginormous. The packaging was simple, effective, and beautiful. I had it up and running in about 10 minutes, and most of that time was moving stuff off my desk to make room. A little while back I had purchased a cheap opened-item (although very nice) 22in Velocity Micro Monitor (similar to this one but not identical). When I brought it home I thought it was huge, it looks Lilliputian next to this hulking behemoth.


There have been some reports of the i7 showing up DOA. I'm lucky enough to have not had this happen, my iMac is pretty and working. I turned on the power, answered some questions, and watching "Welcome" fly at my face in multiple languages for a few minutes, and it was up and running.


The Good



  • This screen is huge and beautiful, plenty of real estate to take on the job of 2 (maybe even 3) physical monitors

  • The wireless keyboard and mighty mouse were pre-synced with the computer and worked right off the bat

  • The Apple Remote synced nicely (after I reread the syncing part of the manual and saw the phrase "menu and right button" instead of just "right button")

  • I can now retire my Acer tower to be a HTPC (It's a little big but I have a cabinet it will fit nicely in)

  • The wireless keyboard is a joy to type on

  • Opened a terminal and typed ruby --version, it replied with 1.8.7 instead of " 'ruby' is not recognized as an internal or external command, operable program or batch file."

The Bad



  • After syncing my remote I couldn't get it to do anything, I tried controlling a DVD with it to no avail.

  • I only took a half day instead of the whole day off so I can't play with its beauty right now

  • I took some great pictures with my phone, but foolishly left behind my usb cable, a gallery will be posted tonight or sometime over the weekend

  • I don't know what I'm doing. This is the first Mac I've owned and so far things seem simple enough, but I'm not at home yet.


There you have it, about 2 years of thinking about buying a new iMac, a few weeks of waiting, and 4 hours off of work later I have my new shiny toy. It is a work of beauty and really a testament to the skill and care the engineers and designers at Apple put into their products. I'm hoping to avoid fanboyism though, I will be running a Vista / Ubuntu powered HTPC and working on an XP Pro laptop everyday for work.


This weekend I will get better introduced to the new member of my tech family, for now though I have to get back to work. Check in Monday for shiny pictures. I hope to do a bunch of how-to's and screencasts in the future about development on macs and setting things up if you are a developer, so stay tuned.




PS. I have changed the RSS Feed to use FeedBurner, if you experience any problems please let me know at ihumanable [at] gmail [dot] com

20091210

weakness

[caption id="attachment_375" align="alignright" width="250" caption="..who drank a soup primarily made up of Zug the Viscous..."]..who drank a soup primarily made up of Zug the Viscous...[/caption]

As I promised yesterday, today's post will be all about the question 'What is Your Biggest Weakness?' Jeremiah Peschka threw down the challenge at me, the challenge coming to him by way of Brent Ozar who himself was tagged by David Stein. This is starting to remind me a bit of the episode of Futurama where Fry becomes King by drinking the previous King, which has my all time favorite quote, "It's just like the story of the grasshopper and the octopus. All year long the grasshopper kept burying acorns for winter while the octopus mooched off his girlfriend and watched TV. Then the winter came, and the grasshopper died, and the octopus ate all his acorns and also he got a race car. Is any of this getting through to you?"


The question being posed though is What is Your Biggest Weakness? now before I answer I would like to examine this question and its prominence in hiring people. Frankly this question is bullshit, you may as well ask someone any of the following because they are about the same.



  • How well can you lie to me?

  • Are you ready to debase yourself for the promise of money?

  • I think you are fucking stupid!*


*Not technically a question

The question is a social contract we have all entered to for reasons unknown, it is like the dance we do when someone sneezes.



  1. Sneezer: *sneezes*

  2. Sneezee: Bless you

  3. Sneezer: Thank you

  4. Sneezee: You're welcome


Four steps to every sneeze, why, because we are afraid our souls are going to shoot out of our nose. No, now it has just become ingrained in the culture as the polite thing to do, even though the reason for its existence long ago stopped being relevant. I'm sure at some point in history the "What's your Biggest Weakness?" question was original and clever and useful. There were people in the world who hadn't heard it and prepared a canned answer. It was a probably a great way to see how someone thought on their feet and could wiggle out of a tough spot. That is no longer the case.


[caption id="attachment_377" align="alignleft" width="300" caption="Sometimes when I fart it smells like cinnamon rolls, that can be distracting for others"]Sometimes when I fart it smells like cinnamon rolls, that can be distracting for others[/caption]

Now this question is an insult to both the person asking and the person being asked. The person being asked knows this question exists and if they have a snowball's chance in hell of ever being employed they have an answer all cued up and ready to go. Some clever little spin on how they work too darn hard, are too much of a perfectionist, or are just too damn likeable for their own good. In that fake answer is the insult to the person asking the question, but really, they deserve it.


If you've ever answered that question with one of these fake answers, don't bother, I have your greatest weakness, you are a whore for money. And guess what people, that's my greatest weakness. When I was interviewing for my current job I recall clearly being asked that question and giving some cock-and-bull "I work too hard and am a perfectionist" line. The truth of the matter is that I'm a bit obsessive compulsive about my code, I am a bit of a perfectionist, but is that my greatest weakness, no. My greatest weakness was that I was too gutless to refuse to answer that stupid question, or too timid to respond with an actual weakness instead of some shrink-wrapped bullshit about working too hard. My greatest weakness that day was letting my fear of living on the streets eating catfood overcome the voice in my head calling out this faux question for what it is, a slap in the face to any prospective employee. I could have answered with any of a wide range of actual professional weaknesses that I have:



  • I get bored easily

  • I don't test simple fixes as thoroughly as I should

  • I don't work at consistent output, I have times when I'm incredibly productive and times when I just want to nap

  • I don't agree with most corporate culture, telling me what to wear, when to show up, how to act, is understandable, but it shows a lack of respect that I find insulting, its a rigid structure in which I am less productive not more.

  • I value my free time more than I value money which makes me a less than ideal candidate when the idea is trading time for money.

  • I like people, sometimes I'm more interested in talking to someone about code (or monkey or robots or zombies) than writing code


Those would have all been great things to say, but I didn't. I sat there with a phony smile and a phony answer, I lied and it worked. I'm hired, I've worked on several projects and they have all been successful, on-time and on-budget. I'm cognizant of these failings that I have and I think that that is my greatest strength.


If I had it to do over again I would have answered with my actual weaknesses, and then I could have spun it a bit. I know that these are the things that can derail me and potentially derail a project. I don't overlook my failings anymore, I remain conscious of them and actively work to counteract my natural tendencies. I'm aware of the fact that I don't test thoroughly the small stuff, so now when I'm pushing a small change that fact pops up and I have to ask myself, did I test this thoroughly or did I cut corners and just run it in the compiler in my brain (which is full of all kinds of bugs and edge cases). The first step to dealing with any weakness is admitting it and being aware of it, the second step is doing something about it.




I'm going to continue this game of blog tag by asking Mark Essel to respond to this question next.

20091209

pushing

[caption id="attachment_368" align="alignright" width="300" caption="cupcake dispensing button"]cupcake dispensing button[/caption]

I have been working on prosper for the last few months, I started thinking about it in early October and according to GitHub my first commit was October 22nd. This project has been great fun so far and I'm not even close to a 1.0 release yet (right now prosper is at 0.6 well on its way to 0.7). I have learned a ton on this project that I would have never guessed before I started.



I completely underestimated the amount of work prosper would be, and I don't mean coding (although coding has eaten up a large chunk of the time I normally fill with playing Borderlands). I didn't realize the amount of work it takes to manage even a small project like this. GitHub has been an amazing resource, but at the end of the day it is a tool, and you need to spend time learning how to use it and populating it with data. Writing up documentation, reading documentation, creating examples, running tests, working with collaborators, discussing technical problems, it has been a mountain of unexpected stuff. Now I'm not complaining, this was the challenge I wanted, I'm learning a ton of new stuff, making great new connections, and pushing myself in ways I never have before. One of the most important new hats I'm learning to wear is promoter


Let's say you have a great idea (like a standardized php database abstraction layer), and you decide to invest your time and energy into it. Great, you start coding like a madman and you have something working, you are working out the kinks, enjoying it, really making something worthwhile. After a while you have this project to the point where you think others might be able to use it, what do you do?



  1. It's too much work to do anything, just let the bits sit on your harddrive

  2. I need to share this with people, I'll toss it on GitHub / BitBucket / SourceForge / etc

  3. I want to promote it

  4. I'm going to get others involved


Those are the steps that I went through, and I would imagine a lot of people do, really I'm at step 2.5-ish, I created some pages within WordPress for prosper, but I plan on spinning out a standalone website for prosper at some point. The list looks easy but the problem is that you have to push yourself, because each step is costly.


To go from step 1 to step 2 you need to push past that voice in your head telling you to apply more polish. You need to push past any indecision or fear of criticism and get your code out there. The next step is to promote the crap out of your project. This step is difficult because how do you even go about it. Here are some ideas.



  • Create a sample application using your project

  • Give your project a home and shamelessly link to it

  • Promote on reddit, Hacker News, etc.

  • Get friends more famous than you to push it, if you don't have famous friends, start sending out emails, the people that I've talked to have been really great

  • Submit your project for review in any pertinent technical website (like PHP5 Magazine, which may actually be defunct)


For step 3 you have to push others, push friends, and push yourself to get your project on people's radar. Now for the next step, getting others involved. You should have created some connections and hopefully some users, enlist them to make your project the best it can be. User's can submit bugs, feature requests, and patches. Other developers can polish up bits they are interested in, as my good friend Jeremiah did. Getting more eyes and ears and noses in your project let's you refine and build, spreading complexity around.


The point of everything is that you have to push. Even great ideas, great code, great projects can fall to the wayside if no one pushes. Promoting the work you do is nearly as important as the work itself, if no one ever uses your code, no one will care about the months of effort you put into making it beautiful. Get out there and be passionate, genuine, and don't stop pushing.




Tomorrow I will be picking up the gauntlet that Jeremiah Peschka threw down today in What is Your Biggest Weakness? Tune in tomorrow to see what my biggest weakness is, and see who I challenge next.

20091208

murdering your baby


[caption id="attachment_356" align="alignnone" width="370" caption="don\'t worry, no babies were harmed"]don't worry, no babies were harmed[/caption]

Yesterday my friend Ian sent me a tweet about prosper



@ihumanable I'd be more interested in using Prosper if it provided support for true prepared statements instead of concatenating strings.
6:29 AM Dec 7th - pian0

With that my baby was born, the baby was a version of prosper that utilized prepared statements where appropriate. Prosper's main functionality has been coded for a while and the bulk of the work I've been doing as of late has been testing, improving backend support, and adding new functionality. The nice thing about this kind of work is that you don't have to go mucking around in working code, you are just fixing broken stuff and adding new functionality. The idea of adding prepared statements made me a little queasy, I had briefly looked at it when I was starting prosper but decided that they were so varied that for the first attempt I would just avoid the headache. What's the problem you ask, let's take a look at this feature table real quick.












































































































Database Supported by Prosper Can Support Prepared Statements
dBase YES NO
DB++ NO NO
FrontBase YES NO
filePro NO NO
Firebird / Interbase YES YES
Informix YES YES
IBM DB2 YES YES
Ingres YES YES
MaxDB YES YES
Mongo NO NO
mSQL YES NO
MS-SQL YES YES
MySQL YES YES
OCI8 (Oracle) YES YES
Ovrimos YES YES
Paradox YES NO
PostgreSQL YES YES
SQLite YES NO
Sybase YES NO
Tokyo Tyrant NO NO

As you can see the support for prepared statements varies in the Vendor Specific Database Extensions of php. There is also the fact that prepared statement support is poorly implemented in several extensions, they can be coded around but it adds a good deal of complexity. Despite all the reasons not to implement prepared statements, safety, speed, and correctness dictate that I should at least give it a go.


Yesterday and today were my go, and I met with some success. Prepared statements are not all that difficult to implement for a given backend, throw in some question marks, call the correct bind function, and you're off and running. The real difficulty is the cross-platform nature of prosper. I wanted prepared statements to be a first class citizen, I didn't want to decrease any existing functionality, I wanted to not overly complicate the way prosper works, and because there are 11 adapters that need to be upgraded, I wanted it to be simple to add this functionality to a given adapter.


I worked and toiled and toiled and worked, I tried hacking something up to make the MySQL adapter work, ran into the bind_results function and screamed at it for a while. Then I got out some paper and drew out some diagrams, thought about sample code. Then I went to sleep. Then I woke up and in the shower pondered the proper syntax for passing around typing information and the division of labor for transformation. Then I hacked on it some more and wrote a quick test. Then and this is the most important part I realized I had done it absolutely backwards.


I had some clues that stuff wasn't working out right, I hit a point where I would either need to embed an if statement in every function of an adapter or have a duplicate function. I thought that with some clever coding I could shove this down into the base class, it wasn't great but it was working. Then I saw another red flag when I realized that the processing in the where clause was identical to the processing in the values clause, and I applied some refactoring. This is when I realized that there was a single function that I could have modified and had the whole thing work much more elegantly.


That is when I had to come to the decision to murder my baby. I had painstakingly worked out the kinks for two days, traveling far down this road, touching a bunch of code, and now I realize the best way forward is back. The best thing I can do right now is to revert my changes to Monday morning and lose 2 days of work, and that is great!


It's not the best outcome, in an ideal world I would have seen this solution before and applied it and not wasted 2 days. The thing is that I've learned a great deal, I've come up with a much better implementation, and I've been reminded of an important lesson, never be afraid to throw away code. The code I wrote is adequate, it works well enough, but it is far from optimal. I could keep going, head down, plowing away making as many problems as I solve trying to build a house on an unsound foundation. The point here is to pay attention to those red flags.


The other important point is that sometimes you have to actually try something to find the thing that will work. You may lose some time, but even after sitting down with pencil and paper, thinking long and hard, the optimal path didn't come to me until I walked down the wrong road. That's just life sometimes as a software developer, you have to learn to live with it.


I will continue working on prepared statements for prosper, and I hope that by 0.7 or 0.8 they will be implemented and in there. I still question the syntax and think that I can clean it up, right now the plan is for prosper to support unnamed parameters (?), named parameters (:name), unnamed typed parameters (%i), and named typed parameters (:name%s), but all this seems like a little much. Good thing prosper hasn't had a 1.0 release yet ;-)