<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-5534765709337552753</id><updated>2011-07-08T16:53:17.887-04:00</updated><category term='install'/><category term='future'/><category term='ruby'/><category term='scripting'/><category term='google wave'/><category term='tools'/><category term='koans'/><category term='javascript'/><category term='erlang'/><category term='php'/><category term='anti-pattern'/><category term='gof'/><category term='programming'/><category term='development'/><category term='ccq'/><category term='free'/><category term='graphics'/><category term='teaser'/><category term='side project'/><category term='sharpening the saw'/><category term='lisp'/><category term='videogames'/><category term='ux'/><category term='open source'/><category term='neat'/><category term='recap'/><category term='ebook'/><category term='chrome'/><category term='meta'/><category term='powershell'/><category term='opinion'/><category term='analysis'/><category term='haskell'/><category term='orm'/><category term='microsoft'/><category term='windows'/><category term='design'/><category term='high-praise'/><category term='off topic'/><category term='project management'/><category term='programming languages'/><category term='learning'/><category term='rant'/><title type='text'>ihumanable</title><subtitle type='html'>usable in any place a human can be used</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://ihumanable.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5534765709337552753/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://ihumanable.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Matt Nowack</name><uri>http://www.blogger.com/profile/00930543505232276126</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='20' src='http://4.bp.blogspot.com/_8IT2c3B5vQk/SsowYFU_8QI/AAAAAAAAADE/6iO_jned-r0/S220/smiles.jpeg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>22</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-5534765709337552753.post-582458076676702194</id><published>2009-11-01T22:50:00.002-05:00</published><updated>2009-11-01T22:54:17.414-05:00</updated><title type='text'>new site</title><content type='html'>&lt;a href="http://www.ihumanable.com"&gt;&lt;h1&gt;ihumanable.com&lt;/h1&gt;&lt;/a&gt;&lt;br /&gt;
&lt;p&gt;That is my new domain, blogger has been great for getting started but now that I know I will continue blogging in a regular fashion I've decided to move to my own domain.  This blog will remain up, but I will not be updating it, for updates come on over to &lt;a href="http://www.ihumanable.com"&gt;ihumanable.com&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5534765709337552753-582458076676702194?l=ihumanable.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ihumanable.blogspot.com/feeds/582458076676702194/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ihumanable.blogspot.com/2009/11/new-site.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5534765709337552753/posts/default/582458076676702194'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5534765709337552753/posts/default/582458076676702194'/><link rel='alternate' type='text/html' href='http://ihumanable.blogspot.com/2009/11/new-site.html' title='new site'/><author><name>Matt Nowack</name><uri>http://www.blogger.com/profile/00930543505232276126</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='20' src='http://4.bp.blogspot.com/_8IT2c3B5vQk/SsowYFU_8QI/AAAAAAAAADE/6iO_jned-r0/S220/smiles.jpeg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5534765709337552753.post-839957477869628941</id><published>2009-10-30T14:06:00.006-04:00</published><updated>2009-10-30T14:52:09.729-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ux'/><category scheme='http://www.blogger.com/atom/ns#' term='neat'/><title type='text'>of mice and men</title><content type='html'>&lt;img src="http://lh6.ggpht.com/_8IT2c3B5vQk/Sus0lMSCdsI/AAAAAAAAALA/yT3WxobgVJA/s288/3689404945_a6bec29f8d.jpg" style="float: right" /&gt;
&lt;p&gt;My birthday is coming up Novemeber 14th, *wink* *wink*, and the one gift I've been angling for is a &lt;a href="http://www.daskeyboard.com/"&gt;Das Keyboard&lt;/a&gt; because I like clicky keyboards.  Growing up I had a classic IBM Model-M, the original clicky keyboard.  I'm not sure why I like the clicky keyboard, it's mostly in my head I'm sure, I feel more productive if I'm making a tremendous amount of noise I guess... maybe that's why I talk so much.&lt;/p&gt;
&lt;p&gt;What it comes down to though is feedback.  Computers are these amazingly pliable machines, I can play a game of solitaire, balance my checkbook, and write a blog post all on the same machine.  It's one of those amazing things that has sadly become commonplace, so much so that we barely think anything about it anymore.  This is sad because it's kind of a big deal, take a modern computer back in time 100 years and watch people flip out.&lt;/p&gt;
&lt;p&gt;We often think about the User Interface that we see on the screen, but rarely do we consider the Physical Interface that we have with the computer itself, mainly the keyboard and mouse.  There is one company though that continues to push the envelope, Apple.  Look at their new &lt;a href="http://www.apple.com/magicmouse/"&gt;Magic Mouse&lt;/a&gt;, think that chiclet style keyboards are neat, Apple did it first, multitouch &lt;a href="http://www.apple.com/iphone/"&gt;you're welcome&lt;/a&gt;.  This is not an Apple lovefest (all evidence to the contrary), their products work really nicely but that's not the point, they spur others to innovate as well, that's the important part.&lt;/p&gt;
&lt;p&gt;So suddenly there is a resurgence in thinking about how we physically interact with computers, &lt;a href="http://gizmodo.com/5365299/courier-first-details-of-microsofts-secret-tablet"&gt;look what Microsoft is doing&lt;/a&gt;.  There is a cornucopia of rumors flying around about a speculative &lt;a href="http://gizmodo.com/tag/apple-tablet"&gt;Apple Tablet&lt;/a&gt;.  And this means really cool interesting gadgets and ideas are now getting the funding to take them from scribbles on a napkin to sketches on a whiteboard to mockup videos to prototypes and then maybe if they hold out to market.&lt;/p&gt;
&lt;p&gt;Then I encountered a video a few weeks ago that was so brilliant, so full of potential, that I just wanted to learn as much as possible about it, &lt;a href="http://10gui.com/"&gt;10/GUI&lt;/a&gt;.  Don't take my word for it, check this thing out.&lt;/p&gt;
&lt;div class="embed-wrap"&gt;
&lt;object width="400" height="220"&gt;&lt;param name="allowfullscreen" value="true" /&gt;&lt;param name="allowscriptaccess" value="always" /&gt;&lt;param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id=6712657&amp;amp;server=vimeo.com&amp;amp;show_title=1&amp;amp;show_byline=1&amp;amp;show_portrait=0&amp;amp;color=00ADEF&amp;amp;fullscreen=1" /&gt;&lt;embed src="http://vimeo.com/moogaloop.swf?clip_id=6712657&amp;amp;server=vimeo.com&amp;amp;show_title=1&amp;amp;show_byline=1&amp;amp;show_portrait=0&amp;amp;color=00ADEF&amp;amp;fullscreen=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="400" height="220"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;p&gt;&lt;a href="http://vimeo.com/6712657"&gt;10/GUI&lt;/a&gt; from &lt;a href="http://vimeo.com/user1415432"&gt;C. Miller&lt;/a&gt; on &lt;a href="http://vimeo.com"&gt;Vimeo&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Pretty neat, huh?  There are definitely things some people might not like or want to change, but it is an intriguing idea.  With proper funding and research it could turn into something awesome.  The problem is that you still have to transition between a 10/GUI touch surface and a keyboard, not a huge deal, but once I saw &lt;a href="http://www.appleinsider.com/articles/09/10/01/evidence_of_apples_tablet_like_input_interface_reappears.html"&gt;this&lt;/a&gt; my mind was set ablaze with visions of a seamless 10/GUI interface.  If you don't want to read that whole page, here is the important part.&lt;/p&gt;
&lt;blockquote&gt;
The described system in the patent application would individually detect all ten fingers and separate palms on a person's hand, giving the ability to type, write, draw and interact with a device large enough to support multiple hands. 
&lt;br /&gt;...&lt;br /&gt;
Typing is a large part of the lengthy application. The document goes into great detail about how a multi-touch interface could distinguish what keys a set of hands intend to type on the surface. It discusses pressure on the sides or center of individual fingers and palms, and how to interpret those various signals.
&lt;/blockquote&gt;
&lt;p&gt;The major problem to overcome is feedback, a system that automatically tracks your palms and places the keys under it could allow for touch typing, but as someone who types all day, I don't know if it could work without feedback.  This is what they said about the iPhone onscreen soft keyboard, but reports are that people can type anywhere from 40-60 wpm after adjusting.&lt;/p&gt;
&lt;p&gt;I'm not sure what the future of the Physical Interface between the user and computer will be, but its definitely an interesting thing to ponder about.  Will we have a &lt;a href="http://flowingdata.com/2008/11/17/minority-report-physical-interface-in-real-life-oblong-g-speak/"&gt;minority report like 3D interface&lt;/a&gt; or a neat &lt;a href="http://10gui.com/"&gt;10/GUI pad&lt;/a&gt; or the tried and true keyboard and mouse or something that hasn't made it off the scribbled on a napkin phase yet.  It sure will be exciting to find out though.&lt;/p&gt;
&lt;em&gt;I plan on moving this blog to my own domain over the weekend, but never fear I will keep everyone informed on the move and where you can always get your daily dose of my crazyness&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5534765709337552753-839957477869628941?l=ihumanable.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ihumanable.blogspot.com/feeds/839957477869628941/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ihumanable.blogspot.com/2009/10/of-mice-and-men.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5534765709337552753/posts/default/839957477869628941'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5534765709337552753/posts/default/839957477869628941'/><link rel='alternate' type='text/html' href='http://ihumanable.blogspot.com/2009/10/of-mice-and-men.html' title='of mice and men'/><author><name>Matt Nowack</name><uri>http://www.blogger.com/profile/00930543505232276126</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='20' src='http://4.bp.blogspot.com/_8IT2c3B5vQk/SsowYFU_8QI/AAAAAAAAADE/6iO_jned-r0/S220/smiles.jpeg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh6.ggpht.com/_8IT2c3B5vQk/Sus0lMSCdsI/AAAAAAAAALA/yT3WxobgVJA/s72-c/3689404945_a6bec29f8d.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5534765709337552753.post-8574980174184333930</id><published>2009-10-29T14:34:00.006-04:00</published><updated>2009-10-29T15:24:04.568-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='teaser'/><category scheme='http://www.blogger.com/atom/ns#' term='orm'/><category scheme='http://www.blogger.com/atom/ns#' term='php'/><category scheme='http://www.blogger.com/atom/ns#' term='side project'/><title type='text'>orm and sql</title><content type='html'>&lt;p&gt;I've been working on a side project in earnest lately.  It's all kinds of PHP fun and I'm enjoying learning the ins and outs of PHP 5.3 as well as relearning some of the stuff I already knew about from my PHP glory days.  I've been looking at various different ORM solutions to use with my project and I'd like to take some time to review them, explain why I chose none of them, and what I'm doing instead.  For the non-technical in the audience, ORM stands for Object-Relational Mapper, its a piece of software that allows you to save parts of your program to and load them back from a database, supposedly quickly and easily.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.doctrine-project.org/"&gt;&lt;img src="http://lh3.ggpht.com/_8IT2c3B5vQk/SunrTz-OO2I/AAAAAAAAAK8/8-k7kB4RQgA/s800/hometopbg.png" style="float: right" /&gt;&lt;/a&gt;&lt;a href="http://www.doctrine-project.org/"&gt;Doctrine&lt;/a&gt;&lt;br /&gt;Doctrine is the 800-pound gorilla of PHP ORM solutions, it has it all, and then some.  It is an ORM  sitting on top of a DBAL (Database Abstraction Layer) which leverages its own query language DQL (Doctrine Query Language).  It can be configured in any number of ways, supports all kinds of backends, is mature, stable, and feature rich.  That's all the good of Doctrine, the bad is the learning curve.  The manual for Doctrine is &lt;em&gt;&lt;strong&gt;30 sections long&lt;/strong&gt;&lt;/em&gt;, each section is quite a bit to take in.  This is great if you are doing an enterprise level program, but for my project Doctrine was overkill.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://flourishlib.com/"&gt;&lt;img src="http://lh6.ggpht.com/_8IT2c3B5vQk/StKiBU4mx5I/AAAAAAAAAFo/mlC6D__hucQ/s144/flourish.gif" style="float: right" /&gt;&lt;/a&gt;&lt;a href="http://flourishlib.com/"&gt;Flourish Lib&lt;/a&gt;&lt;br /&gt;This is not an ORM solution, although it does contain one.  Flourish is an unframework, and a really, really good one at that.  If you want to shut someone up who says you can't write good code in PHP, send them to Flourish, the creator Will Bond did a tremendous job with this unframework, and I still plan on using large parts of it.  The ORM layer is actually really nice, there is a bit of a learning curve, and at the end of the day I decided that it did too much and polluted my models too much.  Flourish though is definitely worth learning, the website also has great best practices to follow if you are building a PHP Web Application.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.phpactiverecord.org/"&gt;&lt;img src="http://lh6.ggpht.com/_8IT2c3B5vQk/StKiBbbqcfI/AAAAAAAAAFs/K8Tw0wGOnQI/s144/phpactiverecord.png" style="float: right" /&gt;&lt;/a&gt;&lt;a href="http://www.phpactiverecord.org/"&gt;php.activerecord&lt;/a&gt;&lt;br /&gt;Based off of the widely successful Ruby on Rails ActiveRecord class, this project aims to bring the ease of Rails database interactions to PHP.  It does not attempt to be a PHP on Rails framework, there are plenty of those, its just a great implementation of the ActiveRecord pattern.  The documentation is also fantastic, covering the essentials and letting you jump right in, it feels like there is no learning curve at all.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.redbeanphp.com/"&gt;&lt;img src="http://lh6.ggpht.com/_8IT2c3B5vQk/SunoWqVyS9I/AAAAAAAAAK0/sd9-9yn6rfM/s800/beanlogo_med.gif" style="float: right" /&gt;&lt;/a&gt;&lt;a href="http://www.redbeanphp.com/"&gt;RedBean&lt;/a&gt;&lt;br /&gt;This is a complete departure from normal ORM solutions.  In a normal solution you are cognizant of both the object model and the relational model, the ORM acts as a pleasant interface for interactions.  In RedBean you are freed from having to know about the relational model, in fact you are allowed to let the relational model change on the fly.  Need a new attribute for that object, don't worry about migrating schemas, just slap it in there and let RedBean figure out the rest.  It is definitely an interesting idea, and it is maturing quickly, but I was wary of using it because of the overly fluid nature and the business constraints of my project&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Those are the most interesting ones I investigated, I investigated quite a few other ones, but these were definitely the cream of the crop.  None of them fit my project, but my project is a little bit weird (if you keep reading this blog you will no doubt see it one day, unless something shiny grabs my attention and I wonder off).  If you are looking for a really powerful ORM with all the bells and whistles, check out Doctrine.  If you are familiar with ActiveRecord, php.activerecord is a fantastic implementation.  If you are programming PHP at all, take the time to read through Will Bond's amazing Flourish Lib.  If you need some lightweight persistence or want to dabble in some object-oriented databases, give RedBean a try.  Really on that last one, if you are even at all interested by technology, check out RedBean, it is a little young but shows amazing potential and is a great example of thinking outside the box.&lt;/p&gt;
&lt;p&gt;So what did I decide, well I decided I don't want to use an ORM layer.  ORM didn't fit my use case, I was only experiencing developer pain trying to shoehorn it in there.  I decided that what I needed was something a little different, and I'm currently developing exactly that.  So what is this mystery project that I'm working on, its a couple different parts that work together, but I decided that all I really wanted was the following list of things.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Cross platform SQL&lt;/li&gt;
&lt;li&gt;Automatic CRUD&lt;/li&gt;
&lt;li&gt;Lightweight library&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So I'm writing them, and I will be releasing at least part of it soon, once I get it to a point where it does something, then expect a blog post with trumpets and whatnot.  I conceived the project structure last night and began coding, I was able to put in 3 hours of work and got a very nice proof of concept running, but it is still all sharp edges and scuffed surfaces.&lt;/p&gt;
&lt;p&gt;Stay tuned though, I hope to have something people can put their fingers on soon.  I think there is a need for the lightweight components that I'm building, as a platform for future innovation and because after 3 months of looking around I couldn't find anything out there that did what I needed.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5534765709337552753-8574980174184333930?l=ihumanable.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ihumanable.blogspot.com/feeds/8574980174184333930/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ihumanable.blogspot.com/2009/10/orm-and-sql.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5534765709337552753/posts/default/8574980174184333930'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5534765709337552753/posts/default/8574980174184333930'/><link rel='alternate' type='text/html' href='http://ihumanable.blogspot.com/2009/10/orm-and-sql.html' title='orm and sql'/><author><name>Matt Nowack</name><uri>http://www.blogger.com/profile/00930543505232276126</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='20' src='http://4.bp.blogspot.com/_8IT2c3B5vQk/SsowYFU_8QI/AAAAAAAAADE/6iO_jned-r0/S220/smiles.jpeg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh3.ggpht.com/_8IT2c3B5vQk/SunrTz-OO2I/AAAAAAAAAK8/8-k7kB4RQgA/s72-c/hometopbg.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5534765709337552753.post-7379684060324280675</id><published>2009-10-28T14:27:00.007-04:00</published><updated>2009-10-28T15:03:45.764-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='rant'/><category scheme='http://www.blogger.com/atom/ns#' term='development'/><category scheme='http://www.blogger.com/atom/ns#' term='learning'/><title type='text'>related tasks</title><content type='html'>&lt;p&gt;I remember watching Mitch Hedburg one time talk about how comedy is an odd kind of profession because if you are really good at it you have to stop doing it.  The point he was making is that if you are successful enough at stand-up then one day people are going to ask you if you can act and write and star in movies.  Here is the pertinent quote.&lt;/p&gt;
&lt;blockquote&gt;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?’&lt;/blockquote&gt;
&lt;p&gt;This is a less severe version of the &lt;a href="the http://en.wikipedia.org/wiki/Peter_Principle"&gt;Peter Principle&lt;/a&gt;.&lt;/p&gt;
&lt;img src="http://lh5.ggpht.com/_8IT2c3B5vQk/SuiUhZvTTpI/AAAAAAAAAKs/sF3htSAVfpw/s800/12169049_dcbed568fe_m.jpg" style="float: right" /&gt;
&lt;p&gt;But it's not just comedians, Software Development has a whole host of secondary tasks that are related, sometimes closely, sometimes not so closely, that need to be taken care of.  I've found myself in a secondary task day the last few days.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;New client conference call&lt;/li&gt;
&lt;li&gt;Functional Specification examination and inquiry&lt;/li&gt;
&lt;li&gt;Task list creation and time estimates&lt;/li&gt;
&lt;li&gt;Talking to a hosting company about plan upgrades&lt;/li&gt;
&lt;li&gt;Researching a fix for PCI non-compliance issue&lt;/li&gt;
&lt;li&gt;Researching why in the hell IIS6 wouldn't serve .aspx pages (&lt;a href="http://support.microsoft.com/kb/315122"&gt;Web Service Extension wasn't permitted&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Fighting with a dev environment to get an application running to test whether or not a PCI Compliance fix would break the application&lt;/li&gt;
&lt;li&gt;Taking a break from fighting with the maddening server to write a blog post&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These secondary tasks are all necessary, some are enjoyable (blogging), some I'm surprisingly skilled at (research, talking), some make me feel completely out of my element (time estimates, server configuration).  In the landmark &lt;a href="http://www.joelonsoftware.com/articles/LeakyAbstractions.html"&gt;The Law of Leaky Abstractions&lt;/a&gt; and the follow up &lt;a href="http://www.joelonsoftware.com/articles/DevelopmentAbstraction.html"&gt;The Development Abstraction&lt;/a&gt;, Joel writes&lt;/p&gt;
&lt;blockquote&gt;Any successful software company is going to consist of a thin layer of developers, creating software, spread across the top of a big abstract administrative organization.

