<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0"><channel><atom:link rel="hub" href="http://tumblr.superfeedr.com/" xmlns:atom="http://www.w3.org/2005/Atom"/><description></description><title>I Like Programming</title><generator>Tumblr (3.0; @nickretallack)</generator><link>http://blog.nickretallack.com/</link><item><title>Scrolling Puzzle Box</title><description>&lt;p&gt;I was experimenting with how different browsers on different devices handle scrolling when I came up with &lt;a href="http://nickretallack.com/experiments/puzzlebox.html"&gt;this little experiment&lt;/a&gt; to stress-test them.&lt;/p&gt;

&lt;p&gt;It plays best in Safari for mac, with iPad a close second.  Firefox does a decent job, but you have to click every so often to get it to focus a different scrollable area.  Chrome has some tearing graphical glitches when you scroll two divs at once.  It&amp;#8217;s totally unplayable on Chrome for Android, unfortunately, since that browser doesn&amp;#8217;t support scrolling blocks.  Internet Explorer 9 doesn&amp;#8217;t even understand the css selectors.&lt;/p&gt;</description><link>http://blog.nickretallack.com/post/13644039791</link><guid>http://blog.nickretallack.com/post/13644039791</guid><pubDate>Fri, 02 Dec 2011 15:24:06 -0500</pubDate></item><item><title>Puppet Box: Now with Real Image Files!</title><description>&lt;p&gt;Now that I know how to upload files in Node.js, I&amp;#8217;ve ditched the data urls.  Instead, we&amp;#8217;re doing real live file uploads via XHR with a FormData attached.  I&amp;#8217;m so glad browsers can finally represent Form Data!&lt;/p&gt;

&lt;p&gt;As an extra level of efficiency, the client hashes the file&amp;#8217;s binary data and does a HEAD request to check if the server already has that file.  It knows exactly where to look since the files are all named after their sha256 anyway.&lt;/p&gt;

&lt;p&gt;Unfortunately, the hash I&amp;#8217;m doing of the real file on the server side doesn&amp;#8217;t agree with the hash of the binary string on the client side.  To work around this, I&amp;#8217;m just trusting the client for now.  Please don&amp;#8217;t be a meanie and exploit this.&lt;/p&gt;

&lt;p&gt;Anyway, the whole thing should be a great deal more efficient now.  &lt;a href="http://toptools.nickretallack.com:5000/"&gt;Try it out&lt;/a&gt;!  Now I just need some more features, like stacking and save states.  Also it&amp;#8217;s still on a janky test server and not guaranteed to be up.  I&amp;#8217;ll deploy it properly eventually.&lt;/p&gt;</description><link>http://blog.nickretallack.com/post/11137458476</link><guid>http://blog.nickretallack.com/post/11137458476</guid><pubDate>Fri, 07 Oct 2011 07:46:46 -0400</pubDate></item><item><title>Puppet Box Progress!</title><description>&lt;p&gt;I now have a little &lt;a href="http://toptools.nickretallack.com:5000/play/things"&gt;puppet box playground&lt;/a&gt; up.  It only works in Chrome, but that&amp;#8217;s ok cuz it&amp;#8217;s an experiment.  Go ahead and open it in multiple browsers or pass the link to a friend to see how collaborative it is.  You can drag the images around, and you can also paste in new images just by copying them off the web (use Copy Image) or out of image editing programs like photoshop.  This should make it really easy to prototype board games, or run D&amp;amp;D simulations that require a map and character locations.&lt;/p&gt;