The abstraction exists solely to create the illusion that the daily activities of a programmer (design and writing code, checking in code, debugging, etc.) are all that it takes to create software products and bring them to market. &lt;/blockquote&gt;
&lt;p&gt;Its not that I don't want to perform these secondary tasks, or that I'm not good at them, it's just that I'm much more productive at coding.  My brain is set up for it, ask anyone that knows me, I think about life as one big program, I examine my emotions based off of function arguments, I turn situations into class hierarchies, it's just how my brain works.  Programming makes sense to me, I feel at home there, I feel warm and cuddly wrapped in curly braces, and I work really well there.&lt;/p&gt;
&lt;p&gt;These secondary tasks, related tasks, need to get done, and because of my availability I'm the one to do them.  It's good to learn new things, but also scary and uncomfortable and frustrating.&lt;/p&gt;
&lt;p&gt;I don't know if there is a point to writing this, it started off as a rant against feeling forced to waste my time and skills on tasks that I don't feel comfortable doing, but it hasn't ended there.  It hasn't really ended anywhere, it's a reality, so I'll deal.&lt;/p&gt;
&lt;p&gt;All I know is that right now the abstraction is leaking and getting my clothes wet, I long to wrap myself in comfy curly braces by a warm fire and feel like I know what I'm doing again.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5534765709337552753-7379684060324280675?l=ihumanable.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ihumanable.blogspot.com/feeds/7379684060324280675/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ihumanable.blogspot.com/2009/10/related-tasks.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5534765709337552753/posts/default/7379684060324280675'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5534765709337552753/posts/default/7379684060324280675'/><link rel='alternate' type='text/html' href='http://ihumanable.blogspot.com/2009/10/related-tasks.html' title='related tasks'/><author><name>Matt Nowack</name><uri>http://www.blogger.com/profile/00930543505232276126</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='20' src='http://4.bp.blogspot.com/_8IT2c3B5vQk/SsowYFU_8QI/AAAAAAAAADE/6iO_jned-r0/S220/smiles.jpeg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh5.ggpht.com/_8IT2c3B5vQk/SuiUhZvTTpI/AAAAAAAAAKs/sF3htSAVfpw/s72-c/12169049_dcbed568fe_m.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5534765709337552753.post-8007162627249030398</id><published>2009-10-27T14:02:00.002-04:00</published><updated>2009-10-27T16:17:00.733-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='install'/><category scheme='http://www.blogger.com/atom/ns#' term='high-praise'/><title type='text'>installation</title><content type='html'>&lt;p&gt;Today at work I had the joyful experience of installing WordPress on my development machine.  My 9-5 is working in the .Net arena so my machine is set up with IIS 7, MSSQL 2008, Visual Studio 2008, a cutting edge Microsoft stack.  So when I was told to install WordPress to do some testing, I knew I would have to install a LAMP stack (minus the L) and then the WordPress software, I prepared myself to do battle.&lt;/p&gt;
&lt;p&gt;Actually I had the feeling that this would be pretty easy, I use to work in LAMP and MAMP and WAMP stacks all day long so I could at least skip over the, "how the hell do I start?" phase and jump in head first.&lt;/p&gt;
&lt;img src="http://lh6.ggpht.com/_8IT2c3B5vQk/SudPEDeO3bI/AAAAAAAAAKk/g_RTTk_pJOU/s800/1240.jpg.gif" style="float: right" /&gt;
&lt;p&gt;I headed over to &lt;a href="http://www.apachefriends.org/en/xampp.html"&gt;XAMPP&lt;/a&gt; and grabbed the latest Windows installer.  44 megabytes later I double clicked, selected my destination directory, C:\ (XAMPP automatically makes a folder called xampp to put itself in, I've made this mistake more than once and ended up with my install in C:\xampp\xampp), and clicked install.  It churned and churned and I took the opportunity to grab a Diet Dr. Pepper.  5 minutes later I had a fully functional WAMP machine at my fingertips.&lt;/p&gt;
&lt;p&gt;I double-clicked the XAMPP Control Panel icon and fired up Apache and MySql, clicked the Admin button and was whisked away to http://localhost/.  After some security configuration, clicked security, entered a password, simple enough, I turned my sights on WordPress.&lt;/p&gt;
&lt;img src="http://lh4.ggpht.com/_8IT2c3B5vQk/SudTQc2vowI/AAAAAAAAAKo/Glgm6_wurFI/s144/wordpress.png" style="float: left" /&gt;
&lt;p&gt;I pointed my web browser at the &lt;a href="http://wordpress.org/download/"&gt;WordPress Download Page&lt;/a&gt; grabbed the zip and clicked through to the &lt;a href="http://codex.wordpress.org/Installing_WordPress"&gt;handy guide&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The &lt;a href="http://codex.wordpress.org/Installing_WordPress"&gt;handy guide&lt;/a&gt; lived up to its name, especially the &lt;a href="http://codex.wordpress.org/Installing_WordPress#Famous_5-Minute_Install"&gt;Famous 5-Minute Install&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;In about 15 minutes I was able to painlessly install Apache, MySQL, PHP, Perl, and WordPress.  It cost me nothing, and it all just seamlessly worked.  In short it was the model install experience.&lt;/p&gt;
&lt;p&gt;Installation can be easy to overlook, you write your app coding and coding away and you never think about getting it set-up.  What often makes it worse is that as programmers we normally don't think much of complicated tasks or dialogs that would scare the average user.  Installation is your software's first impression, and you know what they say about first impressions, try not to be a jackass.&lt;/p&gt;
&lt;p&gt;When installations work right you should feel more and more comfortable as you follow the steps, WordPress is a great example.  Every step I could see more and more of WordPress shining through, it didn't just work, it was intuitive and actually made me want to use it.  Every step assured me that I had done the right thing and helpfully pointed me to the most important things to know for the next step.  There was no technical jargon, just do exactly this, type here, click here, enjoy!  It was short, simple, and sublime.&lt;/p&gt;
&lt;p&gt;So in this world of web applications where we no longer think about installation, if you are going to make your end-user install something, make sure that you do the following&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Provide plenty of &lt;strong&gt;up-to-date&lt;/strong&gt; documentation&lt;/li&gt;
&lt;li&gt;Make the process as simple as possible&lt;/li&gt;
&lt;li&gt;Provide feedback, both positive and negative&lt;/li&gt;
&lt;li&gt;Centralize your installation process&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Follow this advice and someday someone will write a blog post about how much of a joy it was to install your software.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5534765709337552753-8007162627249030398?l=ihumanable.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ihumanable.blogspot.com/feeds/8007162627249030398/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ihumanable.blogspot.com/2009/10/installation.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5534765709337552753/posts/default/8007162627249030398'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5534765709337552753/posts/default/8007162627249030398'/><link rel='alternate' type='text/html' href='http://ihumanable.blogspot.com/2009/10/installation.html' title='installation'/><author><name>Matt Nowack</name><uri>http://www.blogger.com/profile/00930543505232276126</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='20' src='http://4.bp.blogspot.com/_8IT2c3B5vQk/SsowYFU_8QI/AAAAAAAAADE/6iO_jned-r0/S220/smiles.jpeg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh6.ggpht.com/_8IT2c3B5vQk/SudPEDeO3bI/AAAAAAAAAKk/g_RTTk_pJOU/s72-c/1240.jpg.gif' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5534765709337552753.post-801504998548832669</id><published>2009-10-26T13:16:00.008-04:00</published><updated>2009-10-26T14:42:19.304-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='future'/><category scheme='http://www.blogger.com/atom/ns#' term='videogames'/><category scheme='http://www.blogger.com/atom/ns#' term='off topic'/><title type='text'>motion controls and ai</title><content type='html'>&lt;p&gt;I was talking with a friend today about dj hero (which comes out later today) and he asked a simple question, "Have you heard anything about the next wave of game systems?"  I read all kinds of electronics blogs like &lt;a href="http://gizmodo.com"&gt;Gizmodo&lt;/a&gt;, &lt;a href="http://engadget.com"&gt;Engadget&lt;/a&gt;, and even &lt;a href="http://news.ycombinator.com"&gt;Hacker News&lt;/a&gt; and haven't seen anything about a PS4 or a Xbox720.&lt;/p&gt;
&lt;p&gt;The &lt;a href="http://en.wikipedia.org/wiki/PlayStation_3"&gt;PS3&lt;/a&gt; was released on November 17, 2006, the &lt;a href="http://en.wikipedia.org/wiki/Xbox_360"&gt;Xbox 360&lt;/a&gt; on May 12, 2005.  So we are looking at about 3 or 4 years since the last generation, considering that the PS2 and original Xbox launched in 2000 and 2001, respectively, means that we may not see anything for a little while longer.  But the weird thing is that there is no chatter, no rumors about the next-gen consoles, and I got to wondering why.&lt;/p&gt;
&lt;p&gt;You may have noticed above that I left someone out, &lt;a href="http://en.wikipedia.org/wiki/Wii"&gt;Nintendo's Wii&lt;/a&gt;.  Hold on, don't get your Mario shaped pitch-forks out yet, I would argue that the Wii is what is causing the current drought in next-gen systems.  The old logic of producing a next-gen system was as follows&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Release system&lt;/li&gt;
&lt;li&gt;Make giant profits&lt;/li&gt;
&lt;li&gt;Wait for Moore's law to create more powerful hardware&lt;/li&gt;
&lt;li&gt;Put more powerful hardware in box&lt;/li&gt;
&lt;li&gt;Increment number after system name&lt;/li&gt;
&lt;li&gt;Brag about polygon count&lt;/li&gt;
&lt;li&gt;Goto step 1&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The problem is 2 fold though.  The first problem is that we are approaching the uncanny valley, possible even stuck in it.  Have you seen the games little kids get to play these days, they are gorgeous, expansive, photo-realistic dream worlds. Let's compare and contrast&lt;/p&gt;
&lt;div class="embed-wrap"&gt;
&lt;div style="padding-bottom: 10px"&gt;
&lt;img src="http://lh6.ggpht.com/_8IT2c3B5vQk/SuXdhf-vGAI/AAAAAAAAAKA/0EqdzBCXPqE/s800/mario-screen.jpg" /&gt;&lt;br /&gt;&lt;em&gt;Super Mario (NES)&lt;/em&gt;
&lt;/div&gt;
&lt;div style="padding-bottom: 10px"&gt;
&lt;img src="http://lh6.ggpht.com/_8IT2c3B5vQk/SuXdhb_jmQI/AAAAAAAAAKE/wVQBUOdZW6U/s288/gears-screen.jpg" /&gt;&lt;br /&gt;&lt;em&gt;Gears of War (Xbox 360)&lt;/em&gt;
&lt;/div&gt;
&lt;div style="padding-bottom: 10px"&gt;
&lt;img src="http://lh5.ggpht.com/_8IT2c3B5vQk/SuXdg_-82EI/AAAAAAAAAJ8/k7EfGm4qE9E/s288/carbon-screen.png" /&gt;&lt;br /&gt;&lt;em&gt;Need for Speed: Carbon (PS3)&lt;/em&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Pumping out more polygons isn't really an issue anymore, we have reached the land of diminishing returns.  So the idea of just putting out a more powerful machine isn't really going to get most people off of the couches and out in the stores.&lt;/p&gt;
&lt;img src="http://lh5.ggpht.com/_8IT2c3B5vQk/SuXfVmxtmgI/AAAAAAAAAKI/tsv5TZHIYpg/s800/wii360ps3.jpg" style="float: right" /&gt;
&lt;p&gt;The second issue is that Nintendo totally messed everything up, they put out a system that was just about the same power, had some weird remote control thing, and they &lt;strong&gt;DOMINATED&lt;/strong&gt; the market.  This decimated the conventional wisdom, you can't put something out that isn't more powerful and have people buy it, what's happening!?!?  This can't be happening, deep breaths everyone, Bill Gates just threw up.  The news talked about it nonstop, people were selling Wiis for a ton on ebay, the holiday season saw more than its fair share of customers fighting, waiting, and pleading for the hottest new video game system, the Wii.  And its actually pretty fun, I've played Wii Sports Resort with my brother for hours on end, kicking his ass at frisbee golf.&lt;/p&gt;
&lt;p&gt;Immediately though, people had to know, what is the secret sauce of their success, it must be that goofy remote.  Sony quickly tried to slap some motion sensing into their sixaxis controller, with &lt;a href="http://en.wikipedia.org/wiki/Lair_%28video_game%29#Reception"&gt;terrible results&lt;/a&gt;.  Well now both big players have gone back to the drawing board to make some motion sensing controls.&lt;/p&gt;
&lt;p&gt;Microsoft's &lt;a href="http://www.xbox.com/en-US/live/projectnatal/"&gt;Project Natal&lt;/a&gt;&lt;/p&gt;
&lt;div class="embed-wrap"&gt;
&lt;object width="560" height="340"&gt;&lt;param name="movie" value="http://www.youtube.com/v/p2qlHoxPioM&amp;hl=en&amp;fs=1&amp;"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/p2qlHoxPioM&amp;hl=en&amp;fs=1&amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="560" height="340"&gt;&lt;/embed&gt;&lt;/object&gt;
&lt;/div&gt;
&lt;p&gt;Sony's motion sensing wand thing&lt;/p&gt;
&lt;div class="embed-wrap"&gt;
&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/RKXWGHBkHjc&amp;hl=en&amp;fs=1&amp;"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/RKXWGHBkHjc&amp;hl=en&amp;fs=1&amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;
&lt;/div&gt;
&lt;p&gt;Everyone has decided that motion controls are going to be a big part of the future of gaming.  The problem is that motion controls have inherent flaws that all the sensitivity and one to one motion sensing in the world can't fix.  Motion controls fail in 2 important ways, the first is that motion controls only make sense for certain activities, bowling, frisbee, sword play, gun fights, all can be done nicely with motion controls.  But have you ever played a Wii game where the motion controls are tacked on (95%) or confusing (90%) or annoying (90%) or the wiimote is turned into a glorified mouse pointer.  If not then you have never played anything but the AAA titles, and that's fine, that's why we have AAA titles, because they are good.   They represent a tiny fraction of all games on the Wii though, the vast majority of what's out there was pumped out to cash in on a phenomenon, with motion controls thrown in for good measure, and normally to the detriment of the game.&lt;/p&gt;
&lt;p&gt;The prime example in my mind is the Ghostbuster Wii port, a serviceable enough game, but the annoying swinging and shaking and quick-time event motion controls for every single ghost get annoying and unnecessary.&lt;/p&gt;
&lt;p&gt;The second problem is that motion controls is a concept that is at odds against itself.  On one hand your body is supposed to become an extension of the controller, you should be able to blur the line (in your mind's eye) between your actions in real life and the actions on the screen.  The problem is that there is no force feedback, when your sword blow is parried by a wily electronic foe, your arms keeps going but the character's arm on the screen stops.  There is no resistance as you shop through a tree, there is no physical feedback for the motion you are making.  The fantasy world where you are the brave knight bravely trying to rescue the beautiful princess comes crashing down around you when you and your characters movements become out of sync, and suddenly you are back in your living room in your sweatpants swinging a remote like a jackass.&lt;/p&gt;
&lt;p&gt;The Wii was successful because they marketed their machine to the casual gamer, this great untapped resource, and they had a great novelty to get their foot in the door.  And it worked, and I will admit that the well made games on the Wii are a hell of a lot of fun, and I do enjoy the little system that could.  The point of this post is not to rag on the Wii but to say that it succeeded in spite of the wiimote not because of it, and the new adventure down motion control road will end up being a blind alley.&lt;/p&gt;
&lt;p&gt;So where does this leave us, what is the future of gaming?  I don't know for certain, but I will finish up with what I would like to see.  Improvements in Artificial Intelligence.  Artificial Intelligence's capabilities were over promised and underwhelming, this has led to &lt;a href="http://en.wikipedia.org/wiki/AI_winter"&gt;AI Winter&lt;/a&gt;.  Most people today think that there is something fundamental about AI that it could never work, that the best we can make is not very good at all.  And that really is the state of most AI today, especially game AI.  When was the last time the game gave you AI teammates and you thought to yourself, "Yea, AI Teammates!" instead of "I wonder if I will lose points for murdering them."  Not very often I bet, because AI is horrible, its even worse when its trying to help you.  If Sony and Microsoft spent some serious money on developing an AI framework for their developers to use, they could make the games much more fun.&lt;/p&gt;
&lt;p&gt;How do I know it would be more fun, look at the rise of MMORPGs.  Massively Multiplayer games are fun because your opponents and teammates are smart enough to make the gameplay more enjoyable.  MMOs also suffer from various policing issues and behavior, anyone who has been called a n00b by a thirteen year old after he's headshot and teabagged you knows that the fun often comes at the price of dealing with the worst of human behavior.  Its not always so bad, and after a while you learn the rules of the world and online gameplay can be great fun, that's why its a major part of almost any AAA title released these days.&lt;/p&gt;
&lt;p&gt;Its this drive to have intelligent opponents that don't feel like they are cheating, teammates who can understand strategy and don't need to be micromanaged, and gameplay that is both rich and engaging that has brought MMOs, Xbox Live, and PSN to the forefront.  The software AI has failed so we went back to using people, which is great, video game nerds need as much socializing as possible.  But if a little injection of intelligence can be fun, much more intelligence can (and I stress can, not will, it could end up horrible) be much more fun.  I think this is where the future of gaming lies, not in various wands and cameras.&lt;/p&gt;
&lt;em&gt;This post got long and out of control, also it was fairly off topic, I hope to be back on programming tomorrow&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5534765709337552753-801504998548832669?l=ihumanable.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ihumanable.blogspot.com/feeds/801504998548832669/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ihumanable.blogspot.com/2009/10/motion-controls-and-ai.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5534765709337552753/posts/default/801504998548832669'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5534765709337552753/posts/default/801504998548832669'/><link rel='alternate' type='text/html' href='http://ihumanable.blogspot.com/2009/10/motion-controls-and-ai.html' title='motion controls and ai'/><author><name>Matt Nowack</name><uri>http://www.blogger.com/profile/00930543505232276126</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='20' src='http://4.bp.blogspot.com/_8IT2c3B5vQk/SsowYFU_8QI/AAAAAAAAADE/6iO_jned-r0/S220/smiles.jpeg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh6.ggpht.com/_8IT2c3B5vQk/SuXdhf-vGAI/AAAAAAAAAKA/0EqdzBCXPqE/s72-c/mario-screen.jpg' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5534765709337552753.post-7998030297010165549</id><published>2009-10-23T12:46:00.004-04:00</published><updated>2009-10-23T15:29:02.076-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='lisp'/><category scheme='http://www.blogger.com/atom/ns#' term='haskell'/><category scheme='http://www.blogger.com/atom/ns#' term='erlang'/><category scheme='http://www.blogger.com/atom/ns#' term='programming languages'/><title type='text'>treasure hunting</title><content type='html'>&lt;img src="http://lh6.ggpht.com/_8IT2c3B5vQk/SuHiXdizRZI/AAAAAAAAAJg/yrNFUHb9h_A/s800/xkcd_online_communities_340.png" style="float: right" /&gt;
&lt;p&gt;Working with programming languages is fun stuff.  If you are a programmer then you probably only think about your language as much as you need to to get the job done.  In fact you have to really, if you spent all day thinking about how the compiler is going to allocate this variable off the stack or this one off the heap or how its going to write out the virtual lookup tables, you could never get anything accomplished.&lt;/p&gt;
&lt;p&gt;It's a shame though because our programming languages are some of the most interesting and complex software we interact with.  If you are willing to look around you can find some real treasures out there, and even if you never code anything of importance in these new found treasures, the experience will pay dividends elsewhere.&lt;/p&gt;
&lt;p&gt;I'd like to take you on a tour of the treasures I've found in my travels through the world we call programming, I'll split it into four easy to consume chunks.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The Past&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The history of our field is short, still short enough that you can probably come to know most if not all of it.  This is one of the interesting things about Computer Science, its a field that, in it's modern form, is about 60 years old.  The amazing thing about all this is that there are some gems from the past, truly ground breaking work that we still use today.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://en.wikipedia.org/wiki/Lisp_%28programming_language%29"&gt;Lisp&lt;/a&gt;&lt;br/&gt;As you may well be aware I've recently &lt;a href="http://ihumanable.blogspot.com/2009/10/falling-in-love.html"&gt;fallen in love with lisp&lt;/a&gt;, I'm starting to &lt;a href="http://ihumanable.blogspot.com/2009/10/camels-underscores-and-dashes.html"&gt;think about her all the time&lt;/a&gt;, and &lt;a href="http://www.gigamonkeys.com/book/"&gt;you can too&lt;/a&gt;.  The amazing thing that, to this moment, knocks my socks off, is that &lt;a href="http://en.wikipedia.org/wiki/Lisp_%28programming_language%29"&gt;Lisp was originally conceived in 1958&lt;/a&gt; and has all kinds of concepts that you wouldn't expect from a language in it's 50s. &lt;a href="http://www.gigamonkeys.com/book/variables.html#lexical-variables-and-closures"&gt;Closures&lt;/a&gt;, &lt;a href="http://en.wikipedia.org/wiki/Lisp_%28programming_language%29#Language_innovations"&gt;homoiconic code&lt;/a&gt;, &lt;a href="http://en.wikipedia.org/wiki/Lisp_%28programming_language%29#Lambda_expressions"&gt;anonymous functions&lt;/a&gt;, &lt;a href="http://en.wikipedia.org/wiki/Common_Lisp_Object_System"&gt;object oriented programming&lt;/a&gt;, and &lt;a href="http://common-lisp.net/project/ucw/"&gt;a web framework&lt;/a&gt;.  There is a lot more to this language, and it is definitely worth your time, &lt;a href="http://www.gigamonkeys.com/book/"&gt;go read up&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://en.wikipedia.org/wiki/Smalltalk"&gt;Smalltalk&lt;/a&gt;&lt;br /&gt;&lt;a target='_blank' href='http://img202.imageshack.us/i/screenq.jpg/'&gt;&lt;img src='http://img202.imageshack.us/img202/2575/screenq.th.jpg' style="float: right" border='0'/&gt;&lt;/a&gt;This one comes from the 1970's from the famous &lt;a href="http://en.wikipedia.org/wiki/PARC_%28company%29"&gt;Xerox PARC&lt;/a&gt;.  Smalltalk was way ahead of its time with a fully integrated development environment, a fully functional GUI, no files (this sounds bad at first, but its freeing not having to worry about where your source lives), everything is a file, and much more.   Smalltalk's influence is far reaching even to this day, Objective-C borrows heavily from it, and the influential Gang of Four book offers source in C++ and Smalltalk.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://en.wikipedia.org/wiki/C_%28programming_language%29"&gt;C&lt;/a&gt;&lt;br /&gt;Hard to believe that this staple of computer programming was invented in 1972.  Without C, Unix would not exist.  C is still crazy fast, basically human readable assembly, and still widely used.  The backbone and infrastructure of most of our technology exists because of C.  Have a scripting language, need a way to shut people up who are saying it's too slow, allow them to call C modules, done.  C is definitely worth knowing, you can access a giant pile of source code, and get as close to the machine as possible without busting out the x86 Assembly Guide.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;The Present&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.ruby-lang.org/en/"&gt;Ruby&lt;/a&gt;&lt;br /&gt;This is the current hotness, although its hotness may be waning somewhat.  Today &lt;a href="http://github.com/languages"&gt;ruby is the top language on github&lt;/a&gt; and there is a new interesting project written in ruby everyday.  &lt;a href="http://rubyonrails.org/"&gt;Ruby on Rails&lt;/a&gt; created the rockstar ruby programmer, and revolutionized data backed web development.  Ruby is going to be around for a while, and because of REPL its easy to &lt;a href="http://www.ruby-lang.org/en/documentation/quickstart/"&gt;get started&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://en.wikipedia.org/wiki/List_of_JVM_languages"&gt;JVM Languages&lt;/a&gt;&lt;br /&gt;Java may be out, but the virtual maching that runs the language has never been more popular.  &lt;a href="http://en.wikipedia.org/wiki/Clojure"&gt;Clojure&lt;/a&gt; (a JVM Lisp, which will probably get its own article soon) and &lt;a href="http://en.wikipedia.org/wiki/Scala_%28programming_language%29"&gt;Scala&lt;/a&gt; are up and coming.  The ubiquity of the JVM means that you can run this code on almost any machine, and the languages are squeezing speed and performance out of the JVM that would have been unheard of a few years ago.  These languages can also leverage the huge pile of Java Libraries out in the wild, so the first major hurdle to a new language (what can this thing actually do and are there any tools for it), is easily leapt.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://en.wikipedia.org/wiki/Domain-specific_language"&gt;DSLs&lt;/a&gt;&lt;br /&gt;Domain Specific Languages are starting to come into their own.  Some of this popularity is owed to the rise of ruby which makes writing a new DSL somewhat trivial.  &lt;a href="http://sass-lang.com/"&gt;Sass&lt;/a&gt;, &lt;a href="http://haml-lang.com/"&gt;Haml&lt;/a&gt;, and many others DSLs are beginning to find more and more adoption within their domain.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;The Future&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://en.wikipedia.org/wiki/Functional_programming"&gt;Functional Programming&lt;/a&gt;&lt;br /&gt;&lt;a href="http://learnyousomeerlang.com/content"&gt;Erlang&lt;/a&gt;, &lt;a href="http://learnyouahaskell.com/"&gt;Haskell&lt;/a&gt;, &lt;a href="http://batteries.forge.ocamlcore.org/"&gt;OCaml&lt;/a&gt;, etc. are beginning to see an upswing in interest.  The rise of multi-processor cores and the inherent complexity of mutli-threaded programming in imperative programming makes these languages a tantalizing option.  Erlang can support millions of threads with simple, easy to understand code.  &lt;a href="http://couchdb.apache.org/"&gt;CouchDB&lt;/a&gt; will be the proving ground for Erlang's efficacy.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://en.wikipedia.org/wiki/JavaScript"&gt;JavaScript&lt;/a&gt;&lt;br /&gt;As I wrote in &lt;a href="http://ihumanable.blogspot.com/2009/10/future-javascript.html"&gt;the future: javascript&lt;/a&gt;&lt;blockquote&gt;When it get's down to it, JavaScript is a great language. It has a ton of exposure, and a huge amount of developer mindshare. JavaScript isn't going away anytime soon, and considering how hard it is to get browser vendor's to agree, isn't getting replaced anytime soon. JavaScript will become more and more prevalent both on the server and on the desktop. I welcome our new prototype based overlord, and so should you.&lt;/blockquote&gt;So far nothing has changed.&lt;/li&gt;
&lt;li&gt;Anything&lt;br /&gt;That is one of the most exciting things about this field, it could be anything.  Before Ruby on Rails, the ruby language was a small odd scripting language that few outside of Japan had heard about.  With the success of RoR ruby (which is an &lt;a href="http://www.randomhacks.net/articles/2005/12/03/why-ruby-is-an-acceptable-lisp"&gt;acceptable lisp&lt;/a&gt;) use has exploded and they have gained massive developer mindshare.  Tomorrow a new technology could set the world ablaze, and the best part is that we have a chance to shape that future.  This is an industry in which a man with a great idea can truly change the face of the development landscape.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These are just some of the treasures I have discovered by opening my eyes and looking around.  There are plenty more gems that I have found that didn't make it into this post, but only because these one's were on the top of my brain.  If you encounter a new language, take an hour or so to run through a tutorial, it could be worth it, it might not.  You may find yourself falling in love, or maybe you missed a few episodes of the Simpsons.  At the end of the day though, you will be glad that you took the time to learn something new, when you see glimmers of it in something old, and your knowledge of share-nothing concurrency saves the day on your next project.&lt;/p&gt;
&lt;p&gt;This is a dynamic wonderful field, go play!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5534765709337552753-7998030297010165549?l=ihumanable.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ihumanable.blogspot.com/feeds/7998030297010165549/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ihumanable.blogspot.com/2009/10/treasure-hunting.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5534765709337552753/posts/default/7998030297010165549'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5534765709337552753/posts/default/7998030297010165549'/><link rel='alternate' type='text/html' href='http://ihumanable.blogspot.com/2009/10/treasure-hunting.html' title='treasure hunting'/><author><name>Matt Nowack</name><uri>http://www.blogger.com/profile/00930543505232276126</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='20' src='http://4.bp.blogspot.com/_8IT2c3B5vQk/SsowYFU_8QI/AAAAAAAAADE/6iO_jned-r0/S220/smiles.jpeg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh6.ggpht.com/_8IT2c3B5vQk/SuHiXdizRZI/AAAAAAAAAJg/yrNFUHb9h_A/s72-c/xkcd_online_communities_340.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5534765709337552753.post-5901856601228399485</id><published>2009-10-22T14:28:00.004-04:00</published><updated>2009-10-22T15:38:05.940-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='rant'/><category scheme='http://www.blogger.com/atom/ns#' term='project management'/><category scheme='http://www.blogger.com/atom/ns#' term='side project'/><title type='text'>project documentation</title><content type='html'>&lt;p&gt;This post is about documentation, not source code documentation, but project and process level documentatino.  I've spent the last 3 days working on a quick side project at work.  There were 10 tasks, none of which were very complicated, the time spent tackling these tasks was about 5 or 6 billable hours.  The time spent figuring out how to deploy these changes was about 3 days.  The problem, project documentation&lt;/p&gt;
&lt;img src="http://lh4.ggpht.com/_8IT2c3B5vQk/SuClH_UQ3qI/AAAAAAAAAI8/Do-kghgdzqE/s800/ResizedImage231173-ScatteredKeys.jpg" style="float: right" /&gt;
&lt;p&gt;&lt;strong&gt;Scattered Information&lt;/strong&gt;&lt;br /&gt;Like some sort of 80's Nintendo Game I had to find the various colored keys to win the game.  One developer knew the ftp server's ip address, another the username, maybe a third the password.  It didn't help matters that this was a fairly complex site made up of multiple components (third-party blog, storefront, cms) each with their own credentials.  Collecting this information was the first hurdle to leap in getting the code and getting the job done.  It took a solid afternoon of pinging different parties but I finally had a list of keys, the blue door, the red door, even the green glowing door could all be opened!&lt;/p&gt;
&lt;img src="http://lh3.ggpht.com/_8IT2c3B5vQk/SuCqwSEBZrI/AAAAAAAAAJA/fDF5qfsm7CM/s144/ancient-computer.jpg" style="float: left" /&gt;
&lt;p&gt;&lt;strong&gt;Out of Date Information&lt;/strong&gt;&lt;br /&gt;Then came the crushing realization, as I found that the red door was rusted shut, the green glowing door didn't use a key but a magic potion, and no one could remember exactly where the hell the blue door was even located.  The information was out of date or just plain wrong, more time wasted pinging people to get updated information and missing chunks.  But after another day of haranguing I finally confirmed that the doors could in fact be opened, that night visions of tables and source code danced in my head.&lt;/p&gt;
&lt;img src="http://lh6.ggpht.com/_8IT2c3B5vQk/SuCuee4cZBI/AAAAAAAAAJE/0y99Rs-sVW8/s288/dew_mistake.jpg" style="float: right" /&gt;
&lt;p&gt;&lt;strong&gt;Misplaced Information&lt;/strong&gt;&lt;br /&gt;This isn't really anyone's fault.  I was working on a type of system, let's call it a foo type system, this particular foo system had been customized for client bar.  I looked in the foo\bar\ folder for documentation and came up empty-handed.  I assumed that there was no documentation and so created some there to collect up the hard earned bits and pieces of information I was able to pull together.  Being proud of my new documentation with things logically laid out, I reported to my fellow developers the great leap forward in documentation technology I had developed.  I was told there was similar documentation in the foo\ folder, why no one mentioned this to me earlier when I was pulling together this information is beyond me.  But it didn't make sense to my brain, if there is a foo\bar\ folder why isn't foo\bar\ information in it, why is it in foo\, ah!&lt;/p&gt;
&lt;p&gt;So what is the solution? Knowledge Base, Sharepoint, Wikis, Word Documents, what to do?  I don't think that any one of these things by itself is a solution, but I do have some ideas.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Convention over Configuration&lt;/strong&gt;&lt;br /&gt;If you've ever played around with &lt;a href="http://rubyonrails.org/"&gt;Ruby on Rails&lt;/a&gt; you will know the great joy of feeling at home in a rails project.  Where are my models?! app\models\ that's where they always are, that's where they belong.  I think adopting a standard documentation layout structure would be useful.  Here's an idea (off the top of my head, so its not very polished)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;project-name\documentation - Root of the documentation&lt;/li&gt;
&lt;li&gt;project-name\documentation\bootstrap - How to get started, pulling the project from source control, initial builds, dev box configuration&lt;/li&gt;
&lt;li&gt;project-name\documentation\credentials - IP Addresses, Username, and Passwords go here&lt;/li&gt;
&lt;li&gt;project-name\documentation\database - Everything you'd want to know about the database&lt;/li&gt;
&lt;li&gt;project-name\documentation\deploy - Deployment specifics are here&lt;/li&gt;
&lt;li&gt;project-name\documentation\vendor\* - Third party documentation goes in various folders here&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It's not perfect but its a start, really the important thing would be to have some sort of standard and stick to it.&lt;/p&gt;
&lt;p&gt;Wikis&lt;br /&gt;I like wikis, I think they are neat.  Your documentation is easily editable, so it's easy to keep it up to date, and multiple parties can collaborate to break the task of documenting a system into more manageable chucks.  I also think that you should follow some sort of system when writing them.  Make this part of the convention and don't stray from it unless absolutely necessary.  Maybe the sections above simply become wiki pages, with subpages.  Wiki markup is easy to learn for any programmer, and as long as you aren't doing anything fancy, easy to remember.&lt;/p&gt;
&lt;p&gt;Document your processes, that's the big thing, it would be great if you have a convention, its awesome if you have some collaboration medium that let's you keep it up to date, but the most important thing is to document the process.  It's been eye opening to write out a list of steps for some of the "simple" tasks I do on a project from time to time.  Since its become routine in my head the task is one step, do the task, but when I write it out on paper there are 13 steps with small conditional branches.  It seems easy to do a task you've done a hundred times before, but it can be maddening to someone new trying to accomplish that task without the help of the well-worn mental path you've painstakingly claimed from the jaws of chaos.&lt;/p&gt;
&lt;p&gt;I have been on projects with great documentation, and some with not so stellar documentation, and it is like night and day.  So here's a thought experiment, a trite and cliche one, but if your entire development team got hit by a bus tomorrow and some new guys had to come in and deploy, how long would it take them, could they even do it?  The answer should be, they would simply bootstrap then look in deploy and follow my step by step guide to deployment success, if your answer was, they would pray and put on their detective hats, ding ding ding, you've got some documentation work to do.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5534765709337552753-5901856601228399485?l=ihumanable.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ihumanable.blogspot.com/feeds/5901856601228399485/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ihumanable.blogspot.com/2009/10/project-documentation.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5534765709337552753/posts/default/5901856601228399485'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5534765709337552753/posts/default/5901856601228399485'/><link rel='alternate' type='text/html' href='http://ihumanable.blogspot.com/2009/10/project-documentation.html' title='project documentation'/><author><name>Matt Nowack</name><uri>http://www.blogger.com/profile/00930543505232276126</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='20' src='http://4.bp.blogspot.com/_8IT2c3B5vQk/SsowYFU_8QI/AAAAAAAAADE/6iO_jned-r0/S220/smiles.jpeg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh4.ggpht.com/_8IT2c3B5vQk/SuClH_UQ3qI/AAAAAAAAAI8/Do-kghgdzqE/s72-c/ResizedImage231173-ScatteredKeys.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5534765709337552753.post-5410025270057577701</id><published>2009-10-21T12:45:00.010-04:00</published><updated>2009-10-21T14:04:06.573-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='rant'/><category scheme='http://www.blogger.com/atom/ns#' term='lisp'/><category scheme='http://www.blogger.com/atom/ns#' term='opinion'/><title type='text'>camels, underscores, and dashes</title><content type='html'>&lt;img src="http://lh3.ggpht.com/_8IT2c3B5vQk/St8_HmeV7xI/AAAAAAAAAIg/9ykkRbw55zE/s288/2491959095_c51c0ca336.jpg" style="float: right" /&gt;
&lt;p&gt;I've been learning lisp, oh it is good fun!  &lt;a href="http://www.gigamonkeys.com/book/"&gt;Go now&lt;/a&gt;, stop reading this stupid blog, &lt;a href="http://www.gigamonkeys.com/book/"&gt;learn some lisp!&lt;/a&gt;  Anyone still here, well let's talk about some stuff since you won't obey my commands... yet.&lt;/p&gt;
&lt;p&gt;There are stupid things in life that don't seem important but somehow make a big difference.  Really stupid things, things you can't image people would ever care about, like &lt;a href="http://en.wikipedia.org/wiki/Indent_style"&gt;Indent style&lt;/a&gt;.  Not a programmer, don't think it matters, don't think anyone would ever care?  Get 10 programmers together, ask them what their favorite &lt;a href="http://en.wikipedia.org/wiki/Indent_style"&gt;Indent style&lt;/a&gt; is and watch as the &lt;a href="http://en.wikipedia.org/wiki/Indent_style#Variant:_1TBS"&gt;One True Brace Stylistas&lt;/a&gt; (the camp I fall into) and the &lt;a href="http://en.wikipedia.org/wiki/Indent_style#Allman_style_.28bsd_in_Emacs.29"&gt;Allmaniacs&lt;/a&gt; start screaming obscenities at each other and begin to fashion crude weaponry.&lt;/p&gt;
&lt;p&gt;It seems like a small thing, but as programmers we spend a lot of time parsing text with our eyes and our brains.  Reading source with a different &lt;a href="http://en.wikipedia.org/wiki/Indent_style"&gt;Indent style&lt;/a&gt; can feel like walking with shoes on 3 sizes too big, sure you still know how to walk but it feels clumsy and unnatural.&lt;/p&gt;
&lt;p&gt;Lisp can definitely feel like waking up groggy and putting on a pair of rollerblades instead of shoes.  Its syntax can be confounding and lots of new comers really hate the parentheses.&lt;/p&gt;
&lt;pre class="brush: lisp"&gt;
(defmacro once-only ((&amp;rest names) &amp;body body)
  (let ((gensyms (loop for n in names collect (gensym))))
    `(let (,@(loop for g in gensyms collect `(,g (gensym))))
      `(let (,,@(loop for g in gensyms for n in names collect ``(,,g ,,n)))
        ,(let (,@(loop for n in names for g in gensyms collect `(,n ,g)))
           ,@body)))))
&lt;/pre&gt;
&lt;em&gt;Note there should not be any semicolons after the ampersands, syntax highlighter keeps putting them in there (if you know how to fix this please feel free to leave a comment)&lt;/em&gt;
&lt;p&gt;Now this is a little unfair to lisp, if this is the first code example you've every seen don't be scared off, it uses lots of advanced concepts, and to be honest, I still don't fully grok the double-quoting and double-unquoting that is going on in this thing.  The main thing to take away is look at all those parentheses, goodness me!  Actually its not really that bad, SLIME does a great job of balancing them and they are semantic not just syntactic.  Unlike other languages, in lisp parentheses are signal not noise.&lt;/p&gt;
&lt;p&gt;One of the things I love about lisp and find myself wanting to do more and more in other programming languages is using the dash as a separator.  The macro that is defined above is named "only-once" and I like that.  Typing it is a breeze, there are no shifts to get capital letters or underscores.  Depending on the language this would be written as OnlyOnce, onlyOnce, only_once, but lisp lets you type only-once, and although it seems small, I definitely like it more than any other convention.&lt;/p&gt;
&lt;p&gt;I'm a web programmer for my 9-5 actually get a paycheck for programming programming, and there are many things that you can name with dashes.  Web pages (my-sweet-webpage.html), image resources (guy-dancing-with-cat.jpg), css class (div.super-awesome), html entity id's (my-super-awesome-div) are all legal.  I want to be able to use the same convention in JavaScript or C# or PHP or [insert language here] but I can't.&lt;/p&gt;
&lt;p&gt;There is good reason why I can't, it would be impossible to program a parser, don't believe me, parse this JavaScript pretending that you can use dashes in names.&lt;/p&gt;
&lt;pre class="brush: javascript"&gt;
var dash-variable = 10
var dash = 8;
var variable = 4;
alert(dash-variable);
&lt;/pre&gt;
&lt;p&gt;What would the output be, 10 because it looked up "dash-variable" or 4 because it looked up "dash"-"variable" = 8 - 4 = 4.  The way lisp gets around this is that there are no infix operators.  The same code in lisp would look like this.&lt;/p&gt;
&lt;pre class="brush: lisp"&gt;
(defvar dash-variable 10)
(defvar dash 8)
(defvar variable 4)
(format t dash-variable)
; or
(format t (- dash variable))
&lt;/pre&gt;
&lt;p&gt;Slowly but surely though I'm getting used to gliding around on my lisp rollerblades, and when I have to put on my C# shoes or my PHP shoes they just don't feel right anymore.  There is nothing I can about this except be aware, and for the love of the &lt;a href="http://www.venganza.org/"&gt;flying spaghetti monster&lt;/a&gt; &lt;strong&gt;&lt;em&gt;FOLLOW THE LANGUAGE'S NAMING CONVENTION.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Because if I come across some of your .Net code and it looks like Java, or you want to write your JavaScript like its a .Net class, you will incur my unending wrath.  I might think that capitalizing the first letter of function names is wrong (I'm looking at you .Net, first letter capitalization is for classes) but consistency of source code is much more important than my petty preference.  Lunch is over now, back to writing &lt;a href="http://en.wikipedia.org/wiki/Indent_style#Allman_style_.28bsd_in_Emacs.29"&gt;Allman braced&lt;/a&gt; &lt;a href="http://en.wikipedia.org/wiki/CamelCase"&gt;CapWords&lt;/a&gt; C# code, because at the end of the day, someone pays me to walk around in these &lt;a href="http://www.crocs.com/"&gt;crocs&lt;/a&gt;, no matter how ugly I think they are.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5534765709337552753-5410025270057577701?l=ihumanable.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ihumanable.blogspot.com/feeds/5410025270057577701/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ihumanable.blogspot.com/2009/10/camels-underscores-and-dashes.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5534765709337552753/posts/default/5410025270057577701'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5534765709337552753/posts/default/5410025270057577701'/><link rel='alternate' type='text/html' href='http://ihumanable.blogspot.com/2009/10/camels-underscores-and-dashes.html' title='camels, underscores, and dashes'/><author><name>Matt Nowack</name><uri>http://www.blogger.com/profile/00930543505232276126</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='20' src='http://4.bp.blogspot.com/_8IT2c3B5vQk/SsowYFU_8QI/AAAAAAAAADE/6iO_jned-r0/S220/smiles.jpeg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh3.ggpht.com/_8IT2c3B5vQk/St8_HmeV7xI/AAAAAAAAAIg/9ykkRbw55zE/s72-c/2491959095_c51c0ca336.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5534765709337552753.post-6621048209978674942</id><published>2009-10-20T11:30:00.007-04:00</published><updated>2009-10-20T13:27:49.985-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='ux'/><title type='text'>deleting a record</title><content type='html'>&lt;script type="text/javascript"&gt;
   function get_parent(elem, tag) {
  if(elem == null || elem.tagName.toUpperCase() == tag.toUpperCase()) {
   return elem;
  }
  return get_parent(elem.parentNode, tag);
 }
 
 function remove_row(row) {
  row = get_parent(row, "tr");
  var parent = row.parentNode;
  parent.removeChild(row);
 }
 
 function simple_delete(lnk) {
  remove_row(lnk);
 }
 
 function confirm_delete(lnk) {
  if(confirm("Really Delete?")) {
   remove_row(lnk);
  }
 }
 
 var dblclk_delete_state = null;
 function dblclk_delete(lnk, which) {
  for(var i = 1; i &lt;= 3; ++i) {
   var msg = document.getElementById('dblclk_confirm_' + i);
   if(msg) {
    msg.style.display = 'none';
   }
  }
  
  if(dblclk_delete_state == which) {
   remove_row(lnk);
   dblclk_delete_state = null;
  } else {
   dblclk_delete_state = which;
   document.getElementById('dblclk_confirm_' + which).style.display = 'block';
  }
 }
 
 function binary_message(which) {
  var msg = document.getElementById('binary_confirm_' + which);
  if(msg) {
   if(msg.style.display == 'none') {
    msg.style.display = 'block';
   } else {
    msg.style.display = 'none'; 
   }
  }
 }
 
 function modified_open(which) {
  modified_state(which, 'block');
 }
 
 function modified_close(which) {
  modified_state(which, 'none');
 }
 
 function modified_state(which, disp) {
  document.getElementById('modified_confirm_' + which).style.display = disp;
 }