&lt;p&gt;There are a lot of things I could do to make it more suited to these tasks though, like letting you stack, resize, substitute, and delete images.  That stuff will happen eventually though.&lt;/p&gt;</description><link>http://blog.nickretallack.com/post/10838135141</link><guid>http://blog.nickretallack.com/post/10838135141</guid><pubDate>Fri, 30 Sep 2011 00:42:16 -0400</pubDate></item><item><title>Puppet Box</title><description>&lt;p&gt;I started on something I&amp;#8217;ve wanted to make for some time.  &lt;a href="https://github.com/nickretallack/puppetbox"&gt;A puppet box&lt;/a&gt;!  It&amp;#8217;s just a simple web app you can paste images into and drag them around collaboratively with your friends.  I&amp;#8217;ve got the pasting, dragging, and syncing done so far.  Now all I need is multiple rooms, server-side persistence, and support for a few more interactions like deleting and you&amp;#8217;ll be able to start making up ad-hoc games with your friends online!&lt;/p&gt;

&lt;p&gt;I&amp;#8217;ll post a demo as soon as it&amp;#8217;s done enough to be usable by people other than me :P.&lt;/p&gt;</description><link>http://blog.nickretallack.com/post/10803254299</link><guid>http://blog.nickretallack.com/post/10803254299</guid><pubDate>Thu, 29 Sep 2011 07:26:00 -0400</pubDate></item><item><title>What I've been working on</title><description>&lt;p&gt;I always have a million projects on my mind, but here are the top ones of late:&lt;/p&gt;

&lt;h2&gt;Angular + Organizer and Elemental Chess&lt;/h2&gt;

&lt;p&gt;To learn &lt;a href="http://angularjs.org/"&gt;Angular.js&lt;/a&gt; I started porting &lt;a href="https://github.com/nickretallack/todo"&gt;my old organizer application&lt;/a&gt; to it.  &lt;a href="https://github.com/nickretallack/Todo-2"&gt;The new source code is on github now&lt;/a&gt;.  The old app uses &lt;a href="http://gears.google.com/"&gt;Google Gears&lt;/a&gt; for the client-side sqlite database with full-text search features, but unfortunately Gears is no longer supported by any browser and &lt;a href="http://www.w3.org/TR/webdatabase/"&gt;WebSQL is not going anywhere&lt;/a&gt;.  Fortunately, Angular includes a handy full-text object search that works well enough for my needs, and porting was surprisingly simple.  Unfortunately, I had to use a lot of ng:eval&lt;/p&gt;

&lt;p&gt;I also hacked in a very simple method of synchronizing application state so multiple users can collaborate.  All you have to do is wait for some things to change, serialize all the stateful information to JSON, run diff-match-patch to compare it to its previous state, send those patches over the wire via Socket.IO, and patch the state on the other end in the same way.  I _.debounce&amp;#8217;d this so it doesn&amp;#8217;t happen too often.  No idea how well this scales, but it&amp;#8217;s ghetto fabulous so I like it.  However, a much better solution would be to hook into angular&amp;#8217;s scope.$eval for some hints on what actually changed.  If anyone knows how to do this, please &lt;a href="http://stackoverflow.com/questions/7354870/when-angular-js-triggers-an-oneval-is-there-any-way-to-immediately-tell-what-va"&gt;answer my StackOverflow question&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;I also attempted to port my &lt;a href="http://nickretallack.com/elementalchess/"&gt;Elemental Chess&lt;/a&gt; game to Angular.  I was unfortunately rather disappointed with the result.  I used a lot of ng:eval and ng:class, and Angular ended up screwing these up and using old values far too often, so you&amp;#8217;d move a game piece and it&amp;#8217;d leave its colored background behind.  I guess it&amp;#8217;s not really meant for games.  Either way, this did result in me porting the game engine to a DOM-free implementation, which made it easier to build a minimax AI player to play against.  I&amp;#8217;ll post this version when I finish tweaking the AI.  It&amp;#8217;s currently pretty slow, because I couldn&amp;#8217;t find a better way to clone the game state for each iteration of minimax other than to selectively JSON serialize the whole thing and then re-build the board each time.  Perhaps if I made a game event log and added a feature to undo your moves I could use that in my minimax algorithm instead of recreating the game state.  I&amp;#8217;m not sure how I want to do the graphics, but I&amp;#8217;m leaning toward doing them more like the old way again only with support for dragging with touch screens so you can play on your phone.&lt;/p&gt;