&lt;/script&gt;
&lt;p&gt;I've been working on a side project in my spare time, what little there is, and its come time to work on the UI, which is one of my favorite things to do, but one of the hardest things to get right.&lt;/p&gt;
&lt;p&gt;Trying to decide amongst the various ways to delete something, trying to create a user experience that will be pleasant and not knock you out of your workflow.  Here are the various methods I've been mulling over with lists of pro's and con's, and because I'm super nice, some javascript code that implements them.&lt;/p&gt;
&lt;p&gt;All of the methods I'm going to go over rely on some backend handler that will be communicated with asynchronously to do the heavy lifting of performing the actual delete.  The code could be simplified (in some cases greatly) by using jQuery or some other javascript framework, but in the interest of not being dependent on any particular framework, I wrote the code as straight javascript.&lt;/p&gt;
&lt;p&gt;All the code depends on two helper methods&lt;/p&gt;
&lt;pre class="brush: javascript"&gt;
 
/**
 * Finds the nearest ancestor of an element with a given tag name
 * @param elem [HTML Element] element to find the ancestor for
 * @param tag [String] tag name to look up
 * @return elem [HTML Element | null] null if can't be found
 */
function get_parent(elem, tag) {
  if(elem == null || elem.tagName.toUpperCase() == tag.toUpperCase()) {
    return elem;
  }
  return get_parent(elem.parentNode, tag);
}
 
/**
 * Removes a row when given any node within the row or the row itself
 * @param row [HTML Element] row node or any child node of row node
 */
function remove_row(row) {
  row = get_parent(row, "tr");
  var parent = row.parentNode;
  parent.removeChild(row);
}
&lt;/pre&gt;
&lt;p&gt;Method 1: Simple delete&lt;/p&gt;
&lt;blockquote&gt;
&lt;table class="border-br"&gt;
  &lt;tr&gt;
    &lt;th&gt;Name&lt;/th&gt;
    &lt;th&gt;Age&lt;/th&gt;
    &lt;th&gt;Delete&lt;/th&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;Amy&lt;/td&gt;
    &lt;td&gt;24&lt;/td&gt;
    &lt;td&gt;&lt;a href="javascript:;" onclick="simple_delete(this)"&gt;delete&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;Matt&lt;/td&gt;
    &lt;td&gt;23&lt;/td&gt;
    &lt;td&gt;&lt;a href="javascript:;" onclick="simple_delete(this)"&gt;delete&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;Zeke&lt;/td&gt;
    &lt;td&gt;32&lt;/td&gt;
    &lt;td&gt;&lt;a href="javascript:;" onclick="simple_delete(this)"&gt;delete&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
&lt;/table&gt;
&lt;/blockquote&gt;
&lt;pre class="brush: javascript"&gt;
  function simple_delete(lnk) {
    remove_row(lnk);
  }
&lt;/pre&gt;
&lt;table class="border-br"&gt;
  &lt;tr&gt;
    &lt;th&gt;Pros&lt;/th&gt;
    &lt;th&gt;Cons&lt;/th&gt;
  &lt;tr&gt;
  &lt;tr&gt;
    &lt;td&gt;Extremely Simple&lt;/td&gt;
    &lt;td&gt;Easy to accidentally delete something&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;&amp;nbsp;&lt;/td&gt;
    &lt;td&gt;Very little feedback&lt;/td&gt;
  &lt;/tr&gt;
&lt;/table&gt;

&lt;p&gt;Method 2: Confirm Delete&lt;/p&gt;
&lt;blockquote&gt;
&lt;table class="border-br"&gt;
  &lt;tr&gt;
    &lt;th&gt;Name&lt;/th&gt;
    &lt;th&gt;Age&lt;/th&gt;
    &lt;th&gt;Delete&lt;/th&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;Amy&lt;/td&gt;
    &lt;td&gt;24&lt;/td&gt;
    &lt;td&gt;&lt;a href="javascript:;" onclick="confirm_delete(this)"&gt;delete&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;Matt&lt;/td&gt;
    &lt;td&gt;23&lt;/td&gt;
    &lt;td&gt;&lt;a href="javascript:;" onclick="confirm_delete(this)"&gt;delete&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;Zeke&lt;/td&gt;
    &lt;td&gt;32&lt;/td&gt;
    &lt;td&gt;&lt;a href="javascript:;" onclick="confirm_delete(this)"&gt;delete&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
&lt;/table&gt;
&lt;/blockquote&gt; 
&lt;pre class="brush: javascript"&gt;
  function confirm_delete(lnk) {
    if(confirm("Really Delete?")) {
      remove_row(lnk);
    }
  }
&lt;/pre&gt;
&lt;table class="border-br"&gt;
  &lt;tr&gt;
    &lt;th&gt;Pros&lt;/th&gt;
    &lt;th&gt;Cons&lt;/th&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;No accidental deletes&lt;/td&gt;
    &lt;td&gt;Breaks flow&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;Easy cross browser implementation&lt;/td&gt;
    &lt;td&gt;Annoying, focus steal, mousing&lt;/td&gt;
  &lt;/tr&gt;
&lt;/table&gt;

&lt;p&gt;Method 3: Double-click Delete&lt;/p&gt;
&lt;blockquote&gt;
&lt;table class="border-br"&gt;
  &lt;tr&gt;
    &lt;th&gt;Name&lt;/th&gt;
    &lt;th&gt;Age&lt;/th&gt;
    &lt;th&gt;Delete&lt;/th&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;Amy&lt;/td&gt;
    &lt;td&gt;24&lt;/td&gt;
    &lt;td&gt;&lt;a href="javascript:;" onclick="dblclk_delete(this, 1)"&gt;delete&lt;/a&gt;&lt;/td&gt;
    &lt;td id="dblclk_confirm_1" style="display:none"&gt;Click again to confirm&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;Matt&lt;/td&gt;
    &lt;td&gt;23&lt;/td&gt;
    &lt;td&gt;&lt;a href="javascript:;" onclick="dblclk_delete(this, 2)"&gt;delete&lt;/a&gt;&lt;/td&gt;
    &lt;td id="dblclk_confirm_2" style="display:none"&gt;Click again to confirm&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;Zeke&lt;/td&gt;
    &lt;td&gt;32&lt;/td&gt;
    &lt;td&gt;&lt;a href="javascript:;" onclick="dblclk_delete(this, 3)"&gt;delete&lt;/a&gt;&lt;/td&gt;
    &lt;td id="dblclk_confirm_3" style="display:none"&gt;Click again to confirm&lt;/td&gt;
  &lt;/tr&gt;
&lt;/table&gt;
&lt;/blockquote&gt; 
&lt;pre class="brush: javascript"&gt;
  var dblclk_delete_state = null;
  function dblclk_delete(lnk, which) {
    //Hide everything first
    for(var i = 1; i &lt;= 3; ++i) {
      var msg = document.getElementById('dblclk_confirm_' + i);
      if(msg) {
        msg.style.display = 'none';
      }
    }
  
    if(dblclk_delete_state == which) {
      remove_row(lnk);
      //No need to clear state, but it can't hurt
      dblclk_delete_state = null;
    } else {
      dblclk_delete_state = which;
      document.getElementById('dblclk_confirm_' + which).style.display = 'block';
    }
  }
&lt;/pre&gt;
&lt;table class="border-br"&gt;
  &lt;tr&gt;
    &lt;th&gt;Pros&lt;/th&gt;
    &lt;th&gt;Cons&lt;/th&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;Easy deletes&lt;/td&gt;
    &lt;td&gt;Some people double-click out of habit&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;Confirm before delete&lt;/td&gt;
    &lt;td&gt;Double clicks avoid confirmation&lt;/td&gt;
  &lt;/tr&gt;
&lt;/table&gt;

&lt;p&gt;Method 4: Binary Delete&lt;/p&gt;
&lt;blockquote&gt;
&lt;table class="border-br"&gt;
  &lt;tr&gt;
    &lt;th&gt;Name&lt;/th&gt;
    &lt;th&gt;Age&lt;/th&gt;
    &lt;th&gt;Delete&lt;/th&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;Amy&lt;/td&gt;
    &lt;td&gt;24&lt;/td&gt;
    &lt;td&gt;&lt;a href="javascript:;" onclick="binary_message(1)"&gt;delete&lt;/a&gt;&lt;/td&gt;
    &lt;td id="binary_confirm_1" style="display:none"&gt;Really? &lt;a href="javascript:;" onclick="remove_row(this)"&gt;Yes&lt;/a&gt;&amp;nbsp;&amp;nbsp;&lt;a href="javascript:;" onclick="binary_message(1)"&gt;No&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;Matt&lt;/td&gt;
    &lt;td&gt;23&lt;/td&gt;
    &lt;td&gt;&lt;a href="javascript:;" onclick="binary_message(2)"&gt;delete&lt;/a&gt;&lt;/td&gt;
    &lt;td id="binary_confirm_2" style="display:none"&gt;Really? &lt;a href="javascript:;" onclick="remove_row(this)"&gt;Yes&lt;/a&gt;&amp;nbsp;&amp;nbsp;&lt;a href="javascript:;" onclick="binary_message(2)"&gt;No&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;Zeke&lt;/td&gt;
    &lt;td&gt;32&lt;/td&gt;
    &lt;td&gt;&lt;a href="javascript:;" onclick="binary_message(3)"&gt;delete&lt;/a&gt;&lt;/td&gt;
    &lt;td id="binary_confirm_3" style="display:none"&gt;Really? &lt;a href="javascript:;" onclick="remove_row(this)"&gt;Yes&lt;/a&gt;&amp;nbsp;&amp;nbsp;&lt;a href="javascript:;" onclick="binary_message(3)"&gt;No&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
&lt;/table&gt;
&lt;/blockquote&gt;
&lt;pre class="brush: javascript"&gt;
//Yes link simply calls remove_row(this)

//This function is called by the delete link and the No link
function binary_message(which) {
  var msg = document.getElementById('binary_confirm_' + which);
  if(msg) {
    if(msg.style.display == 'none') {
      msg.style.display = 'block';
    } else {
      msg.style.display = 'none'; 
    }
  }
}
&lt;/pre&gt; 
&lt;table class="border-br"&gt;
  &lt;tr&gt;
    &lt;th&gt;Pros&lt;/th&gt;
    &lt;th&gt;Cons&lt;/th&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;No accidental deletes&lt;/td&gt;
    &lt;td&gt;Breaks flow (less)&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;Can be prettied up with &lt;a href="http://craigsworks.com/projects/qtip/"&gt;qTip&lt;/a&gt;&lt;/td&gt;
    &lt;td&gt;Clicking delete after message appears should perform what action?&lt;/td&gt;
  &lt;/tr&gt;
&lt;/table&gt;

&lt;p&gt;Method 5: Binary Modified&lt;/p&gt;
&lt;blockquote&gt;
&lt;table class="border-br"&gt;
  &lt;tr&gt;
    &lt;th&gt;Name&lt;/th&gt;
    &lt;th&gt;Age&lt;/th&gt;
    &lt;th&gt;Delete&lt;/th&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;Amy&lt;/td&gt;
    &lt;td&gt;24&lt;/td&gt;
    &lt;td&gt;&lt;a href="javascript:;" onclick="modified_open(1)"&gt;delete&lt;/a&gt;&lt;/td&gt;
    &lt;td id="modified_confirm_1" style="display:none"&gt;Really? &lt;a href="javascript:;" onclick="remove_row(this)"&gt;Yes&lt;/a&gt;&amp;nbsp;&amp;nbsp;&lt;a href="javascript:;" onclick="modified_close(1)"&gt;No&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;Matt&lt;/td&gt;
    &lt;td&gt;23&lt;/td&gt;
    &lt;td&gt;&lt;a href="javascript:;" onclick="modified_open(2)"&gt;delete&lt;/a&gt;&lt;/td&gt;
    &lt;td id="modified_confirm_2" style="display:none"&gt;Really? &lt;a href="javascript:;" onclick="remove_row(this)"&gt;Yes&lt;/a&gt;&amp;nbsp;&amp;nbsp;&lt;a href="javascript:;" onclick="modified_close(2)"&gt;No&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;Zeke&lt;/td&gt;
    &lt;td&gt;32&lt;/td&gt;
    &lt;td&gt;&lt;a href="javascript:;" onclick="modified_open(3)"&gt;delete&lt;/a&gt;&lt;/td&gt;
    &lt;td id="modified_confirm_3" style="display:none"&gt;Really? &lt;a href="javascript:;" onclick="remove_row(this)"&gt;Yes&lt;/a&gt;&amp;nbsp;&amp;nbsp;&lt;a href="javascript:;" onclick="modified_close(3)"&gt;No&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
&lt;/table&gt;
&lt;/blockquote&gt;
&lt;pre class="brush: javascript"&gt;
  //Yes simply calls remove_row(this); like in the non-modified version

  //delete link calls this function
  function modified_open(which) {
    modified_state(which, 'block');
  }
 
  //No link calls this function
  function modified_close(which) {
    modified_state(which, 'none');
  }

  //Helper function 
  function modified_state(which, disp) {
    document.getElementById('modified_confirm_' + which).style.display = disp;
  }
&lt;/pre&gt;
&lt;table class="border-br"&gt;
  &lt;tr&gt;
    &lt;th&gt;Pros&lt;/th&gt;
    &lt;th&gt;Cons&lt;/th&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;No accidental deletes&lt;/td&gt;
    &lt;td&gt;Breaks flow (less)&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;Also can be made pretty&lt;/td&gt;
    &lt;td&gt;&amp;nbsp;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;Better (?) delete link behavior&lt;/td&gt;
    &lt;td&gt;&amp;nbsp;&lt;/td&gt;
  &lt;/tr&gt;
&lt;/table&gt;
&lt;hr /&gt;
&lt;p&gt;So those are the various methods I'm mulling over now, also whether a delete should remove the row or simply gray it out, should you be able to undo a delete, all kinds of questions.  These have serious consequences for my application and are quite outside of the scope of this already way too long post.  I think I like Method 4 or 5 the best, can't decide which.  Which do you like, is there something that I missed?&lt;/p&gt;
&lt;em&gt;Code is hacked together example code, real code will be nicer, possibly even a jQuery plugin&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5534765709337552753-6621048209978674942?l=ihumanable.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ihumanable.blogspot.com/feeds/6621048209978674942/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ihumanable.blogspot.com/2009/10/deleting-record.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5534765709337552753/posts/default/6621048209978674942'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5534765709337552753/posts/default/6621048209978674942'/><link rel='alternate' type='text/html' href='http://ihumanable.blogspot.com/2009/10/deleting-record.html' title='deleting a record'/><author><name>Matt Nowack</name><uri>http://www.blogger.com/profile/00930543505232276126</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='20' src='http://4.bp.blogspot.com/_8IT2c3B5vQk/SsowYFU_8QI/AAAAAAAAADE/6iO_jned-r0/S220/smiles.jpeg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5534765709337552753.post-1411337621432706157</id><published>2009-10-19T10:23:00.003-04:00</published><updated>2009-10-19T11:00:50.674-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='analysis'/><category scheme='http://www.blogger.com/atom/ns#' term='tools'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><title type='text'>tool roundup</title><content type='html'>&lt;p&gt;As a programmer I'm often asked to do what lots of programmers have to do, think about and analyze a completely conceptual structure.  Programs can build up massive structures, the computer is more than happy to allow you to create a hash of trees of lists of objects with properties that are hashes of trees of lists of objects with properties that are... and so on and so forth.  That is one of the great strengths of programming, but also one of the greatest challenges.&lt;/p&gt;
&lt;p&gt;At the end of the day the computer only has one data structure, a memory address.  It's just one big long row of memory that we can store stuff in, the rest is all conceptual framework we build on top of it.  To deal with these complexities we build tools and abstractions, I want to talk about some of my favorite tools, and find out about some of yours.&lt;/p&gt;
&lt;p&gt;I was recently given the task of fixing up a workflow, there are many entries in a database table somewhere where each entry represents a part of a path through the workflow.  So an entry might define that from the &lt;em&gt;put on socks&lt;/em&gt; state you could move to the &lt;em&gt;put on shoes&lt;/em&gt; state.  Having a vast number of these states and a whole bunch of paths between them, it became difficult to think about the way the system worked, so I created a visualization.&lt;/p&gt;
&lt;div class="embed-wrap"&gt;
&lt;img src="http://lh3.ggpht.com/_8IT2c3B5vQk/Stx4zgrUwHI/AAAAAAAAAH0/yo2xCVtrecU/s800/fund_reqs.png" /&gt;
&lt;/div&gt;
&lt;p&gt;This looks complex, and it is, but it is a much better reference when working with this particular part of the system than looking at the database table and trying to assemble parts of it in my brain as the situation demands.  So how did I create this diagram&lt;/p&gt;
&lt;p&gt;&lt;a href="http://diagrammr.com/"&gt;Diagrammr&lt;/a&gt; one of the coolest on-line tools I've ever encountered.  It's free, it's fast, and it works really well.  I just entered a bunch of fragments into a text box like this&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ds to dc&lt;/li&gt;
&lt;li&gt;dc to ta&lt;/li&gt;
&lt;li&gt;dc to tr&lt;/li&gt;
&lt;li&gt;tr to dc&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And after adding quite a few more, this fun diagram popped out, quick and easy.&lt;/p&gt;
&lt;p&gt;This diagram was fairly straightforward, the boxes are just simple states, but when I need a more full bodied solution, I use &lt;a href="http://live.gnome.org/Dia"&gt;Dia&lt;/a&gt;.  Let's run down the checklist here, free, yes, lightweight, yes, intuitive, yes, awesome, yes.&lt;/p&gt;
&lt;div class="embed-wrap"&gt;
&lt;img src="http://lh3.ggpht.com/_8IT2c3B5vQk/Stx6E0jPdQI/AAAAAAAAAH4/ZSqukB269L4/s400/diagram.png"&gt;
&lt;/div&gt;
&lt;p&gt;Dia is also cross-platform, super bonus, and it has figure sets for almost any kind of diagram you would want to make.  One of the best things about Dia is that the images are intelligent objects, double click on a table in a schema diagram and it brings up a dialog to enter column information.  Double click a class in an inheritance document and it brings up a dialog to add members, functions, and hierarchy information.  Dia also lets you easily export to several different file formats including but not limited to&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Native Dia Diagram File (.dia)&lt;/li&gt;
&lt;li&gt;HP Graphics Language (.hpgl, .plt)&lt;/li&gt;
&lt;li&gt;Portable Network Graphic (.png)&lt;/li&gt;
&lt;li&gt;Scalable Vector Graphic (.svg)&lt;/li&gt;
&lt;li&gt;Visio XML Format (.vdx)&lt;/li&gt;
&lt;li&gt;Windows Meta File (.wmf)&lt;/li&gt;
&lt;li&gt;XSL Transformation Filter (.code)&lt;/li&gt;
&lt;/ul&gt;
&lt;img src="http://lh4.ggpht.com/_8IT2c3B5vQk/Stx--FvnbhI/AAAAAAAAAIE/PT7cdhV1ZWA/s800/s0100305_sc7.jpg" style="float: right" /&gt;
&lt;p&gt;Last but not least is my all purpose tool, the number one go to when the chips are down, &lt;a href="http://www.staples.com/Staples-Quadrille-4x4-Spiral-Notebook-8x10.5/product_716522_SH110?cmArea=SC1:CG10:DP1413:CL159987"&gt;Graph Paper&lt;/a&gt;.  It is fair to say that I love graph paper.  It is by far the most useful tool to have around.  Is there anything graph paper can't do, lets look.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Write beautifully in horizontal and vertical orientations... check&lt;/li&gt;
&lt;li&gt;Allow for monospaced fonts... check&lt;/li&gt;
&lt;li&gt;Ad hoc tables... check&lt;/li&gt;
&lt;li&gt;Impromptu graphs... check&lt;/li&gt;
&lt;li&gt;Arrow support... check&lt;/li&gt;
&lt;li&gt;Runs linux... soon (I'm sure someone's working on it)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These are some of my favorite tools, with them no data structure frightens me, no data set is too formidable, order can be brought to chaos.  What are some of your favorite tools?&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5534765709337552753-1411337621432706157?l=ihumanable.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ihumanable.blogspot.com/feeds/1411337621432706157/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ihumanable.blogspot.com/2009/10/tool-roundup.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5534765709337552753/posts/default/1411337621432706157'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5534765709337552753/posts/default/1411337621432706157'/><link rel='alternate' type='text/html' href='http://ihumanable.blogspot.com/2009/10/tool-roundup.html' title='tool roundup'/><author><name>Matt Nowack</name><uri>http://www.blogger.com/profile/00930543505232276126</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='20' src='http://4.bp.blogspot.com/_8IT2c3B5vQk/SsowYFU_8QI/AAAAAAAAADE/6iO_jned-r0/S220/smiles.jpeg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh3.ggpht.com/_8IT2c3B5vQk/Stx4zgrUwHI/AAAAAAAAAH0/yo2xCVtrecU/s72-c/fund_reqs.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5534765709337552753.post-1751218229971493993</id><published>2009-10-16T14:12:00.006-04:00</published><updated>2009-10-16T14:40:56.465-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='recap'/><category scheme='http://www.blogger.com/atom/ns#' term='meta'/><title type='text'>the blog experiment</title><content type='html'>&lt;img src="http://lh3.ggpht.com/_8IT2c3B5vQk/Sti9M_cTRoI/AAAAAAAAAHY/CW6ofm3XECA/s400/62288main_aldrin_ladder_full.jpg" style="float: left; padding-right: 20px" /&gt;
&lt;p&gt;So as you know, since you are reading this blog currently, I have a blog now.  Welcome to 2002, Matt, &lt;em&gt;everyone&lt;/em&gt; has a blog these days.  Now that its been running for two weeks I wanted to do a meta-post about my blog.&lt;/p&gt;
&lt;p&gt;I have a wide array of interests, from video games to progressive politics to linguistics.  I decided though that I wanted to write a technology blog to increase my professional stature on the cybernets.  It hasn't always been easy, some days I've had little inspiration in the technology part of my life, but something burning in the politics part of my brain.  I strive though to keep this blog about programming and software and sometimes rage filled rants.  When I started this blog I came up with a strategy for how I wished to drive traffic to the blog.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Post everyday - When people can reliably expect some new content they will come and look for it or set up a feed reader to your site.  &lt;a href="http://thedailywtf.com"&gt;The Daily WTF&lt;/a&gt; posts something everyday, and although most days I read the story with a "meh" I still come back every time the lunch whistle blows.&lt;/li&gt;
&lt;li&gt;More than words - I wanted to avoid the wall of text, breaking up posts with a related image, code snippet, or youtube embed makes that post more memorable and more valuable.&lt;/li&gt;
&lt;li&gt;Shameless self-promotion - Every post I write is followed up with a tweet, shouting to my co-workers about how great I am telling them to read my post, texting people, shining a special "Matt-signal" into the perpetually overcast Columbus sky&lt;/li&gt;
&lt;/ul&gt;
&lt;strong&gt;The Good:&lt;/strong&gt; 
&lt;ul&gt;
&lt;li&gt;I have had a few neat things happen so far, I've gotten comments from people I know and respect &lt;a href="http://rickdoes.net/"&gt;Rick&lt;/a&gt;, &lt;a href="http://facility9.com/"&gt;Jeremiah&lt;/a&gt;, etc.  and somewhat more exciting, comments from random people I don't know.&lt;/li&gt;
&lt;li&gt;Knowing that I need to produce content has had my creative brain juices flowing, it has spurred me to learn about ruby, powershell, and lisp.&lt;/li&gt;
&lt;li&gt;Wanting to produce quality content has caused me to dig deeper into things than I normally would have, leading to more learning, and bonus for you, better content&lt;/li&gt;
&lt;li&gt;Launched my first &lt;a href="http://capcityquest.com"&gt;self-designed website&lt;/a&gt; and had &lt;a href="http://ihumanable.blogspot.com/2009/10/first-step-into-web-design.html"&gt;somewhere to brag about it&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;strong&gt;The Bad:&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;Writing a post everyday is hard, even when I have an idea, doing the research, linking things up nicely, and trying to write something that people will want to read is a daunting task.&lt;/li&gt;
&lt;li&gt;Failed to get anyone to join up with my I'll pimp your site if you pimp mine old school 1990's style blog-ring (I really only tweeted this once so its not like I tried very hard)&lt;/li&gt;
&lt;li&gt;Scant feedback.  Sometimes starting up a blog is a lot like shouting into the darkness, it is very exciting to get a comment on a post, even when its someone disagreeing with you, at least you know someone's reading.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So I'm going to keep on keeping on, I'm going to post something everyday, I've got 4 or 5 posts saved up for a series I'm hoping to publish soon.  The blog has been a positive thing for me, it has kept me learning, communicating, and creating.&lt;/p&gt;
&lt;p&gt;Let me know what you think about the blog, the good, the bad, and the ugly.  I'm going to keep up with my post a day schedule for a while longer, so check back in daily or follow my blog to get a little sliver of goodness everyday.&lt;/p&gt;
&lt;em&gt;Post a day doesn't include weekends, people have better things to do on the weekends than read blog posts, like &lt;a href="http://ihumanable.blogspot.com/2009/10/falling-in-love.html"&gt;program lisp&lt;/a&gt;&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5534765709337552753-1751218229971493993?l=ihumanable.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ihumanable.blogspot.com/feeds/1751218229971493993/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ihumanable.blogspot.com/2009/10/blog-experiment.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5534765709337552753/posts/default/1751218229971493993'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5534765709337552753/posts/default/1751218229971493993'/><link rel='alternate' type='text/html' href='http://ihumanable.blogspot.com/2009/10/blog-experiment.html' title='the blog experiment'/><author><name>Matt Nowack</name><uri>http://www.blogger.com/profile/00930543505232276126</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='20' src='http://4.bp.blogspot.com/_8IT2c3B5vQk/SsowYFU_8QI/AAAAAAAAADE/6iO_jned-r0/S220/smiles.jpeg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh3.ggpht.com/_8IT2c3B5vQk/Sti9M_cTRoI/AAAAAAAAAHY/CW6ofm3XECA/s72-c/62288main_aldrin_ladder_full.jpg' height='72' width='72'/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5534765709337552753.post-6017226540036300570</id><published>2009-10-15T12:17:00.005-04:00</published><updated>2009-10-15T12:59:22.292-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='rant'/><category scheme='http://www.blogger.com/atom/ns#' term='google wave'/><category scheme='http://www.blogger.com/atom/ns#' term='meta'/><title type='text'>you can't understand google wave</title><content type='html'>&lt;img src="http://lh3.ggpht.com/_8IT2c3B5vQk/StdNmnsJC9I/AAAAAAAAAHU/BdUCOD2AXL0/s800/googlewavesmall.jpg" style="float: right" /&gt;
&lt;p&gt;Please everyone, just stop.  &lt;a href="http://danieltenner.com/posts/0012-google-wave.html"&gt;Everyday&lt;/a&gt; &lt;a href="http://www.slate.com/id/2232311/pagenum/all"&gt;someone&lt;/a&gt; &lt;a href="http://lifehacker.com/5381219/google-waves-best-use-cases"&gt;writes&lt;/a&gt; &lt;a href="http://mashable.com/2009/05/28/google-wave-guide/"&gt;a&lt;/a&gt; &lt;a href="http://www.techcrunch.com/2009/10/12/google-wave-and-the-dawn-of-passive-aggressive-communication/"&gt;new&lt;/a&gt; &lt;a href="http://lifehacker.com/5285944/the-google-wave-highlight-reel"&gt;article&lt;/a&gt; &lt;a href="http://radar.oreilly.com/2009/05/google-wave-what-might-email-l.html"&gt;about&lt;/a&gt; &lt;a href="http://wave.google.com/"&gt;Google Wave&lt;/a&gt;.  If you are writing a first impressions, explanation, frequently asked questions type of article, go ahead, this rant is not aimed at you.  The rest of you people writing reviews, glowing or scathing, you can't understand Google Wave, yet.&lt;/p&gt;
&lt;p&gt;Google Wave is big, that's for sure, its got a Federated Protocol and XMPP and PubSub and all kinds of neat technology.  It has an interface too, half email, half chat client, half sentient alien technology.  The problem with people waxing inanely about what Google Wave will be is that they have their heads up their asses.  They don't know, because they can't know.&lt;/p&gt;
&lt;p&gt;Let's go back to 1975 and somebody explains the idea of the World Wide Web, they go on and on about HyperText Transfer Protocols and HyperText Markup Language and they show you the &lt;a href="http://www.w3.org/History/19921103-hypertext/hypertext/WWW/TheProject.html"&gt;first webpage&lt;/a&gt;.  Imagine that instead of being the tech savvy web surfing person that you are that you have no idea what HyperText or Uniform Resource Locators are, this is where we are at with Google Wave.&lt;/p&gt;
&lt;p&gt;The idea behind it is complex, the foundations are new (at least in application) and also very complex, and the future of Google Wave is unknown, more than that it is unknowable.  Could &lt;a href="http://www.w3.org/People/Berners-Lee/"&gt;Tim Berners-Lee&lt;/a&gt; have guessed what we would be doing with his invention today, could he have dreamed of web applications, twitter, social networking.  I guess he could have, but it wouldn't have been immediately apparent.&lt;/p&gt;
&lt;div class="embed-wrap"&gt;
&lt;object width="560" height="340"&gt;&lt;param name="movie" value="http://www.youtube.com/v/v_UyVmITiYQ&amp;hl=en&amp;fs=1&amp;"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/v_UyVmITiYQ&amp;hl=en&amp;fs=1&amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="560" height="340"&gt;&lt;/embed&gt;&lt;/object&gt;
&lt;/div&gt;
&lt;p&gt;The technology is too new, it could be a new World Wide Web, or it could be a &lt;a href="http://en.wikipedia.org/wiki/Gopher_%28protocol%29"&gt;Gopher&lt;/a&gt;.  We won't know until we see what people create with it.  Google has already produced a collaboration tool that looks very promising, and people &lt;a href="http://www.victusspiritus.com/2009/10/13/google-wave-aha-moment-withpublic-is-awesome/"&gt;are already finding surprising ways to use it&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;So if you want to vacillate and bloviate about Google Wave continue doing so, I certainly can't stop you, but you might go down in history as the &lt;a href="http://www.newsweek.com/id/106554/page/1"&gt;guy who called the internet a fad&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5534765709337552753-6017226540036300570?l=ihumanable.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ihumanable.blogspot.com/feeds/6017226540036300570/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ihumanable.blogspot.com/2009/10/you-cant-understand-google-wave.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5534765709337552753/posts/default/6017226540036300570'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5534765709337552753/posts/default/6017226540036300570'/><link rel='alternate' type='text/html' href='http://ihumanable.blogspot.com/2009/10/you-cant-understand-google-wave.html' title='you can&apos;t understand google wave'/><author><name>Matt Nowack</name><uri>http://www.blogger.com/profile/00930543505232276126</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='20' src='http://4.bp.blogspot.com/_8IT2c3B5vQk/SsowYFU_8QI/AAAAAAAAADE/6iO_jned-r0/S220/smiles.jpeg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh3.ggpht.com/_8IT2c3B5vQk/StdNmnsJC9I/AAAAAAAAAHU/BdUCOD2AXL0/s72-c/googlewavesmall.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5534765709337552753.post-8718786959919914326</id><published>2009-10-14T13:16:00.003-04:00</published><updated>2009-10-14T13:53:28.233-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='lisp'/><category scheme='http://www.blogger.com/atom/ns#' term='free'/><category scheme='http://www.blogger.com/atom/ns#' term='ebook'/><title type='text'>falling in love</title><content type='html'>&lt;p&gt;I'm home from work today, sick.  Being sick is no fun, I think it is just a cold, hopefully back to work tomorrow.  The only good thing about being sick is that it gives me time to spend with my new love.  I fell in love yesterday.  She is brilliant, straight forward, strong, and has sexy sexy curves.  As I slept last night, my dreams were filled by her.  I'm so taken by her beauty, her power, and again, the curves.  By this point we should all know that I'm talking about the sweetest flower, lisp.&lt;/p&gt;
&lt;a href="http://www.gigamonkeys.com/book/"&gt;&lt;img src="http://lh5.ggpht.com/_8IT2c3B5vQk/StYJfuOMEOI/AAAAAAAAAGw/GVR_WzB-Zys/s144/small-cover.gif" style="float: right" /&gt;&lt;/a&gt;
&lt;p&gt;I have always intended to learn lisp better.  It's one of those languages, where, if you are a language wonk like me, just seems to keep coming up.  It's one of those beautiful, almost mythological pieces of technology that no one uses, but it just seems to come back up.  I wrote yesterday in &lt;a href="http://ihumanable.blogspot.com/2009/10/future-javascript.html"&gt;the future: javavscript&lt;/a&gt; that javascript is lisp dressed in C's clothing (and in actuality I stole that quote from Douglas Crockford).  Lisp is one of those magical languages that was developed in 1956 and seems to have had within it every important language feature that we take for granted today.  Just like with &lt;a href="http://www.parc.com/about/milestones.html"&gt;Xerox PARC&lt;/a&gt; seems to have, in 1975, created every single GUI feature that is now common place, lisp is that for programming languages.&lt;/p&gt;
&lt;p&gt;A lot of people will say that lisp is dead, that it isn't worth learning, that no one uses it, and there is no money or projects in it.  I won't try to dispute these statements, &lt;a href="http://www.gigamonkeys.com/book/introduction-why-lisp.html"&gt;Peter Seibel&lt;/a&gt; does a better job than I can.  What I want to argue is that lisp is &lt;em&gt;&lt;strong&gt;worth learning&lt;/strong&gt;&lt;/em&gt;, dead or alive.&lt;/p&gt;
&lt;p&gt;So here it is, plain and simple&lt;/p&gt;
&lt;blockquote&gt;Lisp is the Latin of Programming&lt;/blockquote&gt;
&lt;p&gt;Learning Latin may not help you in your day to day conversation, but understanding declension, Latin grammar, and Latin vocabulary, can help you better understand your own language, or any language with roots in Latin.  The same holds true for lisp, so many languages and language features have their roots in lisp.  Macros, recursion, lambdas, the list goes on and on, learning the roots of these concepts in lisp, illuminates your understanding in other languages.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Want to understand Ruby better, &lt;a href="http://www.gigamonkeys.com/book/"&gt;learn lisp&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Want to understand functional languages better, &lt;a href="http://www.gigamonkeys.com/book/"&gt;learn lisp&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Want to understand JavaScript better, &lt;a href="http://www.gigamonkeys.com/book/"&gt;learn lisp&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Want to improve your development skills, &lt;a href="http://www.gigamonkeys.com/book/"&gt;learn lisp&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Want to be a better developer, &lt;a href="http://www.gigamonkeys.com/book/"&gt;learn lisp&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I have always wanted to learn lisp, but I could never find a source of learning that wasn't either obtusely academic, or painfully slow.  I wanted a book that was written for programmers, I don't need you to explain the concept of a variable to me, I also don't want to have to write out a formal S-expression proof.  I hold high hopes for &lt;a href="http://www.amazon.com/gp/product/1593272006"&gt;Land of Lisp: Learn to Program in Lisp, One Game at a Time!&lt;/a&gt; but sadly it is not out yet.  I came across a fantastic free book online called &lt;a href="http://www.gigamonkeys.com/book/"&gt;Practical Common Lisp&lt;/a&gt; and within an hour of reading through it have a fully functional CD database with a DSL that models SQL written completely in lisp, in just about 50 lines of code.&lt;/p&gt;
&lt;p&gt;It is the &lt;strong&gt;Practical&lt;/strong&gt; part of this book that is so great.  You learn as you go, you build programs up that actually do things, and because of REPL you build incrementally, seeing your environment get more and more feature rich.  I find myself unable to stop, for the first time in a while its a book that I treat like a video game, I just need to beat this next boss and then I can save and go eat dinner, ok maybe just one more level, whoa how did it get so late?  It is a book that I lose myself in, fantastically well written, great examples, and a true feeling of discovery.&lt;/p&gt;
&lt;p&gt;So pick up lisp, especially pick up &lt;a href="http://www.gigamonkeys.com/book/"&gt;Practical Common Lisp&lt;/a&gt; and give it a try.  I know that I will be spending the rest of my day reading through it, and eating some chicken noodle soup.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5534765709337552753-8718786959919914326?l=ihumanable.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ihumanable.blogspot.com/feeds/8718786959919914326/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ihumanable.blogspot.com/2009/10/falling-in-love.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5534765709337552753/posts/default/8718786959919914326'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5534765709337552753/posts/default/8718786959919914326'/><link rel='alternate' type='text/html' href='http://ihumanable.blogspot.com/2009/10/falling-in-love.html' title='falling in love'/><author><name>Matt Nowack</name><uri>http://www.blogger.com/profile/00930543505232276126</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='20' src='http://4.bp.blogspot.com/_8IT2c3B5vQk/SsowYFU_8QI/AAAAAAAAADE/6iO_jned-r0/S220/smiles.jpeg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh5.ggpht.com/_8IT2c3B5vQk/StYJfuOMEOI/AAAAAAAAAGw/GVR_WzB-Zys/s72-c/small-cover.gif' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5534765709337552753.post-766320823990344473</id><published>2009-10-13T14:32:00.007-04:00</published><updated>2009-10-13T15:36:35.968-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='chrome'/><category scheme='http://www.blogger.com/atom/ns#' term='future'/><title type='text'>the future: javascript</title><content type='html'>&lt;p&gt;JavaScript is awesome.  I'm going to say this unabashedly, there may be no language I love more than JavaScript.  Truly cross platform, unique, glorious in its many ways, its lisp dressed up in C's clothing.   Want to know about the origins of JavaScript, go watch Douglas Crockford's &lt;a href="http://video.yahoo.com/watch/111593/1710507"&gt;amazing talk&lt;/a&gt; or &lt;a href="http://www.crockford.com/javascript/javascript.html"&gt;read his synopsis&lt;/a&gt;.
&lt;div class="embed-wrap"&gt;&lt;object width="512" height="322"&gt;&lt;param name="movie" value="http://d.yimg.com/static.video.yahoo.com/yep/YV_YEP.swf?ver=2.2.46" /&gt;&lt;param name="allowFullScreen" value="true" /&gt;&lt;param name="AllowScriptAccess" VALUE="always" /&gt;&lt;param name="bgcolor" value="#000000" /&gt;&lt;param name="flashVars" value="id=1710507&amp;vid=111593&amp;lang=en-us&amp;intl=us&amp;thumbUrl=http%3A//l.yimg.com/a/i/us/sch/cn/v/v0/w327/111593_320_240.jpeg&amp;embed=1" /&gt;&lt;embed src="http://d.yimg.com/static.video.yahoo.com/yep/YV_YEP.swf?ver=2.2.46" type="application/x-shockwave-flash" width="512" height="322" allowFullScreen="true" AllowScriptAccess="always" bgcolor="#000000" flashVars="id=1710507&amp;vid=111593&amp;lang=en-us&amp;intl=us&amp;thumbUrl=http%3A//l.yimg.com/a/i/us/sch/cn/v/v0/w327/111593_320_240.jpeg&amp;embed=1" &gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;a href="http://video.yahoo.com/watch/111593/1710507"&gt;Douglas Crockford: &amp;quot;The JavaScript Programming Language&amp;quot;/1 of 4&lt;/a&gt; @ &lt;a href="http://video.yahoo.com" &gt;Yahoo! Video&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;A lot of people get soured by JavaScript not because of any fault in the language but because of the horrible non-cross browser compatible DOM.  John Resig of jQuery fame, now working for Mozilla, has a &lt;a href="http://ejohn.org/blog/the-dom-is-a-mess/"&gt;great talk about this&lt;/a&gt;.&lt;/p&gt;
 &lt;div class="embed-wrap"&gt;&lt;object width="512" height="322"&gt;&lt;param name="movie" value="http://d.yimg.com/static.video.yahoo.com/yep/YV_YEP.swf?ver=2.2.46" /&gt;&lt;param name="allowFullScreen" value="true" /&gt;&lt;param name="AllowScriptAccess" VALUE="always" /&gt;&lt;param name="bgcolor" value="#000000" /&gt;&lt;param name="flashVars" value="id=11812238&amp;vid=4403981&amp;lang=en-us&amp;intl=us&amp;thumbUrl=http%3A//l.yimg.com/a/p/i/bcst/videosearch/899/79387316.jpeg&amp;embed=1" /&gt;&lt;embed src="http://d.yimg.com/static.video.yahoo.com/yep/YV_YEP.swf?ver=2.2.46" type="application/x-shockwave-flash" width="512" height="322" allowFullScreen="true" AllowScriptAccess="always" bgcolor="#000000" flashVars="id=11812238&amp;vid=4403981&amp;lang=en-us&amp;intl=us&amp;thumbUrl=http%3A//l.yimg.com/a/p/i/bcst/videosearch/899/79387316.jpeg&amp;embed=1" &gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;a href="http://video.yahoo.com/watch/4403981/11812238"&gt;John Resig: &amp;quot;The DOM Is a  Mess&amp;quot;&lt;/a&gt; @ &lt;a href="http://video.yahoo.com" &gt;Yahoo! Video&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;I would like to declare today, in no uncertain terms that &lt;strong&gt;JavaScript is the future&lt;/strong&gt;  Would you care to disagree with me?  That's nice, get your own blog, or leave a snarky comment, I intend to prove it.&lt;/p&gt;