&lt;p&gt;Oh yeah, gotta love the name they put on this version of Angular: &amp;#8220;Canine Psychokinesis&amp;#8221;.  It sure beats &amp;#8220;Jiggling Armfat&amp;#8221;.&lt;/p&gt;

&lt;h2&gt;Factor Blaster and Beat Ship&lt;/h2&gt;

&lt;p&gt;Two games I started on &lt;a href="http://pixieengine.com"&gt;PixieEngine.com&lt;/a&gt;.  Beat Ship was lost but I intend to resurrect it.  For &lt;a href="http://pixieengine.com/projects/658/fullscreen"&gt;Factor Blaster&lt;/a&gt; I want to remove spacial navigation and make it more like Missile Command.  Check my previous post for more details.&lt;/p&gt;

&lt;h2&gt;&lt;a href="http://toptools.nickretallack.com"&gt;TopTools&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;Like I said before, using &lt;a href="http://webfinger.org/"&gt;webfinger&lt;/a&gt; was probably a mistake, and I should really make this a general purpose tool instead instead of forcing a use case on it.  I&amp;#8217;d like to make this super easy to use without even creating accounts.  Perhaps it would work if all votes were public and an election&amp;#8217;s creator and moderators were allowed to police them for sock puppets.  Also it needs to have a hot-seat mode where all the users can vote from one computer, so you can easily settle disputes like which board game to play next in real time with minimal hassle.  And it needs to work on a phone browser!&lt;/p&gt;

&lt;h2&gt;Art and Animation!&lt;/h2&gt;

&lt;p&gt;Cartoon animation is a passion of mine.  I practiced it in my spare time in high school and college.  I do a lot of drawings for friends, and I even sell stuff at conventions.  However, I haven&amp;#8217;t really put together much of a portfolio online to show off my work.  I need to do this.&lt;/p&gt;

&lt;p&gt;Playing &lt;a href="http://itunes.apple.com/us/app/game-dev-story/id396085661?mt=8"&gt;Game Dev Story&lt;/a&gt; has convinced me that career changes are good for developing your all-around skills and making more valuable people.&lt;/p&gt;

&lt;p&gt;I&amp;#8217;ve also been looking into traditional pencil and paper animation.  I got myself a peg board, light board, and ordered some paper for it.  We&amp;#8217;ll see what I come up with =]&lt;/p&gt;</description><link>http://blog.nickretallack.com/post/10761953747</link><guid>http://blog.nickretallack.com/post/10761953747</guid><pubDate>Wed, 28 Sep 2011 04:43:12 -0400</pubDate></item><item><title>HTML5 Dev Conf</title><description>&lt;p&gt;I signed up for this on a whim, and I&amp;#8217;m glad I did.  I learned about a lot of new fun things out there.&lt;/p&gt;

&lt;p&gt;The biggest booth at the show was for &lt;a href="http://spaceport.io/"&gt;SpacePort&lt;/a&gt;, which can extract vector art from flash files and render it in SVG and CSS or OpenGL ES.  They&amp;#8217;ve also ported the Flash AS3 API to JavaScript.  This seems aimed at helping Flash developers port their apps to native mobile apps and flashless web browsers.&lt;/p&gt;

&lt;p&gt;I attended a panel about &lt;a href="https://github.com/mrdoob/three.js/"&gt;Three.js&lt;/a&gt; which I&amp;#8217;m pretty tempted to use now, despite having already used the lower level features of OpenGL and GLSL before.&lt;/p&gt;

&lt;p&gt;I was looking forward to Max Goodman&amp;#8217;s panel on procedural audio in JavaScript, but he called in sick.  I was still able to get some advice on syncing the audio in Beat Ship, the browser-based rhythm game I started on at last year&amp;#8217;s TigJAM.  Unfortunately the source code for this was lost when PixieEngine.com was re-architected, but it shouldn&amp;#8217;t be too hard to rewrite.  This will be my next project.&lt;/p&gt;