&lt;p&gt;JavaScript has been plagued with numerous problems in the past, buggy implementations, DOM nightmares, speed issues, and general abuse.  But today we have a perfect storm of things occurring that mean that if you don't know JavaScript, start learning.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Thing the first&lt;/strong&gt;: Google is producing a new operating system &lt;a href="http://googleblog.blogspot.com/2009/07/introducing-google-chrome-os.html"&gt;Chrome OS&lt;/a&gt;.&lt;/p&gt;
&lt;blockquote&gt;Speed, simplicity and security are the key aspects of Google Chrome OS. We're designing the OS to be fast and lightweight, to start up and get you onto the web in a few seconds. The user interface is minimal to stay out of your way, and &lt;em&gt;&lt;strong&gt;most of the user experience takes place on the web.&lt;/strong&gt;&lt;/em&gt;&lt;/blockquote&gt;
&lt;p&gt;You have the massive juggernaut saying that their OS is going to be web-centric.  Along with the mindshare that has moved over to JavaScript for the web, this is going to push more of the best and brightest over to the JavaScript side.  I have a sneaking suspicion that they will have an OS API in JavaScript, I base this off the fact that when Google last took to the desktop they &lt;a href="http://code.google.com/apis/desktop/docs/gadgetapi.html"&gt;did exactly that&lt;/a&gt;.  This isn't JavaScript's &lt;a href="http://www.appcelerator.com/"&gt;first&lt;/a&gt; &lt;a href="http://www.adobe.com/products/air/"&gt;dance&lt;/a&gt; &lt;a href="http://www.jaxer.org/"&gt;outside&lt;/a&gt; &lt;a href="http://narwhaljs.org/"&gt;the&lt;/a&gt; &lt;a href="http://en.wikipedia.org/wiki/Server-side_JavaScript"&gt;browser&lt;/a&gt;, but with native support it might be the most important.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Thing the second&lt;/strong&gt;:  Speed.  The big browser makers are in a shooting war speed wise, and we are all winners.  &lt;a href="https://wiki.mozilla.org/JavaScript:TraceMonkey"&gt;Native code compilation&lt;/a&gt;, &lt;a href="http://code.google.com/p/v8/"&gt;more horsepower&lt;/a&gt;, and &lt;a href="http://www.apple.com/safari/whats-new.html"&gt;pure competition&lt;/a&gt; have led to a wide array of speed improvements.  All signs point to this only getting better, people are attacking the problem from all angles, and as these solutions combine, all the while Moore's Law keeps on running, we are looking at outrageous speed for JavaScript execution.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Thing the third&lt;/strong&gt;:  JavaScript is actually a really awesome language.  Things that people are going crazy about in other languages, JavaScript has had from the outset.  Let's see:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Closures... check!&lt;/li&gt;
&lt;li&gt;First class functions... check!&lt;/li&gt;
&lt;li&gt;Regex literals... check!&lt;/li&gt;
&lt;li&gt;Huge ecosystem... check!&lt;/li&gt;
&lt;li&gt;Objects... check!&lt;/li&gt;
&lt;li&gt;Consistent comprehensible object notation... check!&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;When it get's down to it, JavaScript is a great language.  It has a ton of exposure, and a huge amount of developer mindshare.  JavaScript isn't going away anytime soon, and considering how hard it is to get browser vendor's to agree, isn't getting replaced anytime soon.  JavaScript will become more and more prevalent both on the server and on the desktop.  I welcome our new prototype based overlord, and so should you.&lt;/p&gt;
&lt;p&gt;Pick up &lt;a href="http://oreilly.com/catalog/9780596517748"&gt;Douglas Crockford's JavaScript: The Good Parts&lt;/a&gt;.  Work through &lt;a href="http://ejohn.org/apps/learn/#1"&gt;John Resig's Learning Advanced JavaScript&lt;/a&gt;.  Check out &lt;a href="http://jquery.com/"&gt;the present&lt;/a&gt; and &lt;a href="http://www.whatwg.org/specs/web-workers/current-work/"&gt;dream of what could be.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Once you start learning JavaScript, you will see an amazing language that for too long has been relegated to changing label colors and hiding page elements.  I expect the future to hold great things for this little language.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5534765709337552753-766320823990344473?l=ihumanable.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ihumanable.blogspot.com/feeds/766320823990344473/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ihumanable.blogspot.com/2009/10/future-javascript.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5534765709337552753/posts/default/766320823990344473'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5534765709337552753/posts/default/766320823990344473'/><link rel='alternate' type='text/html' href='http://ihumanable.blogspot.com/2009/10/future-javascript.html' title='the future: javascript'/><author><name>Matt Nowack</name><uri>http://www.blogger.com/profile/00930543505232276126</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='20' src='http://4.bp.blogspot.com/_8IT2c3B5vQk/SsowYFU_8QI/AAAAAAAAADE/6iO_jned-r0/S220/smiles.jpeg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5534765709337552753.post-1802318020192080172</id><published>2009-10-12T14:16:00.004-04:00</published><updated>2009-10-12T14:45:23.654-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='rant'/><category scheme='http://www.blogger.com/atom/ns#' term='development'/><category scheme='http://www.blogger.com/atom/ns#' term='meta'/><title type='text'>perception is _not_ reality</title><content type='html'>&lt;p&gt;Perception is reality.  This is a sentiment that has taken hold in the modern age, and it's easy to see why.  We live in a world of constant spin, it's not that this spin didn't exist in the past, it's just that we are bombarded with it.  The thing people weren't prepared for was that the information age was to be accompanied by the misinformation age.  We have unfettered access to mountains of data, so many voices, look I'm one more.&lt;/p&gt;
&lt;p&gt;So the question in this new age is, how do we separate perception from reality?  And then someone said it, really thousands if not millions of people said it.&lt;/p&gt;
&lt;blockquote&gt;Perception &lt;em&gt;is&lt;/em&gt; Reality&lt;/blockquote&gt;
&lt;p&gt;With the air of a Matrix quote and with about as much meaning, it is a seductive little phrase.  It has a simple elegance about it, it says just enough to sound deep without saying anything at all.  It's also a sort of self proving maxim, since the only thing we experience is our own perception, it makes sense, that is our reality.  Another aspect of it's seductive power is that it is oddly freeing, it says, there is no reality that you don't make.  It takes you from an observer of reality to the actor and center, it is &lt;strong&gt;your&lt;/strong&gt; perceptions that form reality.&lt;/p&gt;
&lt;img src="http://lh3.ggpht.com/_8IT2c3B5vQk/StN1mKWPHVI/AAAAAAAAAF0/351quyXLdBM/s800/g37_ptolemy.gif" style="float: right" /&gt;
&lt;p&gt;And this is why it's an intellectually dishonest concept.  It is easy to look up at the Sun and perceive that it is circling the Earth, but that doesn't make it real.   It is simple to look at a table and feel the surface and perceive that it is solid, the reality is that it's mostly empty space.  Perception is that first attempt to understand reality, not the end of understanding.&lt;/p&gt;
&lt;p&gt;Perception is &lt;strong&gt;not&lt;/strong&gt; reality.  This does not stop people from believing this foolishness.&lt;/p&gt;
&lt;p&gt;Did you spend weeks writing that application, fine tuning it to run fast and work reliably?  Great.  Ship it off and the user that's running AOL 6.0 with BearShare in the background and clicking away with Comet Cursor (because they want their mouse pointer to look like a fluffy kitty) is going to fire up your application and think that you are a terrible programmer because its slow as molasses on their overworked machine.  Didn't you perform compatibility tests with the unpatched pirated version of Norton Web Defender 0.8beta that the user is running, what in the hell is wrong with you?!&lt;/p&gt;
&lt;p&gt;The problem is that in a complex enough system people's ability to make reasoned and rational evaluations break down.  The cognitive load of the person using your application is normally completely saturated with whatever task the application is intended to perform.  This is why troubleshooting from a user's perspective is frustrating and magical.  And why as a developer you have to take everything the user tells you with the understanding that they have no idea how a computer functions.&lt;/p&gt;
&lt;p&gt;It is frustrating to be on the wrong end of the blame stick for something that BearShare did, but it happens.  The best we can hope to do is educate the user, patch up our software, and keep plugging away.&lt;/p&gt;
&lt;p&gt;Perception &lt;strong&gt;is&lt;/strong&gt; reality to the user, and that is a reality that we as developers have to come to grips with.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;
&lt;p&gt;&lt;em&gt;I'm working on a multipart series that should begin to see the light of day this week, I was going to start today but wanted to have a little bit more meat before publishing.  Stay tuned...&lt;/em&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5534765709337552753-1802318020192080172?l=ihumanable.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ihumanable.blogspot.com/feeds/1802318020192080172/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ihumanable.blogspot.com/2009/10/perception-is-not-reality.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5534765709337552753/posts/default/1802318020192080172'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5534765709337552753/posts/default/1802318020192080172'/><link rel='alternate' type='text/html' href='http://ihumanable.blogspot.com/2009/10/perception-is-not-reality.html' title='perception is _not_ reality'/><author><name>Matt Nowack</name><uri>http://www.blogger.com/profile/00930543505232276126</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='20' src='http://4.bp.blogspot.com/_8IT2c3B5vQk/SsowYFU_8QI/AAAAAAAAADE/6iO_jned-r0/S220/smiles.jpeg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh3.ggpht.com/_8IT2c3B5vQk/StN1mKWPHVI/AAAAAAAAAF0/351quyXLdBM/s72-c/g37_ptolemy.gif' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5534765709337552753.post-5810095953047945564</id><published>2009-10-09T11:16:00.005-04:00</published><updated>2009-10-09T13:19:51.852-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='anti-pattern'/><category scheme='http://www.blogger.com/atom/ns#' term='sharpening the saw'/><category scheme='http://www.blogger.com/atom/ns#' term='gof'/><title type='text'>sharpening the saw</title><content type='html'>&lt;img src="http://lh4.ggpht.com/_8IT2c3B5vQk/Ss9uR7PZmzI/AAAAAAAAAFM/dUKmH8-B1yM/s800/saw.png" style="float:left" /&gt;
&lt;p&gt;The other day I was reading some delicious &lt;a href="http://en.wikipedia.org/wiki/Design_Patterns_%28book%29"&gt;GoF&lt;/a&gt; and even though it was published 15 years ago, it still is a great read.  I've never read it before and going into it I read several wise people basically saying the same thing, "After reading it, don't go overboard."&lt;/p&gt;
&lt;p&gt;Apparently, there is a propensity to overuse the patterns and make a bigger mess than using no patterns at all.  Being fully aware of this fact, and with the good fortune of not being a silly n00b and actually having experience using many of the design patterns I'm currently reading about in the real world, it got me thinking as to why people would overuse the patterns.  I think it is because the book is a sublime piece of work, the patterns are expressed succinctly, the examples are clear, and the code that is produced is readable and understandable.  The problem domains are complex but well suited to pattern application.  In reading the book you get an impression that patterns make things better, and that because when skillfully applied they generally do.&lt;/p&gt;
&lt;p&gt;The problem is that there is a lack of examples of when a pattern bites you, when the inartful application of patterns leaves you fighting against an army of delegates, bridges, and command objects.  This got me thinking about pattern-abuse's cousin, &lt;strong&gt;the anti-pattern&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;The anti-pattern is something that very few people ever study or know the names of, but they pop up all over and most of us have to deal with them on a daily basis.  For education's sake I've picked the best one's from &lt;a href="http://en.wikipedia.org/wiki/Anti-pattern#Known_anti-patterns"&gt;Wikipedia's excellent list.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Abstraction Inversion&lt;/strong&gt; - 
&lt;blockquote&gt;An anti-pattern arising when users of a construct need functions implemented within it but not exposed by its interface. The result is that the users re-implement the required functions in terms of the interface, which in its turn uses the internal implementation of the same functions.&lt;/blockquote&gt;
The most egregious example of this that I can think of is languages that don't treat functions as first class objects.  This is the cause of &lt;a href="http://java.sun.com/docs/books/tutorial/reflect/member/methodInvocation.html"&gt;fun code like this&lt;/a&gt;&lt;/p&gt;
&lt;pre class="brush: java;"&gt;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.Locale;
import static java.lang.System.out;
import static java.lang.System.err;

public class Deet&amp;lt;T&amp;gt; {
  private boolean testDeet(Locale l) {
    // getISO3Language() may throw a MissingResourceException
    out.format("Locale = %s, ISO Language Code = %s%n", l.getDisplayName(), l.getISO3Language());
    return true;
  }

  private int testFoo(Locale l) { return 0; }
  private boolean testBar() { return true; }

  public static void main(String... args) {
    if (args.length != 4) {
      return;
    }
    
    try {
      Class&amp;lt;?&amp;gt; c = Class.forName(args[0]);
      Object t = c.newInstance();

      Method[] allMethods = c.getDeclaredMethods();
      for (Method m : allMethods) {
        String mname = m.getName();
        if (!mname.startsWith("test") || (m.getGenericReturnType() != boolean.class)) {
          continue;
        }
        Type[] pType = m.getGenericParameterTypes();
        if ((pType.length != 1) || Locale.class.isAssignableFrom(pType[0].getClass())) {
          continue;
        }

        out.format("invoking %s()%n", mname);
        try {
          m.setAccessible(true);
          Object o = m.invoke(t, new Locale(args[1], args[2], args[3]));
          out.format("%s() returned %b%n", mname, (Boolean) o);

          // Handle any exceptions thrown by method to be invoked.
        } catch (InvocationTargetException x) {
          Throwable cause = x.getCause();
          err.format("invocation of %s failed: %s%n", mname, cause.getMessage());
        }
     }

     // production code should handle these exceptions more gracefully
  } catch (ClassNotFoundException x) {
    x.printStackTrace();
  } catch (InstantiationException x) {
    x.printStackTrace();
  } catch (IllegalAccessException x) {
    x.printStackTrace();
  }
}
&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Expection Handling&lt;/strong&gt; (a portmanteau of expect and exception) - 
&lt;blockquote&gt;Using a language's error handling system to implement normal program logic&lt;/blockquote&gt;
You shouldn't do this, if you are, you are doing your job wrong, stop that.  The catch block should be used to perform exception handling, that's it.
&lt;/p&gt;
&lt;img src="http://lh5.ggpht.com/_8IT2c3B5vQk/Ss9uR37-__I/AAAAAAAAAFI/OAamFwg8sco/s800/gold-hammer.png" style="float: right"/&gt;
&lt;p&gt;&lt;strong&gt;Golden Hammer&lt;/strong&gt; aka &lt;strong&gt;Silver Bullet&lt;/strong&gt; - 
&lt;blockquote&gt;"When the only tool you have is a hammer, it is tempting to treat everything as if it were a nail. - &lt;em&gt;Abraham Maslow&lt;/em&gt;&lt;/blockquote&gt;
&lt;strong&gt;If you read the GoF Design Patterns book and then proceed to use Design Patterns everywhere, this is your anti-pattern!&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;The GoF book was so groundbreaking because it allowed us to encapsulate and share knowledge.  Design Patterns are to our brains and conversations what classes are to compilers.  For the first time we could talk to people we didn't know about implementing the Visitor pattern to solve a problem, and all parties involved knew what the other was talking about.&lt;/p&gt;
&lt;p&gt;Maybe its time someone wrote a comprehensive anti-pattern book, and so we could stop saying that code smells, and really identify the anti-pattern at work.  Being able to identify bad code is just as important as being able to write good code.&lt;/p&gt;
&lt;p&gt;I only scratched the surface of anti-patterns. Go read the rest of the list for yourself, then try to identify if you are using anti-patterns in your code, then &lt;strong&gt;REFACTOR!&lt;/strong&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5534765709337552753-5810095953047945564?l=ihumanable.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ihumanable.blogspot.com/feeds/5810095953047945564/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ihumanable.blogspot.com/2009/10/sharpening-saw.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5534765709337552753/posts/default/5810095953047945564'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5534765709337552753/posts/default/5810095953047945564'/><link rel='alternate' type='text/html' href='http://ihumanable.blogspot.com/2009/10/sharpening-saw.html' title='sharpening the saw'/><author><name>Matt Nowack</name><uri>http://www.blogger.com/profile/00930543505232276126</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='20' src='http://4.bp.blogspot.com/_8IT2c3B5vQk/SsowYFU_8QI/AAAAAAAAADE/6iO_jned-r0/S220/smiles.jpeg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh4.ggpht.com/_8IT2c3B5vQk/Ss9uR7PZmzI/AAAAAAAAAFM/dUKmH8-B1yM/s72-c/saw.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5534765709337552753.post-2458438616737836859</id><published>2009-10-07T21:35:00.006-04:00</published><updated>2009-10-08T09:25:51.156-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ccq'/><category scheme='http://www.blogger.com/atom/ns#' term='graphics'/><category scheme='http://www.blogger.com/atom/ns#' term='design'/><category scheme='http://www.blogger.com/atom/ns#' term='side project'/><title type='text'>first step into web design</title><content type='html'>&lt;img src="http://lh4.ggpht.com/_8IT2c3B5vQk/Ss1CZqe8ejI/AAAAAAAAAEU/Dz4fthIOeNs/s400/programmer-graphics.jpg" style="float: right"/&gt;
&lt;p&gt;I have degrees in Computer Science and Mathematics, this means that I'm a huge nerd, it also means that I should, under no circumstances, attempt to design things.  What happens when programmers try to design graphics?  Normally they come out badly, our brains just aren't wired for making things look nice.  There are of course exceptions, but do a google image search for "programmer graphics" and you will find thousands of examples of terrible, terrible artwork. Here is one I found that exemplifies what I'm talking about&lt;/p&gt;
&lt;p&gt;Scary isn't it?  Well us programmers and mathematicians should be kept far far away from designing things.  We also like to break the rules and in that spirit I would like to announce that my first wholly designed site is now live.  It is for my friend Tim's band, &lt;a href="http://www.capcityquest.com/"&gt;Cap City Quest&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I think the design is passable, what with blueprint css and jquery plugins, these websites basically make themselves these days.  Making it did reinforce a very good lesson, &lt;strong&gt;Do what you are good at, farm out the rest&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;So this was my first step into an actual public facing site design.  I think I did ok, if you have suggestions feel free to leave them here.  If you want me to design you a site with sweet delicious jquery and blueprint and maybe even some dynamic content, leave me a comment.  This site took about 10-12 hours of work, it was a quick one off project, but I enjoyed it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;If you missed the link up above, go and view it now &lt;a href="http://www.capcityquest.com/"&gt;Cap City Quest&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5534765709337552753-2458438616737836859?l=ihumanable.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ihumanable.blogspot.com/feeds/2458438616737836859/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ihumanable.blogspot.com/2009/10/first-step-into-web-design.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5534765709337552753/posts/default/2458438616737836859'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5534765709337552753/posts/default/2458438616737836859'/><link rel='alternate' type='text/html' href='http://ihumanable.blogspot.com/2009/10/first-step-into-web-design.html' title='first step into web design'/><author><name>Matt Nowack</name><uri>http://www.blogger.com/profile/00930543505232276126</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='20' src='http://4.bp.blogspot.com/_8IT2c3B5vQk/SsowYFU_8QI/AAAAAAAAADE/6iO_jned-r0/S220/smiles.jpeg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh4.ggpht.com/_8IT2c3B5vQk/Ss1CZqe8ejI/AAAAAAAAAEU/Dz4fthIOeNs/s72-c/programmer-graphics.jpg' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5534765709337552753.post-8410288537346637227</id><published>2009-10-07T13:17:00.006-04:00</published><updated>2009-10-07T14:37:38.539-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='open source'/><category scheme='http://www.blogger.com/atom/ns#' term='powershell'/><category scheme='http://www.blogger.com/atom/ns#' term='windows'/><title type='text'>just because its better doesn't mean its good</title><content type='html'>&lt;p&gt;I recently wrote a blog post called &lt;a href="http://ihumanable.blogspot.com/2009/10/why-no-love-for-scripting-languages.html"&gt;why no love for scripting languages&lt;/a&gt; lamenting the lack of open source scripting environments in Windows 7.  I got some interesting feedback, most of which went along the lines of "POWERSHELL!!!1!!one!"&lt;/p&gt;
&lt;p&gt;Being an interested fellow I took it upon myself to look up PowerShell, and it looks like a nice language, really good for administrative tasks.  So I read some of the manual and it looked ok, and I started looking for some scripts that would compare old school .bat to the new PowerShell.  I found what I was looking for here &lt;a href="http://www.robvanderwoude.com/powershellexamples.php"&gt;PowerShell Examples&lt;/a&gt;.  We will be looking at an example that displays the current date.&lt;/p&gt;
&lt;pre class="brush: shell"&gt;
@ECHO OFF
IF NOT "%1"=="" GOTO Syntax

:: Use BATCHMAN to retrieve day
BATCHMAN DAY
:: Errorlevel 0 means BATCHMAN was not found
IF NOT ERRORLEVEL 1 GOTO NotFound
FOR %%A IN   (1 2 3 4 5 6 7 8 9) DO IF ERRORLEVEL  %%A SET DD=0%%A
FOR %%A IN (0 1 2 3 4 5 6 7 8 9) DO IF ERRORLEVEL 1%%A SET DD=1%%A
FOR %%A IN (0 1 2 3 4 5 6 7 8 9) DO IF ERRORLEVEL 2%%A SET DD=2%%A
FOR %%A IN (0 1)                 DO IF ERRORLEVEL 3%%A SET DD=3%%A

:: Use BATCHMAN to retrieve month
BATCHMAN MONTH
FOR %%A IN (1 2 3 4 5 6 7 8 9) DO IF ERRORLEVEL  %%A SET MM=0%%A
FOR %%A IN (0 1 2)             DO IF ERRORLEVEL 1%%A SET MM=1%%A

:: Use BATCHMAN to retrieve year
BATCHMAN YEAR
FOR %%A IN (0 1 2 3 4 5 6 7 8 9) DO IF ERRORLEVEL  %%A SET YYYY=198%%A
FOR %%A IN (0 1 2 3 4 5 6 7 8 9) DO IF ERRORLEVEL 1%%A SET YYYY=199%%A
FOR %%A IN (0 1 2 3 4 5 6 7 8 9) DO IF ERRORLEVEL 2%%A SET YYYY=200%%A
FOR %%A IN (0 1 2 3 4 5 6 7 8 9) DO IF ERRORLEVEL 3%%A SET YYYY=201%%A

:: Store in variable and clean up temporary variables
SET SortDate=%YYYY%%MM%%DD%
SET YYYY=
SET MM=
SET DD=

:: Display the result
ECHO.
ECHO SortDate = %SortDate%
GOTO End

:Syntax
ECHO.
ECHO SortDate.bat,  Version 1.00 for MS-DOS
ECHO Display the current date in YYYYMMDD format
ECHO.
ECHO Usage:  SORTDATE
ECHO.
ECHO This batch file uses BATCHMAN, a utility by Michael Mefford
ECHO.
ECHO Written by Rob van der Woude
ECHO http://www.robvanderwoude.com

:End
&lt;/pre&gt;
&lt;p&gt;Rough, if you've ever had to write anything non-trivial in batch you will start to feel that pain at the back of your eyes right now, this is your brain trying to eat your memories.  Batch is hideous, and difficult to write, and gross, and everyone hates it.  Don't believe me, well you don't have to, Microsoft agreed with me and began development on Monad in 2003, this project would become PowerShell.  Now let's look at the PowerShell equivalent of this code&lt;/p&gt;
&lt;pre class="brush: powershell"&gt;
""
"Date / Format   YYYYMMDD        DD-MM-YYYY        MM/DD/YYYY"
"============================================================"
"Yesterday       " + (get-date (get-date).AddDays(-1) -uformat %Y%m%d) + "        " + (get-date (get-date).AddDays(-1) -uformat %d-%m-%Y) + "        " + (get-date (get-date).AddDays(-1) -uformat %m/%d/%Y)
"Today           " + (get-date -uformat %Y%m%d)                        + "        " + (get-date (get-date)             -uformat %d-%m-%Y) + "        " + (get-date (get-date)             -uformat %m/%d/%Y)
"Tomorrow        " + (get-date (get-date).AddDays(1)  -uformat %Y%m%d) + "        " + (get-date (get-date).AddDays(1)  -uformat %d-%m-%Y) + "        " + (get-date (get-date).AddDays(1)  -uformat %m/%d/%Y)
&lt;/pre&gt;
&lt;p&gt;That is much better.  I see some stuff that looks like objects in there (I'm definitely seeing the dot operator).  I'm a n00b to PowerShell and yet this code is easy to grok and all and all very pretty.  Nicely done Microsoft, you get a cookie.&lt;/p&gt;
&lt;p&gt;Well this would be a pretty boring post if I just went around patting Microsoft on the head for doing a good job.  The interesting thing about &lt;a href="http://www.robvanderwoude.com/powershellexamples.php"&gt;PowerShell Examples&lt;/a&gt; is that they go on to provide the same example in other languages as well.  Here is the same thing in perl.&lt;/p&gt;
&lt;pre class="brush: perl"&gt;
#! perl

# SortDate.pl,  Version 1.00
# Display "sorted" date (YYYYMMDD)
# Written by Rob van der Woude
# http://www.robvanderwoude.com

# Parse time string
($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);

# Add "base year"
$year = $year + 1900;

# Add 1, since moth seems to be zero based
$mon  = $mon  + 1;

# Add leading zeroes if necessary
if ($mon &lt; 10) {
 $mon = "0".$mon
}
if ($mday &lt; 10) {
 $mday = "0".$mday
}

# Concatenate substrings
$sortdate = $year.$mon.$mday;

# Display result
print "\nSortDate = $sortdate\n";
&lt;/pre&gt;
&lt;p&gt;Certainly could use a text formatter of some kind to get rid of the icky manual padding, but for someone who has never written a line of perl, this looks quite nice and readable (although I am quite aware that that is not always the case for perl).  So what's got a bee in my bonnet?  Well I almost didn't write this until my friend Jeremiah tweeted the following&lt;/p&gt;
&lt;blockquote&gt;
Writing powershell. This is happily like writing perl. &lt;a href="http://twitter.com/peschkaj/status/4656145522"&gt;7:31am Oct 6th&lt;/a&gt;
&lt;/blockquote&gt;
&lt;p&gt;And a little bit later&lt;/p&gt;
&lt;blockquote&gt;
ZOMG This is seriously just like writing perl... I &lt;3 you #PowerShell &lt;a href="http://twitter.com/peschkaj/status/4660387379"&gt;10:41am Oct 6th&lt;/a&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;em&gt;Side note: Jeremiah is about the smartest man in the world when it comes to SQL &lt;a href="http://twitter.com/peschkaj"&gt;follow him here&lt;/a&gt; and &lt;a href="http://facility9.com/"&gt;view his blog facility9&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Why go about reinventing the wheel, if you are going to make a language similar to perl, just host perl.  What's the harm?  Its hard to call it harm, but its inefficient and tastes a little bit too much like &lt;a href="http://en.wikipedia.org/wiki/Embrace,_extend_and_extinguish"&gt;embrace, extend, extinguish&lt;/a&gt; to me.  PowerShell becomes the defacto scripting language in Windows enticing open source programmers because it is similar to their language of choice.  So why fret, PowerShell, perl, batch, bashscript, who cares?  Well there are legion reasons why software developers should care.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://www.cpan.org/"&gt;CPAN&lt;/a&gt;, &lt;a href="http://pear.php.net/"&gt;PEAR&lt;/a&gt;, &lt;a href="http://rubyforge.org/"&gt;GEMS&lt;/a&gt;, etc.&lt;/strong&gt; - These are huge repositories of tested code that can be leveraged quickly and easily by open source developers.  CPAN (Comprehensive Perl Archive Network) contains 16,600 modules.  PEAR (PHP Extension and Application Repository) contains 536 different packages with 1,255,213 lines of code.  RubyForge hosts 8406 different projects.  These established languages have a gigantic ecosystem of usable code.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Learning curve&lt;/strong&gt; - Do you know the intricacies of your chosen language?  Did you spend two hours debugging a wily error and because of it have forever learned some dark corner of your language?  Can you tell me in your sleep the difference between $foo and $$foo in php?  Well none of that will help you in the new PowerShell.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Brain drain&lt;/strong&gt; - Come up with a really clever way to solve a problem in PowerShell, great, keep it to yourself.  Where is the community?  There is &lt;a href="http://powershellcommunity.org/Default.aspx"&gt;powershellcommunity.org&lt;/a&gt;.  But there is yet to be an established authority for the community&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Now these problems I outline are true of any emerging language.  They are normally offset by some inherent positives in the language.  I haven't examined PowerShell in-depth enough to find out its intrinsic value.  On first blush and with my limited exposure, it seems to be a competent enough pseudo object oriented scripting language well suited for administrative tasks.  Nothing ground breaking, nothing that knocked my socks off, in the words of Homer Simpson:&lt;/p&gt;
&lt;blockquote&gt;
I saw you desperately trying to cram one more salty treat into America's already bloated snack hole. So I did what I could. I did what any loving husband would do! I reached out to some violent mobsters.
&lt;/blockquote&gt;
&lt;p&gt;PowerShell is just one more salty treat that Microsoft is cramming into America's already bloated snack hole.  It would be fine if they had a level playing field and allowed other scripting languages to be first class citizens, but they don't.  After the mind numbing pain of batch scripting, PowerShell seems great.  It really starts to lose its shine when you view it against the cornucopia of free mature open source scripting languages.&lt;/p&gt;
&lt;p&gt;I want to end with a real world example (anonymized).  There was a system that managed &lt;a href="http://theinfosphere.org/Blernsball"&gt;blerns&lt;/a&gt;.  Blerns could be collected in collections called Bars, Bars could be collected in collections called Foos.  These things were numbered and a system was built to manage them in COBOL.  Because COBOL likes to make pictures, the original architects thought to themselves, we will pack the information into an 8 digit number like so FFBBbbbb, so that 01010001 would be the first blern, in the first bar, in the first foo, 01010002 would be the next and so on.&lt;/p&gt;
&lt;p&gt;This worked great, the company was selling blerns left and right, and pretty soon foo:01 had 98 bars.  Then things started to break down, 3 more bars, and the whole house of cards would come crashing down.  What to do, what to do?!  The engineers were assembled and solutions were offered.&lt;/p&gt;
&lt;blockquote&gt;
We only have 8 foos, just assign the overflow into foo:10.
&lt;/blockquote&gt;
&lt;p&gt;Seemed reasonable enough, but that would have resulted in weird code springing up all over the place like this&lt;/p&gt;
&lt;pre class="brush: ruby"&gt;
if foo == 1 or foo == 10
  return "foo the first"
else
  ...
end
&lt;/pre&gt;
&lt;p&gt;Surely there was a better solution, what could it be?  Well, suffice it to say I wasn't present for these meeting and I only saw the terror of the last solution being halfway implemented and this new solution coming in.  The solution was a technical sounding concept called &lt;strong&gt;field widening&lt;/strong&gt;.  It amounted to storing the identifiers like so FFFBBBbbbb, 10 digits now capable of holding up to 1000 Foos, 1000 Bars per Foo, and 10000 Blerns per Bar.  Surely this was better, but was it any good.  I guess it might be, as long as we don't live in an exponential world.&lt;/p&gt;
&lt;div class="embed-wrap"&gt;
&lt;object width="480" height="385"&gt;&lt;param name="movie" value="http://www.youtube.com/v/lUMf7FWGdCw&amp;hl=en&amp;fs=1&amp;"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/lUMf7FWGdCw&amp;hl=en&amp;fs=1&amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="480" height="385"&gt;&lt;/embed&gt;&lt;/object&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Oh...&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5534765709337552753-8410288537346637227?l=ihumanable.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ihumanable.blogspot.com/feeds/8410288537346637227/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ihumanable.blogspot.com/2009/10/just-because-its-better-doesnt-mean-its.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5534765709337552753/posts/default/8410288537346637227'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5534765709337552753/posts/default/8410288537346637227'/><link rel='alternate' type='text/html' href='http://ihumanable.blogspot.com/2009/10/just-because-its-better-doesnt-mean-its.html' title='just because its better doesn&apos;t mean its good'/><author><name>Matt Nowack</name><uri>http://www.blogger.com/profile/00930543505232276126</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='20' src='http://4.bp.blogspot.com/_8IT2c3B5vQk/SsowYFU_8QI/AAAAAAAAADE/6iO_jned-r0/S220/smiles.jpeg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5534765709337552753.post-3635108369925611832</id><published>2009-10-06T11:41:00.007-04:00</published><updated>2009-10-06T12:05:27.505-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='koans'/><title type='text'>ruby koans (2)</title><content type='html'>&lt;p&gt;I still have the good fortune of not having any huge problems with our production application.  During this time I'm brushing up on some ruby, sharpening the blade.  I've been doing this by working through &lt;a href="http://github.com/edgecase/ruby_koans"&gt;EdgeCase's Ruby Koans&lt;/a&gt;.  In my first blog post &lt;a href="http://ihumanable.blogspot.com/2009/10/ruby-koans.html"&gt;ruby koans&lt;/a&gt; I suggested that anyone interested in ruby utilize this resource and pointed out some problems I had encountered.  I still suggest that anyone wanting to learn ruby and who has a basic understanding of programming use this great resource.&lt;/p&gt;
&lt;p&gt;Working through the koans I have found some more issues, this time in the about_message_passing.rb file.  One is just an oddity, the other a potential show stopper for someone new to programming.&lt;/p&gt;
&lt;p&gt;Starting at line 50 there is a class called MessageCatcher (technically they are reopening the class defined on line 5)&lt;/p&gt;
&lt;pre class="brush: ruby; first-line:50"&gt;
class MessageCatcher
  def add_a_payload(*args)
    return :empty unless args
    args
  end
end
&lt;/pre&gt;
&lt;p&gt;This is a very oddly named function, it doesn't seem to add a payload to the the arguments, and it is coded in such a way that it will never return :empty.  For it to return :empty, args would have to evaluate to false.  The only falsey values in Ruby are nil and false, the only values args can be is an array.  Arrays, even empty arrays, are true in ruby.  If you don't believe me, go ahead and run this in irb&lt;/p&gt;
&lt;pre class="brush: ruby; gutter: false"&gt;:empty_arrays_are_true if []&lt;/pre&gt;
&lt;p&gt;That will evaluate to :empty_arrays_are_true, which proves my point.  This is really a minor issue, but when filling out the corresponding test, the results aren't really obvious.&lt;/p&gt;
&lt;p&gt;The much bigger problem starts with the TypicalObject example&lt;/p&gt;
&lt;pre class="brush: ruby; first-line: 69"&gt;
class TypicalObject
end

def test_sending_undefined_messages_to_a_typical_object_results_in_errors
  typical = TypicalObject.new

  assert_raise(NoMethodError) do
    typical.foobar
  end
  assert_match(/foobar/, exception.message)
end
&lt;/pre&gt;
&lt;p&gt;This results in a nasty error when you rake, that looks something like this&lt;/p&gt;
&lt;pre class="brush: plain; highlight: 2; gutter: false"&gt;
You have not yet reached enlightenment ...
undefined local variable or method `exception' for #&lt;AboutMessagePassing:0xmemory&gt;

Please meditate on the following code:
./about_message_passing.rb:78:in `test_sending_undefined_messages_to_a_typical_object_results_in_erros'
./edgecase.rb:143:in `send'
./edgecase.rb:143:in `run_test'
./edgecase.rb:135:in `run_tests'
./edgecase.rb:134:in `each'
./edgecase.rb:134:in `run_tests'
./edgecase.rb:204
./edgecase.rb:203:in `each'
./edgecase.rb:203
./edgecase.rb:202:in `catch'
./edgecase.rb:202
path_to_enlightment.rb:27
&lt;/pre&gt;
&lt;p&gt;If you are new to programming this could throw you off your game, the interpreter does helpfully tell us the line number to look at, line 78.&lt;/p&gt;
&lt;p&gt;Looking at line 78 we see that we are using a local variable named `exception', but we never define this variable.  The way to fix this is to assign the result of the assert_raise to the variable exception, like so&lt;/p&gt;
&lt;pre class="brush: ruby; first-line: 69; highlight: 75"&gt;
class TypicalObject
end

def test_sending_undefined_messages_to_a_typical_object_results_in_errors
  typical = TypicalObject.new

  exception = assert_raise(NoMethodError) do
    typical.foobar
  end
  assert_match(/foobar/, exception.message)
end
&lt;/pre&gt;
&lt;p&gt;That simple assignment, which does appear correctly in the test right after this one, solves the problem and allows you to continue on your ruby learning way.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5534765709337552753-3635108369925611832?l=ihumanable.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ihumanable.blogspot.com/feeds/3635108369925611832/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ihumanable.blogspot.com/2009/10/ruby-koans-2.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5534765709337552753/posts/default/3635108369925611832'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5534765709337552753/posts/default/3635108369925611832'/><link rel='alternate' type='text/html' href='http://ihumanable.blogspot.com/2009/10/ruby-koans-2.html' title='ruby koans (2)'/><author><name>Matt Nowack</name><uri>http://www.blogger.com/profile/00930543505232276126</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='20' src='http://4.bp.blogspot.com/_8IT2c3B5vQk/SsowYFU_8QI/AAAAAAAAADE/6iO_jned-r0/S220/smiles.jpeg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5534765709337552753.post-198741600813645643</id><published>2009-10-05T09:46:00.009-04:00</published><updated>2009-10-06T09:37:03.273-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='open source'/><category scheme='http://www.blogger.com/atom/ns#' term='windows'/><category scheme='http://www.blogger.com/atom/ns#' term='microsoft'/><category scheme='http://www.blogger.com/atom/ns#' term='scripting'/><title type='text'>why no love for scripting languages</title><content type='html'>&lt;p&gt;Windows 7 is about to drop &lt;a href="http://www.engadget.com/2009/10/04/windows-7-retail-boxes-hitting-stores/"&gt;20091022&lt;/a&gt;.  And the internet is buzzing with comments like this:&lt;/p&gt;
&lt;blockquote&gt;Definitely the best OS of all time. - WindowsFTW&lt;/blockquote&gt;
&lt;blockquote&gt;Snow Leopard for me please! - Sam&lt;/blockquote&gt;
&lt;blockquote&gt;It's sad that people are excited by this level of mediocrity only because XP is archaic and Vista is a disaster. Talk about lowered expectations.&lt;br/&gt;&lt;br/&gt;
Get your anti-virus, and registry cleaners, and disk defragmenters, and other assorted utilities ready. You'll need them. Modern OS? Not hardly. - Terry&lt;/blockquote&gt;
&lt;p&gt;Well putting religion aside, Windows 7 looks to me what Vista should have been.  Microsoft is doing a great job with the ad campaign, they have awesome buzz going, and the computing world will probably be better off thanks to Windows 7.&lt;/p&gt;
&lt;div class="embed-wrap"&gt;
&lt;object width="560" height="340"&gt;&lt;param name="movie" value="http://www.youtube.com/v/ssOq02DTTMU&amp;hl=en&amp;fs=1&amp;"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/ssOq02DTTMU&amp;hl=en&amp;fs=1&amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="560" height="340"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/div&gt;
&lt;p&gt;To be fair I use Vista Business at work and Vista Home Premium at home with an Ubuntu partition that I dual boot into.  I don't hate Windows or Microsoft, but I do feel that both deliver underpowered products at overblown prices, their greatest strength is that with such a high market share other manufacturers make their products to easily inter-operate.  That is really the thing that keeps me from dropping Vista at home, after 4 hours of trying I still couldn't get my PS3 to play nice with my Ubuntu box for media streaming, it worked in 2 minutes with Vista.&lt;/p&gt;
&lt;p&gt;So here is my question for Windows 7, &lt;strong&gt;why no love for scripting languages?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Apple's new Mac OS X Snow Leopard has built in support for &lt;a href="http://www.apple.com/macosx/specs.html"&gt;Ruby, PHP, Perl, and Python&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;Ubuntu can install almost any hosting environment with the click of a button or by issuing a simple &lt;strong&gt;sudo apt-get ruby&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Windows is supposed to be the OS for everyone, easy to use, so where as the Ubuntu nerds are more than happy with firing up a terminal and apt-getting some fun, why doesn't Windows have these scripting environments ready to rock out of the box?&lt;/p&gt;
&lt;p&gt;Could it be that Windows is philosophically opposed to hosting scripting environments?  I don't think so as they build in a J-Script interpreter, try double clicking a .js file.&lt;/p&gt;
&lt;p&gt;Could it be that Windows foot print would be gigantic if they included these languages?  Ruby has a 23.7MB installer, Python 2.6.3 is 14.2MB, Perl 6's Rakudo source is 314KB, and PHP 5.3.0 has a 23MB installer.  So in total we are talking about 60MB of disk space.&lt;/p&gt;
&lt;p&gt;So why no love?  I'm guessing that it is three fold.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Not invented here syndrome.  These aren't Microsoft technologies, so why bundle them in with a Microsoft product.  This is somewhat valid, if these environments expose a security hole or need lots of updates, this is overhead for Microsoft that doesn't add any money to their bottom line but costs them in maintenance.&lt;/li&gt;
&lt;li&gt;Conflicts with the .Net platform.  If these environments are installed by default, then people could make &lt;a href="http://www.macruby.org/trac/wiki/HotCocoa"&gt;HotCocoa&lt;/a&gt; like bindings and create Windows programs outside of the .Net platform.  Microsoft wants people to use IronRuby, IronPython, CLR based scripting languages.  Really they want you to use C# and Visual Basic.Net so that you will buy the Visual Studio licenses, they are after all a software business.&lt;/li&gt;
&lt;li&gt;Unsuitable hosting environment.  This one is more conjecture as I'm not an OS Engineer, but it is informed conjecture.  Windows lacks the fundamental security model that is at the heart of Unix systems.  Windows 7 will more than likely continue with the bolted on solution of User Account Controls, although hopefully less annoying in this latest release.  This makes the idea of sandboxing a scripting environment much more difficult in the Microsoft world than in a Unix based OS.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;But Windows 7 definitely should include these scripting languages, and others (lua is the first to come to mind), because it will ultimately benefit them.  Steve Ballmer once famously shouted on stage "Developers, developers, developers, developers!"&lt;/p&gt;
&lt;div class="embed-wrap"&gt;
&lt;object width="480" height="385"&gt;&lt;param name="movie" value="http://www.youtube.com/v/8To-6VIJZRE&amp;hl=en&amp;fs=1&amp;"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/8To-6VIJZRE&amp;hl=en&amp;fs=1&amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="480" height="385"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/div&gt;&lt;br/&gt;&lt;br/&gt;
&lt;p&gt;There is a world of Ruby, Python, PHP, Perl, Lua, Ocaml, Erlang, Haskell, etc. developers that have a huge hurdle to jump in getting their programs onto the Windows platform.  They can either bundle the interpreter into their program a-la py2exe, they can try to get their program to run on a CLR based implementation of their language (if one exists), or they can try to get the user to install the necessary platform.&lt;/p&gt;
&lt;p&gt;If Microsoft made it easier to release to these platforms, a world of new and innovative software could flourish on the PC platform.  Rails development wouldn't have to suggest that if you have the misfortune of owning a windows-box to do all your development inside of a virtual linux-box.&lt;/p&gt;
&lt;blockquote&gt;If you’re working on Windows, you may find it easier to install Instant Rails. Be aware, though, that Instant Rails releases tend to lag seriously behind the actual Rails version. Also, you will find that Rails development on Windows is overall less pleasant than on other operating systems. If at all possible, we suggest that you install a Linux virtual machine and use that for Rails development, instead of using Windows.&lt;/blockquote&gt;
&lt;p&gt;From what I understand it is not currently baked in to Windows 7, but maybe we could throw developers a bone in SP1. If they could standardize the convention of scripting languages installation on the Windows platform, they could become a friendly release environment to a large segment of the open source movement.  If Microsoft wants to engage the Open Source community in a meaningful way, this would be a great first step.  Anything is better than the sham &lt;a href="http://www.codeplex.org"&gt;CodePlex Foundation&lt;/a&gt; Microsoft recently tried to pass off as an Open Source haven, but that really warrants its own post.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5534765709337552753-198741600813645643?l=ihumanable.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ihumanable.blogspot.com/feeds/198741600813645643/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ihumanable.blogspot.com/2009/10/why-no-love-for-scripting-languages.html#comment-form' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5534765709337552753/posts/default/198741600813645643'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5534765709337552753/posts/default/198741600813645643'/><link rel='alternate' type='text/html' href='http://ihumanable.blogspot.com/2009/10/why-no-love-for-scripting-languages.html' title='why no love for scripting languages'/><author><name>Matt Nowack</name><uri>http://www.blogger.com/profile/00930543505232276126</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='20' src='http://4.bp.blogspot.com/_8IT2c3B5vQk/SsowYFU_8QI/AAAAAAAAADE/6iO_jned-r0/S220/smiles.jpeg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5534765709337552753.post-4574380590943458003</id><published>2009-10-02T13:51:00.018-04:00</published><updated>2009-10-06T09:39:06.215-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='koans'/><title type='text'>ruby koans</title><content type='html'>&lt;p&gt;&lt;a href="http://github.com/edgecase/ruby_koans"&gt;EdgeCase's Ruby Koans&lt;/a&gt; are a great way to get started with the Ruby programming language.  I've worked through them once before and have had some free time at work so decided to work through them again.&lt;/p&gt;
&lt;p&gt;The quality of the koans are normally excellent, there are a few times where a comment is left in the code to make you think, and you really wish that there was an answer key somewhere.  There are also what look like a few errors in the code&lt;/p&gt;
&lt;p&gt;In about_sandwich_code.rb, the find_line and find_line2 functions don't seem to make much sense.  You would imagine a function would find a line matching a given regular expression, but the regular expression is hardcoded to /e/ which doesn't seem very realistic. This is the original.&lt;/p&gt;
&lt;pre class="brush: ruby"&gt;
def find_line(file_name)
  file = open(file_name)
  while line = file.gets
    return line if line.match(/e/)
  end
ensure
  file.close if file
end
&lt;/pre&gt;
&lt;p&gt;A more realistic function would be&lt;/p&gt;
&lt;pre class="brush: ruby"&gt;
def find_line(file_name, regex)
  file = open(file_name)
  while line = file.gets
    return line if line.match(regex)
  end
ensure
  file.close if file
end
&lt;/pre&gt;
&lt;p&gt;I'm sure this was done to simplify the exercise, but it violates the rule of least surprise by adding magic functionality to the function.&lt;/p&gt;
&lt;p&gt;In the last function of about_scoring_project.rb, named test_score_of_mixed_is_sum, the first assert reads&lt;/p&gt;
&lt;pre class="brush: ruby"&gt; assert_equal 50, score([2, 5, 2, 2, 3]) &lt;/pre&gt;
&lt;p&gt;The rules of the game clearly specify that&lt;/p&gt;
&lt;pre class="brush: ruby"&gt; 
# * A set of three numbers (other than ones) is worth 100 times thenumber. (e.g. three fives is 500 points).
# ...
# * A five (that is not part of a set of three) is worth 50 points.
&lt;/pre&gt;
&lt;p&gt;This means that the score should be 200 (for the set of three 2's) + 50 (for the 5) = 250.  The first assert should be changed to&lt;/p&gt;
&lt;pre class="brush: ruby"&gt; assert_equal 250, score([2, 5, 2, 2, 3]) &lt;/pre&gt;
&lt;p&gt;If you are interested in learning ruby, this is an indispensable way to learn not just the syntax, but to get the flavor, and to start thinking in ruby.&lt;/p&gt;
&lt;p&gt;Click this link to reveal my solution to the scoring problem&lt;br /&gt;
&lt;a href="javascript:;" onclick="toggle(this)" id="ruby-koans-spoiler-toggle"&gt;Show Solution&lt;/a&gt;&lt;/p&gt;
&lt;div style="display:none" id="ruby-koans-spoiler"&gt;
&lt;pre class="brush: ruby"&gt;
def score(dice)
  result = 0
  counter = {}
  (1..6).each { |x| counter[x] = 0 }
  dice.each { |d| counter[d] += 1 }
  if counter[1] &gt;= 3 
    result += 1000
    counter[1] -= 3
  end 
  
  (2..6).each do |x| 
    if counter[x] &gt;= 3
      result += (100 * x)
      counter[x] -= 3
    end 
  end

  result += (counter[1] * 100)
  result += (counter[5] * 50)
end
&lt;/pre&gt;
&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5534765709337552753-4574380590943458003?l=ihumanable.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ihumanable.blogspot.com/feeds/4574380590943458003/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ihumanable.blogspot.com/2009/10/ruby-koans.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5534765709337552753/posts/default/4574380590943458003'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5534765709337552753/posts/default/4574380590943458003'/><link rel='alternate' type='text/html' href='http://ihumanable.blogspot.com/2009/10/ruby-koans.html' title='ruby koans'/><author><name>Matt Nowack</name><uri>http://www.blogger.com/profile/00930543505232276126</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='20' src='http://4.bp.blogspot.com/_8IT2c3B5vQk/SsowYFU_8QI/AAAAAAAAADE/6iO_jned-r0/S220/smiles.jpeg'/></author><thr:total>0</thr:total></entry></feed>