&lt;p&gt;Speaking of Pixie Engine, I ran into the creators and they insisted I make my experimental game &lt;a href="http://pixieengine.com/projects/658/fullscreen"&gt;Factor Blaster&lt;/a&gt; more like Missile Command.  We both agreed that spacial navigation just distracts the player from the real fun of factoring.  I think I&amp;#8217;ll place the player at the bottom of the screen and have the numbers rain down from above.  I&amp;#8217;d love to add some more variation in the weapons too.  I&amp;#8217;d like 2 to be a machine gun, 3 to be a sweep laser, and 5 and 7 could be chain reaction bombs like in Missile Command.&lt;/p&gt;

&lt;p&gt;I also ran into Ryan Jarvinen from Eventbrite and it seems we&amp;#8217;re both big advocates of the alternative vote.  Some time ago, I made a nice web interface for running Condorcet elections with &lt;a href="http://www.openstv.org/"&gt;OpenSTV&lt;/a&gt; called &lt;a href="http://toptools.nickretallack.com/"&gt;TopTools&lt;/a&gt;.  Perhaps I could have it import EventBrite attendee information in case you wanted to run some elections at an event.&lt;/p&gt;

&lt;p&gt;I realize that this would serve better as a general purpose election tool than it would for the niche I&amp;#8217;d selected for it.  Also it needs to be able to display ties, especially when there aren&amp;#8217;t enough votes for a definitive winner to be selected.  Also I&amp;#8217;m a little worried about my choice of doing logins with WebFinger.  It seemed like an awesomely simple idea at the time, but I&amp;#8217;m sure it&amp;#8217;s just gonna scare people away since there are so many issues with everyone&amp;#8217;s implementations of it &amp;#8212; even google.&lt;/p&gt;</description><link>http://blog.nickretallack.com/post/10761948179</link><guid>http://blog.nickretallack.com/post/10761948179</guid><pubDate>Wed, 28 Sep 2011 04:42:41 -0400</pubDate></item><item><title>4Fourths</title><description>&lt;p&gt;What a beautiful game!  I got to play with this at &lt;a href="http://www.kokoromi.org/gamma4/"&gt;Gamma 4&lt;/a&gt; as part of their One Button showcase.  It&amp;#8217;s a co-operative game where four players control two ships using one button each: players 1 and 3 can charge and shoot their lasers, while players 2 and 4 control the upward thrust of each ship.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://4fourths.com/"&gt;4Fourths&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Unlike a lot of co-operative games, this one does nothing to stop players from killing each other.  In fact, it&amp;#8217;s pretty fun to spar between challenges, and most players who pick the game up got right into shooting and dodging each other.  Before long, the first enemy is lowered between the players like a giant wall, forcing them to break it up and learn how to work together without a word of dialog.  But as the game goes on, bosses place less walls between the players until they must be very careful not to blow each other up.&lt;/p&gt;

&lt;p&gt;Despite the fun of shooting each other, there are no competitive scoring elements.  Also, it&amp;#8217;s rather difficult to defeat a boss without both players&amp;#8217; combined firepower, and failing to do so in time means everyone loses.  That makes this one of the most purely co-operative games I&amp;#8217;ve played.&lt;/p&gt;

&lt;p&gt;Also, I love the bright colors and boxy graphics.  It&amp;#8217;s so Nu-Lo-Fi.  And it&amp;#8217;s made in &lt;a href="http://unity3d.com/"&gt;unity&lt;/a&gt;.&lt;/p&gt;</description><link>http://blog.nickretallack.com/post/443112921</link><guid>http://blog.nickretallack.com/post/443112921</guid><pubDate>Fri, 12 Mar 2010 05:37:11 -0500</pubDate></item><item><title>N-Key Rollover, or Why Modern Keyboards Suck</title><description>&lt;p&gt;Have you ever tried to play a two-player game on one keyboard?  Chances are it wasn&amp;#8217;t a fun experience.  You press down a few keys, and the rest don&amp;#8217;t register at all!  What gives?&lt;/p&gt;

&lt;p&gt;What we want is called &lt;a href="http://en.wikipedia.org/wiki/Rollover_(key)"&gt;n-key rollover&lt;/a&gt; aka NKRO, a feature that older keyboards like the IBM Model M used to have.  But these days, manufacturers have been cutting costs.  According to &lt;a href="http://www.renoise.com/indepth/equipment/crippled-chords-without-full-n-key-rollover"&gt;this blog&lt;/a&gt;, keyboard manufacturers save seven cents per key by using &lt;a href="http://www.dribin.org/dave/keyboard/one_html/"&gt;matrix circuits&lt;/a&gt;.  That&amp;#8217;s $7.28 for 104 keys, which makes me wonder how vendors can justify charging over $50 for &amp;#8220;gaming keyboards&amp;#8221; that don&amp;#8217;t have it.&lt;/p&gt;

&lt;p&gt;It&amp;#8217;s hard to find any keyboards these days with NKRO.  Fortunately, the &lt;a href="http://www.elitekeyboards.com/products.php?sub=filco_keyboards"&gt;Filco keyboards&lt;/a&gt; on EliteKeyboards.com advertise the feature prominently.  I&amp;#8217;ll have to get one of these.&lt;/p&gt;</description><link>http://blog.nickretallack.com/post/192229436</link><guid>http://blog.nickretallack.com/post/192229436</guid><pubDate>Sat, 19 Sep 2009 23:16:00 -0400</pubDate></item><item><title>JavaScript Scoping Oddity</title><description>&lt;p&gt;Guess the output.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;var outer = "test1"

function test1(){
  var inner = outer
  return inner
}

function test2(){
  var inner = outer
  var outer = "test2"
  return inner
}

test1()
test2()
&lt;/code&gt;&lt;/pre&gt;</description><link>http://blog.nickretallack.com/post/185172109</link><guid>http://blog.nickretallack.com/post/185172109</guid><pubDate>Fri, 11 Sep 2009 04:07:00 -0400</pubDate></item><item><title>Shrinky-Fit TextArea</title><description>&lt;p&gt;While working on my &lt;a href="http://nickretallack.com/outliner/"&gt;latest hobby project&lt;/a&gt;, I wanted the text entry boxes to always be just large enough for the text you&amp;#8217;re typing into them, similar to the text boxes in desktop apps like OmniFocus.&lt;/p&gt;

&lt;p&gt;The first solution I found, &lt;a href="http://plugins.jquery.com/project/autogrow"&gt;jquery.autogrow&lt;/a&gt;, was not satisfactory.  It simply did not respond to input quick enough to avoid having text slip out of the top of my input for a moment if I hit enter too fast, and it assumed you&amp;#8217;d leave some space to write and not truly shrink to fit.&lt;/p&gt;

&lt;p&gt;Wishing to replace it, I chatted with a friend and we came up with a scheme quite similar to &lt;a href="http://peter.michaux.ca/articles/automatically-expanding-textarea-elements-with-yahoo-ui"&gt;another solution by Peter Michaux&lt;/a&gt; which I didn&amp;#8217;t discover until after I threw together mine.&lt;/p&gt;

&lt;p&gt;The gists of all of them are similar: take the text of your current textarea, place it in a similarly-styled div, let the browser flow it the way you want it, then apply its height back to the textarea.&lt;/p&gt;

&lt;p&gt;My solution made a few little changes.  Here&amp;#8217;s &lt;a href="http://gist.github.com/178299"&gt;the gist of it&lt;/a&gt;.  I attached this as a keydown handler on the affected textareas.  Each keydown, it copies the text into a similarly styled div, then sets the height like usual.  Also, I used a zero-millisecond setTimeout so it would fire just after the textarea&amp;#8217;s text was changed.  I suppose I could have used bubbling up events instead.  Not to be wasteful, my version only uses one doppelganger div for each different style of textarea I needed.  Both are positioned absolutely at left:-9999999px.&lt;/p&gt;</description><link>http://blog.nickretallack.com/post/176106759</link><guid>http://blog.nickretallack.com/post/176106759</guid><pubDate>Mon, 31 Aug 2009 02:46:46 -0400</pubDate></item><item><title>Who says Python doesn't have function static variables?</title><description>&lt;p&gt;If you want to store internal state in a python function, most people would say you need to create a class and use class or instance attributes.  Of course you don&amp;#8217;t.  Python 3 introduces &amp;#8220;nonlocal&amp;#8221; as a keyword for creating static variables, but you can already make them without this help.&lt;/p&gt;

&lt;p&gt;In fact, you might even create them accidentally, due to this &lt;a href="http://stackoverflow.com/questions/146329/what-is-the-worst-gotcha-youve-experienced#147877"&gt;weird behavior with default arguments&lt;/a&gt;.  Python only evaluates default arguments once, so if your default argument is mutable complex type, you have yourself some internal state.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; def counter(count=[0]):
...   count[0] += 1
...   return count[0]
... 
&amp;gt;&amp;gt;&amp;gt; counter()
1
&amp;gt;&amp;gt;&amp;gt; counter()
2
&amp;gt;&amp;gt;&amp;gt; counter()
3
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Well, that&amp;#8217;s kind of a hack.  A better way to do this is to use function attributes.  Yes, functions can have attributes, just like classes.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;def counter():
  counter.count += 1
  return counter.count
counter.count = 0
&lt;/code&gt;&lt;/pre&gt;</description><link>http://blog.nickretallack.com/post/117150710</link><guid>http://blog.nickretallack.com/post/117150710</guid><pubDate>Tue, 02 Jun 2009 23:38:00 -0400</pubDate></item><item><title>Building a Good New User Experience for Elemental Chess</title><description>&lt;p&gt;People don&amp;#8217;t like to log in to things until they&amp;#8217;re convinced it&amp;#8217;s worth it.  That&amp;#8217;s a given.  My first thought was to just make a sandbox mode for my game, where you can play it purely on the client side, with a friend or against the computer.  If you wanted to play against other players online, you&amp;#8217;d need to log in with an openid provider.&lt;/p&gt;
&lt;p&gt;I showed off my new sandbox mode at Google IO.  It didn&amp;#8217;t have AI or checkmate detection yet, since I couldn&amp;#8217;t decide whether to implement that on the client side or the server side.  &lt;a href="http://code.google.com/webtoolkit/"&gt;Google Web Toolkit&lt;/a&gt; seems like a nice solution for client/server code sharing that I will definitely pursue.  But then I thought, I can solve this code sharing problem &lt;i&gt;and&lt;/i&gt; provide a better user experience, if I get a little more ambitious with my user account handling.  I&amp;#8217;ll let users do anything they want except hang onto their history if they&amp;#8217;re not logged in.&lt;/p&gt;
&lt;p&gt;When a user hits the site without a user in their session cookie, I&amp;#8217;ll create a brand new user for them with a randomized name (and plenty of invitation to change it).  This is a full-featured user, with one caveat: it can expire, at about the time their cookie-based session should.  To keep it from expiring, all the user has to do is associate it with an OpenID.  This is exactly the same thing as logging in.&lt;/p&gt;
&lt;p&gt;Okay, but what if a lazy user who already has a saved account comes along and plays a few games without logging in?  Easy.  When they eventually do log in, we can delete their temporary account and replace every instance of it with the real one!  Talk about awesome.&lt;/p&gt;
&lt;p&gt;Since I&amp;#8217;m totally overloading my Login button to function as &amp;#8220;Login&amp;#8221;, &amp;#8220;Register&amp;#8221;, &amp;#8220;Save&amp;#8221;, and &amp;#8220;Merge Accounts&amp;#8221;, I think it&amp;#8217;s appropriate to call it something else.  &amp;#8220;Recognize Me&amp;#8221; sounds pretty good!&lt;/p&gt;</description><link>http://blog.nickretallack.com/post/116140624</link><guid>http://blog.nickretallack.com/post/116140624</guid><pubDate>Mon, 01 Jun 2009 03:15:59 -0400</pubDate></item><item><title>Rebuilding</title><description>&lt;p&gt;I&amp;#8217;ve lost tons of work in the past in almost every way imaginable, from melted or crushed hard disks to raid failures and unreliable hosts.  I thought redundancy would save me, but these failures always seem to happen in pairs.  I could fill a &lt;a href="http://wiki.nickretallack.com/graveyard"&gt;graveyard&lt;/a&gt; with all the work I&amp;#8217;ve lost.&lt;/p&gt;
&lt;p&gt;But I&amp;#8217;m not gonig to let this get me down.  I can still remember how I made most of those old things, and some of them were pretty good simple ideas, so it might be fun to re-make them better stronger faster than before!&lt;/p&gt;
&lt;p&gt;In the future, I&amp;#8217;ll use reliable backup sites like github, amazon s3, and I&amp;#8217;ll look into Mozy.  &lt;a href="http://www.youtube.com/watch?v=w_F_6xOlke0&amp;amp;videos=3izu1LXoPZE"&gt;Their commercial&lt;/a&gt; is spot on, after all.  Fortunately, not all of my data is gone.  A good hunk of it survived on my 120GB WD Passport, which includes things as far back as 2005. I better back this up before I lose it!&lt;/p&gt;</description><link>http://blog.nickretallack.com/post/109442571</link><guid>http://blog.nickretallack.com/post/109442571</guid><pubDate>Mon, 18 May 2009 07:15:11 -0400</pubDate></item><item><title>Reduce by Any Other Name</title><description>&lt;p&gt;One of my favorite functions is `reduce`.  It&amp;#8217;s the perfect way to represent anything like sum, product, factorial, reverse, that walks along a list accumulating the values it finds.  Unfortunately, it&amp;#8217;s hard to share my love of reduce when every language calls it something different.  Observe:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;# Python - reduce&lt;br/&gt;# reduce(function, iterable[, initializer])&lt;br/&gt;def factorial(n):&lt;br/&gt; return reduce(lambda acc,x: acc*x, range(1,n), 1)&lt;br/&gt;&lt;br/&gt;# Ruby - inject&lt;br/&gt;# Enumerable#inject(init) {|result, item| ...}&lt;br/&gt;def factorial(n)&lt;br/&gt; (1..n).inject(1) {|acc,x| acc*x}&lt;br/&gt;end&lt;br/&gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;-- Haskell - fold&lt;br/&gt;-- foldl :: (a -&amp;gt; b -&amp;gt; a) -&amp;gt; a -&amp;gt; [b] -&amp;gt; a&lt;br/&gt;factorial n = foldl (*) 1 [1..n]&lt;br/&gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;// C# - Aggregate&lt;br/&gt;// Enumerable.Aggregate&amp;lt;(Of &amp;lt;(TSource, TAccumulate&amp;gt;)&amp;gt;)&lt;br/&gt;//   Method (IEnumerable&amp;lt;(Of &amp;lt;(TSource&amp;gt;)&amp;gt;), &lt;br/&gt;//     TAccumulate, Func&amp;lt;(Of &amp;lt;(TAccumulate, TSource, TAccumulate&amp;gt;)&amp;gt;))&lt;br/&gt;// (This type signature is pretty ridiculous)&lt;br/&gt;int factorial(int n){&lt;br/&gt; return Enumerable.Range(1, n).Aggegate(1, (acc,x) =&amp;gt; acc*x);&lt;br/&gt;}&lt;/code&gt;&lt;/p&gt;</description><link>http://blog.nickretallack.com/post/103936635</link><guid>http://blog.nickretallack.com/post/103936635</guid><pubDate>Tue, 05 May 2009 19:51:00 -0400</pubDate></item><item><title>Board Game Abstraction</title><description>&lt;p&gt;How would you model a board game in a sql database?  I&amp;#8217;ve been overthinking this.  I&amp;#8217;d probably have a Game model to keep track of whose turn it is, with a lot of Pieces associated with it.  But that&amp;#8217;s obvious.&lt;/p&gt;
&lt;p&gt;To be totally generic, a Piece could consist of string:kind, string:space, and string:color.  But what if you were playing a game like chess with a 2D board?  You could name the space something like 2-2.  What if the piece has meta information like rank and class?  You could encode it in the kind, like fire-2.  Why bother using data types other than string if you&amp;#8217;re just going to fetch all pieces and assemble the board whenever you compute a move?&lt;/p&gt;
&lt;p&gt;Or is there a reason to query on meta information and board positions?  Would you optimize your game logic by not constructing the whole board each time?  Should you create a new model for the kind of piece that exists in each game, like a monopoly piece which moves around the board linearly versus a checkers piece which traverses in two dimensions and can be kinged?  Do you want many small tables or few large ones?&lt;/p&gt;</description><link>http://blog.nickretallack.com/post/103297823</link><guid>http://blog.nickretallack.com/post/103297823</guid><pubDate>Mon, 04 May 2009 08:11:23 -0400</pubDate></item><item><title>Ruby Doesn't Have Inner Functions</title><description>&lt;p&gt;Ruby syntax allows you to write something that looks a lot like an inner function in other languages.  However, it really isn&amp;#8217;t.  Lets explore this odd behavior.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class Foo
  def bar
    x = "scoped variable"
    def baz
      puts x
    end
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This looks like a pretty standard test of closures.  One might expect the &lt;code&gt;bar&lt;/code&gt; method to define a function &lt;code&gt;baz&lt;/code&gt; with access to bar&amp;#8217;s scope, namely the variable &lt;code&gt;x&lt;/code&gt;.  Lets see what really happens.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;puts Foo.instance_methods.include?("bar") # true
puts Foo.instance_methods.include?("baz") # false
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Still consistent with our expectations, we see we have created an instance method &lt;code&gt;bar&lt;/code&gt;, but not baz.  Lets test out &lt;code&gt;bar&lt;/code&gt; on an instance.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;instance = Foo.new
instance.bar
puts Foo.instance_methods.include?("baz") # true
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Oho, where did this &lt;code&gt;baz&lt;/code&gt; method come from that wasn&amp;#8217;t there before?  Running &lt;code&gt;bar&lt;/code&gt; created it!  In fact, calling `bar&amp;#8217; in our instance even changed the global class definition to include it!  Lets try it out!&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;instance.baz # NameError: undefined local variable or method ‘x’ for #&amp;lt;Foo:0x1cee4&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So much for closures.  It seems baz doesn&amp;#8217;t have access to bar&amp;#8217;s scope.  It&amp;#8217;s just a plain old instance method that we&amp;#8217;ve defined.&lt;/p&gt;

&lt;p&gt;Well, it doesn&amp;#8217;t behave much like other languages, but this behavior could still be useful.  You could use it to evaluate method definitions conditionally, or just wait and create some of your methods after others have run.  It&amp;#8217;s not all that useful, but it&amp;#8217;s still good to know so you don&amp;#8217;t accidentally use this syntax wrong.&lt;/p&gt;</description><link>http://blog.nickretallack.com/post/71039207</link><guid>http://blog.nickretallack.com/post/71039207</guid><pubDate>Fri, 16 Jan 2009 21:16:00 -0500</pubDate></item></channel></rss>

