<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Oliver Steele | Blog</title>
    <description>My historical blog</description>
    <link>https://blog.osteele.com/</link>
    <atom:link href="https://blog.osteele.com/feed.xml" rel="self" type="application/rss+xml" />
    <pubDate>Thu, 01 Aug 2019 12:57:56 -0400</pubDate>
    <lastBuildDate>Thu, 01 Aug 2019 12:57:56 -0400</lastBuildDate>
    <generator>Jekyll v3.8.5</generator>
    
      <item>
        <title>Stroop: A Card Game</title>
        <description>&lt;p&gt;Stroop is a card game for two or more players and a dealer, who also serves as referee. The objective is to collect the most cards, by naming cards that differ in rank and suit color from the cards that the dealer reveals.&lt;/p&gt;

&lt;!-- more --&gt;

&lt;p&gt;Stroop is played with a standard 52-card deck. The dealer shuffles the deck and turns it face down; this is the &lt;em&gt;stock pile&lt;/em&gt;. At the beginning of each round, the dealer removes the top card (the &lt;em&gt;top card&lt;/em&gt;) from the stock pile, and places it face up. This begins the &lt;em&gt;stake pile&lt;/em&gt;. If the stake pile contains cards, the top card is placed on top of them.&lt;/p&gt;

&lt;p&gt;Once the dealer has revealed the top card, all players become &lt;em&gt;active&lt;/em&gt;. An active player may &lt;em&gt;call&lt;/em&gt; a card name (e.g. “five of spades”). The first active player to call a &lt;em&gt;qualifying card&lt;/em&gt; wins the round and collects the discard pile. A qualifying card is a card that differs in both rank and suit color from the top card in the discard pile, as described below.&lt;/p&gt;

&lt;h1 id=&quot;qualified-cards&quot;&gt;Qualified Cards&lt;/h1&gt;

&lt;p&gt;To qualify, a card must have a different rank and a different color suit than the top card. If the top card is a face card or an ace, the qualifying card must additionally be a face card or an ace. If the top card is a number card (two through ten), the qualifying card must additionally be a number card.&lt;/p&gt;

&lt;p&gt;Examples:&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th style=&quot;text-align: left&quot;&gt;Top Card&lt;/th&gt;
      &lt;th style=&quot;text-align: left&quot;&gt;Qualifying Calls&lt;/th&gt;
      &lt;th style=&quot;text-align: left&quot;&gt;Non-Qualifying Calls&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;3♠&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;4♡, 9♧&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;3♡, 4, A♡, J♣&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;6♢&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;2♠, 8♣&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;3♢, 6, J♡&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;Q♡&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;K♠, A♦&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;9♦, Q♦, A♢&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;A♣&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;J♢, Q♡&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;10♢, 7♣, J♠&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;In a two player game, if one player names a card that doesn’t qualify, the other player wins the dealt card. Otherwise, the first player to name a qualifying card wins the card.&lt;/p&gt;

&lt;h1 id=&quot;active-players&quot;&gt;Active Players&lt;/h1&gt;

&lt;p&gt;When the top card is dealt, all players are active. A player who calls a non-qualifying card becomes inactive, if there are other players who have not yet called a non-qualifying card in this turn. Once all players have called non-qualifying cards, all players become active for the remainder of the round.&lt;/p&gt;

&lt;p&gt;Example: Player one wins on the first call.&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th style=&quot;text-align: left&quot;&gt;Top Card&lt;/th&gt;
      &lt;th style=&quot;text-align: center&quot;&gt;Player 1 Calls&lt;/th&gt;
      &lt;th style=&quot;text-align: center&quot;&gt;Player 2 Calls&lt;/th&gt;
      &lt;th style=&quot;text-align: left&quot;&gt;Result&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;3♠&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt; &lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt; &lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;Round starts; both players are active&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;3♠&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;2♡&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt; &lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;Player 1 wins the round&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;Example: Player one makes an invalid call; player two wins.&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th style=&quot;text-align: left&quot;&gt;Top Card&lt;/th&gt;
      &lt;th style=&quot;text-align: center&quot;&gt;Player 1 Calls&lt;/th&gt;
      &lt;th style=&quot;text-align: center&quot;&gt;Player 2 Calls&lt;/th&gt;
      &lt;th style=&quot;text-align: left&quot;&gt;Result&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;4♢&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt; &lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt; &lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;Round starts; both players are active&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;4♢&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;2♡&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt; &lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;Player 1 becomes inactive&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;4♢&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;3♣&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt; &lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;No effect; player 1 is inactive&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;4♢&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt; &lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;3♣&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;Player 2 wins the round&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;Example: Both players make invalid calls.&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th style=&quot;text-align: left&quot;&gt;Top Card&lt;/th&gt;
      &lt;th style=&quot;text-align: center&quot;&gt;Player 1 Calls&lt;/th&gt;
      &lt;th style=&quot;text-align: center&quot;&gt;Player 2 Calls&lt;/th&gt;
      &lt;th style=&quot;text-align: left&quot;&gt;Result&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;J♣&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt; &lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt; &lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;Round starts; both players are active&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;J♣&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;2♡&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt; &lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;Player 1 becomes inactive&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;J♣&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt; &lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;Q♠&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;Player 2 miscalls; now both players are active acgain&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;J♣&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;Q♡&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt; &lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;Player 1 wins the round&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;h1 id=&quot;call-ties&quot;&gt;Call Ties&lt;/h1&gt;

&lt;p&gt;If two or more active players call a qualifying card simultaneously, the first player to &lt;em&gt;complete&lt;/em&gt; the call (in the judgement of the dealer) wins the turn. If several active players complete qualified calls simultaneously, the first player to &lt;em&gt;begin&lt;/em&gt; the call (in the judgement of the dealer) wins the turn. If several active players begin and end qualified calls simultaneously, the round is a draw and the next card is placed on top of it (and the winner of that round wins the entire discard pile).&lt;/p&gt;

&lt;h1 id=&quot;variants&quot;&gt;Variants&lt;/h1&gt;

&lt;p&gt;We tried a variant where each player is dealt a “match card”: if the top card matches the match card’s suit, a qualifying card &lt;em&gt;for that player&lt;/em&gt; must match the suit instead of differ from it’s color; and if the top card matches the match card’s rank, a qualifying for that player must match the top card’s rank instead of differing from it.&lt;/p&gt;

&lt;p&gt;For example, if player one’s match card is a 9♠, and a 9♡ is dealt, player one must call a 9♡ or 9♢ to win the round (but player two cannot call a nine, unless player two’s match card is also a nine). If player one’s match card is a 9♠ and a K♠ is dealt, player one must call an A♠, J♠, or Q♠ to win.&lt;/p&gt;

&lt;p&gt;This variant was intended to keep the game from getting too easy after we’d played it for a while and therefore presumably gotten better at it. It turned out to be unnecessary. Presumably there’s a &lt;a href=&quot;http://en.wikipedia.org/wiki/Power_Law_of_Practice&quot;&gt;practice effect&lt;/a&gt; eventually, but in our limited experience the game was actually harder the second time we sat down for it.&lt;/p&gt;

&lt;h1 id=&quot;origin&quot;&gt;Origin&lt;/h1&gt;

&lt;p&gt;Stroop is named after the &lt;a href=&quot;http://en.wikipedia.org/wiki/Stroop_effect&quot;&gt;Stroop Effect&lt;/a&gt;. I made it up last weekend after showing the kids &lt;a href=&quot;http://en.wikipedia.org/wiki/GOPS&quot;&gt;GOPS&lt;/a&gt;, and we played it over the weekend.&lt;/p&gt;
</description>
        <pubDate>Sat, 08 Sep 2012 11:26:00 -0400</pubDate>
        <link>https://blog.osteele.com/2012/09/stroop-a-card-game/</link>
        <guid isPermaLink="true">https://blog.osteele.com/2012/09/stroop-a-card-game/</guid>
        
        <category>fun,</category>
        
        <category>games</category>
        
        
      </item>
    
      <item>
        <title>DLW</title>
        <description>&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;From: Daniel Weinreb &amp;lt;dlw@alum.mit.edu&amp;gt;
Date: June 2, 2009 7:30:19 AM EDT
To: Oliver Steele &amp;lt;steele@osteele.com&amp;gt;

Jenny said something to me about a year ago that I find somewhat profound, even though maybe it's not: there are two kinds of people: those who define themselves by what they consume, and those who define themselves by what they produce.

Obviously, all of us are the second kind, and, tacitly but obviously, we find that far superior in both a practical and a moral sense.

I think that's a very important value of our group, one that is so much in the air we breathe that we never even think to express it explicitly.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;RIP, &lt;a href=&quot;http://en.wikipedia.org/wiki/Dan_Weinreb&quot;&gt;DLW&lt;/a&gt;.&lt;/p&gt;
</description>
        <pubDate>Fri, 07 Sep 2012 00:00:00 -0400</pubDate>
        <link>https://blog.osteele.com/2012/09/dlw/</link>
        <guid isPermaLink="true">https://blog.osteele.com/2012/09/dlw/</guid>
        
        <category>sad,</category>
        
        <category>grief,</category>
        
        <category>friends</category>
        
        
      </item>
    
      <item>
        <title>Code Samples from Practical Functional JavaScript</title>
        <description>&lt;p&gt;The code samples from my &lt;a href=&quot;/2008/09/practical-functional-javascript&quot;&gt;talk at the Ajax Experience
conference&lt;/a&gt; are now available
&lt;a href=&quot;https://osteele.com/talks/ajaxian-2008/samples&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Each example runs itself when you load its page, at least in Safari and Firefox.
This is something I first did for my talk at &lt;a href=&quot;http://ll2.ai.mit.edu/&quot;&gt;LL2&lt;/a&gt;. It’s
the only way I’ve ever been able to keep sample code actually working&lt;sup id=&quot;fnref:1&quot;&gt;&lt;a href=&quot;#fn:1&quot; class=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;

&lt;p&gt;The full slide deck (including these code samples, but without the comments and
the ability to run the code) is
&lt;a href=&quot;http://www.slideshare.net/osteele/oliver-steele-functional-javascript-presentation&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;These are from the final draft of the talk, but they’re really the first draft
of this material. The audience was great, and I learned a lot about how to
explain this from their questions during the presentation. I’m planning to
reorganize and expand this the next time I get a free weekend to work on it.&lt;/p&gt;

&lt;hr /&gt;

&lt;div class=&quot;footnotes&quot;&gt;
  &lt;ol&gt;
    &lt;li id=&quot;fn:1&quot;&gt;
      &lt;p&gt;A funny story about that: John Resig asked me after the talk whether I’d looked at &lt;a href=&quot;http://ejohn.org/apps/learn/&quot;&gt;Learn JavaScript&lt;/a&gt;. The truth is, I’d wanted to get by without any fancy slideware or sample scaffolding at all, but I needed a way to get formatted code into Keynote. I started out using a technique that &lt;a href=&quot;http://www.macvicar.net/blog/2008/06/source-code-hig.html&quot;&gt;Scott MacVicar&lt;/a&gt; came up with, and eventually added section breaks, and then “Previous” and “Next” buttons, until I’d eventually feature-crept my way up to something pretty similar to John’s tool. Oh well. &lt;a href=&quot;#fnref:1&quot; class=&quot;reversefootnote&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
  &lt;/ol&gt;
&lt;/div&gt;
</description>
        <pubDate>Thu, 02 Oct 2008 21:52:47 -0400</pubDate>
        <link>https://blog.osteele.com/2008/10/code-samples-from-practical-functional-javascript/</link>
        <guid isPermaLink="true">https://blog.osteele.com/2008/10/code-samples-from-practical-functional-javascript/</guid>
        
        <category>JavaScript,</category>
        
        <category>functional,</category>
        
        <category>talks,</category>
        
        <category>conferences</category>
        
        
        <category>JavaScript</category>
        
      </item>
    
      <item>
        <title>Practical Functional JavaScript</title>
        <description>&lt;p&gt;I’ll be giving a talk next Wednesday October 1 at &lt;a href=&quot;http://ajaxexperience.techtarget.com/east/index.html&quot;&gt;The AJAX Experience&lt;/a&gt;, on “Practical Functional JavaScript”.  This could be subtitled “distributing JavaScript across time and space”, or maybe just “how to do things with functions”&lt;sup id=&quot;fnref:1&quot;&gt;&lt;a href=&quot;#fn:1&quot; class=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;

&lt;!-- more --&gt;

&lt;p&gt;A couple of years ago I found that all the interesting AJAX programs that I wanted to write involved asynchronous communication with the server (or sometimes with a Flash plugin, or sometimes within the client but with a few seconds or minutes delay). Trying to think about and debug these programs made me feel like I was just learning how to program again (or hadn’t yet), and hurt my head.  But now I can emerge, sadder but wiser, head fully healed, and with this talk in hand.&lt;/p&gt;

&lt;p&gt;I’ll be covering:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;Talking REST asynchronously to your server – &lt;em&gt;without&lt;/em&gt; dipping into bleeding-edge technologies such as &lt;a href=&quot;http://en.wikipedia.org/wiki/Comet_(programming)&quot;&gt;Comet&lt;/a&gt; and &lt;a href=&quot;http://svn.xantus.org/shortbus/trunk/bayeux/bayeux.html&quot;&gt;Bayeux&lt;/a&gt;.&lt;sup id=&quot;fnref:2&quot;&gt;&lt;a href=&quot;#fn:2&quot; class=&quot;footnote&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Deferred execution and lightweight multithreading without &lt;a href=&quot;http://code.google.com/apis/gears/api_workerpool.html&quot;&gt;Google Gears&lt;/a&gt;.&lt;sup id=&quot;fnref:3&quot;&gt;&lt;a href=&quot;#fn:3&quot; class=&quot;footnote&quot;&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Messaging between the Flash and the HTML within a page.  I’ll put this last so that if you aren’t interested in Flash you don’t have to worry about when to wake up.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This talk is really the flip side of &lt;a href=&quot;https://osteele.com/sources/javascript/functional/&quot;&gt;functional javascript&lt;/a&gt; and &lt;a href=&quot;https://osteele.com/sources/javascript/sequentially/&quot;&gt;sequentially&lt;/a&gt;. Those were &lt;em&gt;non-production&lt;/em&gt; experiments to take functional javascript &lt;em&gt;to an extreme&lt;/em&gt;.  “Practical”, on the other hand, will be about real-world techniques I’ve used to write web sites such as &lt;a href=&quot;http://browsegoods.com&quot;&gt;Browsegoods&lt;/a&gt;, &lt;a href=&quot;http://fansnap.com&quot;&gt;FanSnap&lt;/a&gt;, Style&amp;amp;Share, and the &lt;a href=&quot;http://www.gowebtop.com&quot;&gt;goWebtop Calendar&lt;/a&gt;, and that resulted in some of the JavaScript-related libraries &lt;a href=&quot;http://github.com/osteele&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;em&gt;main&lt;/em&gt; purpose of this talk is to be useful to practicing developers.  But it should also be fun.  AJAX lets you do a lot on the web that’s fun to look at and use.  It can be fun to program too, and I’d like to get some of that across.&lt;/p&gt;

&lt;p&gt;If you’re interested in the &lt;em&gt;type&lt;/em&gt; of things I’ve posted &lt;a href=&quot;/category/javascript&quot;&gt;here&lt;/a&gt;, but found that those zoomed through the material too quickly or that you wanted to see more of a connection to real-world production programming, then this is the talk for you.&lt;/p&gt;

&lt;p&gt;The bad news: &lt;a href=&quot;http://ajaxexperience.techtarget.com/east/html/eventsataglance.html&quot;&gt;It’s at 8am&lt;/a&gt;.  I promise not to think badly of you if you take a nap, and to make loud noises when it’s time for you to go your next talk.&lt;/p&gt;

&lt;p&gt;Update: A draft of the talk is &lt;a href=&quot;https://osteele.com/talks/Oliver_Steele_Functional_JavaScript_v2.pdf&quot;&gt;here&lt;/a&gt; (PDF).  It doesn’t include most of the code samples.&lt;/p&gt;

&lt;p&gt;Update 2: The final version with screenshots of all the code is &lt;a href=&quot;http://www.slideshare.net/osteele/oliver-steele-functional-javascript-presentation&quot;&gt;here&lt;/a&gt;.  I’ll publish a runnable version of the examples soon.&lt;/p&gt;

&lt;p&gt;Update 3: The runnable examples are &lt;a href=&quot;/2008/10/code-samples-from-practical-functional-javascript&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;hr /&gt;

&lt;div class=&quot;footnotes&quot;&gt;
  &lt;ol&gt;
    &lt;li id=&quot;fn:1&quot;&gt;
      &lt;p&gt;With a nod to &lt;a href=&quot;http://en.wikipedia.org/wiki/J._L._Austin#How_to_Do_Things_With_Words&quot;&gt;Austin&lt;/a&gt; – but you don’t have to get that, if you aren’t a linguistics geek. &lt;a href=&quot;#fnref:1&quot; class=&quot;reversefootnote&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:2&quot;&gt;
      &lt;p&gt;COMET and Bayeaux are cool, but the server-side support can be scary. &lt;a href=&quot;#fnref:2&quot; class=&quot;reversefootnote&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:3&quot;&gt;
      &lt;p&gt;Another cool technology, but for the typical occasional-use consumer-facing site, you can’t count on it. &lt;a href=&quot;#fnref:3&quot; class=&quot;reversefootnote&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
  &lt;/ol&gt;
&lt;/div&gt;
</description>
        <pubDate>Wed, 24 Sep 2008 15:06:06 -0400</pubDate>
        <link>https://blog.osteele.com/2008/09/practical-functional-javascript/</link>
        <guid isPermaLink="true">https://blog.osteele.com/2008/09/practical-functional-javascript/</guid>
        
        <category>JavaScript,</category>
        
        <category>functional,</category>
        
        <category>talks,</category>
        
        <category>conferences</category>
        
        
        <category>JavaScript</category>
        
      </item>
    
      <item>
        <title>Latin Agreement and Case</title>
        <description>&lt;p&gt;&lt;a href=&quot;https://images.osteele.com/2008/latin%20agreement.png&quot;&gt;&lt;img src=&quot;https://images.osteele.com/2008/latin%20agreement.png&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://images.osteele.com/2008/latin%20agreement.pdf&quot;&gt;PDF&lt;/a&gt;, &lt;a href=&quot;https://images.osteele.com/2008/latin%20agreement.png&quot;&gt;PNG&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here’s a chart from a couple of years ago when my son was studying Latin.  Like several things I’ve done, reaction seems to be split between “this makes it clearer” and “this makes it much more confusing”.  Thing of it as a variance magnifier &lt;img src=&quot;https://images.osteele.com/2008/bimodal.png&quot; alt=&quot;&quot; /&gt;1 :-)&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;1 The pseudo-&lt;a href=&quot;http://en.wikipedia.org/wiki/Sparkline&quot;&gt;sparkline&lt;/a&gt; is either a bimodal distribution, or a &lt;a href=&quot;http://en.wikipedia.org/wiki/The_Little_Prince&quot;&gt;programming language mascot that has swallowed a fedora&lt;/a&gt;.&lt;/p&gt;
</description>
        <pubDate>Sun, 25 May 2008 13:45:05 -0400</pubDate>
        <link>https://blog.osteele.com/2008/05/latin-agreement-and-case/</link>
        <guid isPermaLink="true">https://blog.osteele.com/2008/05/latin-agreement-and-case/</guid>
        
        <category>language,</category>
        
        <category>posters,</category>
        
        <category>illustrations</category>
        
        
        <category>Illustrations</category>
        
        <category>Words</category>
        
      </item>
    
      <item>
        <title>Commit Policies</title>
        <description>&lt;p&gt;Git is a complicated beast. The Git index, if you’re coming from other VCS’s, is
a new concept. Yesterday &lt;a href=&quot;/2008/05/my-git-workflow&quot;&gt;I described&lt;/a&gt; how I use the
Git index in my workflow:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/archive/2008/05/my-git-workflow&quot;&gt;&lt;img src=&quot;https://images.osteele.com/2008/git-transport.png&quot; alt=&quot;&quot; /&gt;&lt;img src=&quot;https://images.osteele.com/2008/git-workflow.png&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;!-- more --&gt;

&lt;p&gt;These pictures illustrate the multiple locations, or “data stores”, that host a
copy of the source tree. These stores are: the working directory, local and
remote repositories, and the index. In order to show more of the whole
development process, the second picture also includes a “distribution
directory”, for code that is being distributed outside of Git. (The distribution
directory could be the deployment directory of a web site, or a compiled
artifact, such as a binary, that is placed in firmware or on a DVD.)&lt;/p&gt;

&lt;h2 id=&quot;salmon-run-development&quot;&gt;Salmon Run Development&lt;/h2&gt;

&lt;p&gt;The x axis in these pictures is actually meaningful. In fact, it has several
meanings. Towards the left is personal (only I can see my working directory);
towards the right is public (the remote repository is visible to other
developers; the distribution directory to users as well). Towards the left is
closer to closer to development, towards the right is closer to production.
Towards the left is easier to change; towards the right is more stable&lt;sup id=&quot;fnref:1&quot;&gt;&lt;a href=&quot;#fn:1&quot; class=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://images.osteele.com/2008/datastore-spectrum.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Two of the most important properties of a project are its design flexibility
(the ease with which developers can change it), and its stability. Flexibility
is necessary in order to maintain development velocity, to accommodate changing
requirements, and to explore design spaces. Stability is important in order to
maintain quality (by allowing settling time for bugs, and by reducing their
injection rate), and to synchronize with separately developed artifacts (test
suites, test plans, and documentation, if they’re not in the repository; and
books, forum and blog postings, and user knowledge). Unfortunately, these
properties conflict.&lt;/p&gt;

&lt;p&gt;Putting each of these constraints at the opposite end of the chain of data
stores allows you to compromise each individual data store less. You don’t need
to maintain as stable a workspace, but the remote repository needn’t be yanked
around as much.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://images.osteele.com/2008/flexible-stable.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;I picture the process of moving edits from my working directory to a
distribution as a multi-stage
&lt;a href=&quot;http://en.wikipedia.org/Transmission_%28mechanical%29&quot;&gt;transmission&lt;/a&gt;, where
each step to the right steps down in speed (development velocity) but up in
torque (quality). Making the chain longer means there’s more of an impedance
match between any two successive stores. This is why DVCS is better than VCS;
and it’s why I like to use the index as a staging area&lt;sup id=&quot;fnref:2&quot;&gt;&lt;a href=&quot;#fn:2&quot; class=&quot;footnote&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;

&lt;p&gt;I also picture the process of moving edits to a distribution as a salmon
run&lt;sup id=&quot;fnref:3&quot;&gt;&lt;a href=&quot;#fn:3&quot; class=&quot;footnote&quot;&gt;3&lt;/a&gt;&lt;/sup&gt;. To make it from the index up to a distribution, a change has to swim up
a series of falls. Each level of the stream is a data store; it has to leap the
lowest fall to make it into the index, and another to make it into the local
repository. Only a few changes are strong enough to make it all the way.
[Although, unlike salmon, changes can team up to make a stronger fish. Or maybe
I’m not talking about salmon, but salmon DNA. I’ll drop the metaphor in a moment
:-)]&lt;/p&gt;

&lt;p&gt;What makes the falls steep – what makes it more difficult for a change to get
further towards distribution – isn’t (in this age of fast networks, reliable
DVCS, and automated deployment recipes) a technical limitation; it’s a matter of
convention. In this case, it’s a matter of conventions that are constructed to
maintain the quality of releases, by maintaining invariants on the data stores
that feed into them. These conventions are commit policies.&lt;/p&gt;

&lt;h2 id=&quot;commit-policies&quot;&gt;Commit Policies&lt;/h2&gt;

&lt;p&gt;The most helpful paper I’ve read on source control is &lt;a href=&quot;http://www.perforce.com/perforce/bestpractices.html&quot;&gt;“High-level Best
Practices in Software Configuration
Management”&lt;/a&gt;, by Laura
Wingerd and Christopher Seiwald of Perforce Software. Its most helpful
recommendation is “Give each codeline a policy”. (The runners up are “branch on
a policy change”, and “don’t branch unless necessary”.)&lt;/p&gt;

&lt;p&gt;Git’s data stores are in many ways like anonymous, built-in branches, with a
built-in set of commands that operate on them&lt;sup id=&quot;fnref:4&quot;&gt;&lt;a href=&quot;#fn:4&quot; class=&quot;footnote&quot;&gt;4&lt;/a&gt;&lt;/sup&gt;. Like branches, I find it
helpful to give each data store its own policy. Each policy is more rigorous
than the policy to its left. These policies tell me how far upstream a change
can swim.&lt;/p&gt;

&lt;p&gt;Here’s an example of the policies I use in my personal projects, or for the
non-shared part (the workspace, index, and local repository) of a collaborative
project. “Revision Frequency” is how often I typically make changes to each data
store, when I’m developing it full-time.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://images.osteele.com/2008/commit-policies.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Policies implement the intent of the salmon run. By placing un-restrictive
policies to the left, I can checkpoint my work frequently. By placing
restrictive policies on the right, I can maintain the stability of releases. And
by incrementing the restrictiveness of these policies in small steps, I reduce
the backlog of code that is “trapped” towards the left. Compare this to a
centralized VCS, in which (since there’s no local repository), developers may
keep changes out of VCS for hours or days (since the alternative is making a
central branch, which is expensive to create and expensive to tear down). Or
compare to a DVCS system without an index, where the overhead of either making
and tearing down branches, or of pruning temporary commits, can discourage a
developer from making a checkpoint every minute or two. (At least they
discourage me, even though these operations are far less expensive than with
centralized VCS.)&lt;/p&gt;

&lt;p&gt;And no, I’m not saying to do this &lt;em&gt;instead&lt;/em&gt; of branching. I find this system
useful as an always-on, lightweight alternative to branching, and then add in
branching when the lifting gets heaver. This process, without branches, is as
much mechanism as I usually want for small, personal projects such as
&lt;a href=&quot;http://github.com/osteele&quot;&gt;these&lt;/a&gt;. For a collaborative project, I often synch
to a feature branch of the main repository. For an experiment that takes more
than half a day, and that I therefore want to be able to set aside, I make a
local branch. And for a shared collaborative experiment, or a feature that calls
on only part of the development team, I do both.&lt;/p&gt;

&lt;p&gt;More on branches tomorrow.&lt;/p&gt;

&lt;hr /&gt;

&lt;div class=&quot;footnotes&quot;&gt;
  &lt;ol&gt;
    &lt;li id=&quot;fn:1&quot;&gt;
      &lt;p&gt;The reasons for these differences are partly convention, but mostly technical. I can easily make and revert changes in my workspace with my editor (or another tool). Changes to the index and the local repository require some extra work with some command line intervention but can still be rolled back (via &lt;code class=&quot;highlighter-rouge&quot;&gt;get rebase -i&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;git reset&lt;/code&gt;) without a trace. Changes to the remote repository are carved in stone (I can only revert them with &lt;code class=&quot;highlighter-rouge&quot;&gt;git revert&lt;/code&gt;, which reverses the reverted change but leaves both it and its reversion in the permanent record). Changes to the distribution require a new version number, an announcement, and, depending on the circumstances, a recall notice and egg on my face. &lt;a href=&quot;#fnref:1&quot; class=&quot;reversefootnote&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:2&quot;&gt;
      &lt;p&gt;But why not use branches? Yeah, I’ll get to branches. But the answer is mostly just personal preference. &lt;a href=&quot;#fnref:2&quot; class=&quot;reversefootnote&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:3&quot;&gt;
      &lt;p&gt;Since you’re such a careful reader that you even bother to read footnotes, I’ll let you in on a secret. I like to think about abstract stuff, but I’m not much good with abstractions. Instead, I try to keep my concept library well-stocked with metaphors. Then the hard parts become easy again. &lt;a href=&quot;#fnref:3&quot; class=&quot;reversefootnote&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:4&quot;&gt;
      &lt;p&gt;For example, &lt;code class=&quot;highlighter-rouge&quot;&gt;git diff&lt;/code&gt; tells me what’s different between my working directory and the index, without my having to build up, tear down, or remember any branch names. The working directory and the index are self-cleaning (they don’t collect commits that I have to squash later); this has advantages and disadvantages, but it works for me and for the granularity with which I save to them. &lt;a href=&quot;#fnref:4&quot; class=&quot;reversefootnote&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
  &lt;/ol&gt;
&lt;/div&gt;
</description>
        <pubDate>Sat, 10 May 2008 19:51:30 -0400</pubDate>
        <link>https://blog.osteele.com/2008/05/commit-policies/</link>
        <guid isPermaLink="true">https://blog.osteele.com/2008/05/commit-policies/</guid>
        
        <category>git,</category>
        
        <category>illustrations</category>
        
        
        <category>Illustrations</category>
        
        <category>Software Development</category>
        
      </item>
    
      <item>
        <title>My Git Workflow</title>
        <description>&lt;p&gt;&lt;a href=&quot;http://git.or.cz/&quot;&gt;Git&lt;/a&gt;’s great! But it’s difficult to learn (it was for me,
anyway) – especially the index, which unlike the power-user features, comes up
in day-to-day operation.&lt;/p&gt;

&lt;p&gt;Here’s my path to enlightenment, and how I ended up using the index in my
particular workflow. There are other workflows, but this one is mine.&lt;/p&gt;

&lt;!-- more --&gt;

&lt;p&gt;What this isn’t: a Git tutorial. It doesn’t tell you how to set up git, or use
it. I don’t cover branches, or merging, or tags, or blobs. There are dozens of
really great articles about Git on the web; here are
&lt;a href=&quot;http://del.icio.us/osteele/git&quot;&gt;some&lt;/a&gt;. What’s here are just some pictures that
&lt;em&gt;aren’t&lt;/em&gt; about branches or blobs, that I wished I’d been able to look at six
months ago when I was trying to figure this stuff out; I still haven’t seen them
elsewhere, so here they are now.&lt;/p&gt;

&lt;h2 id=&quot;my-brief-history-with-git&quot;&gt;My brief history with Git&lt;/h2&gt;

&lt;p&gt;I started using Git about six months ago, in order to productively subcontract
for a company that still uses Perforce. Before that I had been a happy Mercurial
user; before that, a Darcs devotee; before that, a mildly satisfied Subversion
supplicant; and before that, a Perforce proponent. (That last was before the
other systems even &lt;em&gt;existed&lt;/em&gt;. I introduced Perforce into a couple of companies
that had previously been using SourceSafe(!) – including the one I was now
contracting for.)&lt;/p&gt;

&lt;p&gt;Each of these systems has flaws. Perforce and Subversion require an always-on
connection and make branching (and merging) expensive, and Perforce uses
pessimistic locking too (you have to check a file out before you can edit it). I
got hit by the exponential merge bug in Darcs (since fixed?); a deeper problem
was that I found I wanted to be able to go back in time more often than I needed
to commute patches, whereas Darcs makes the latter easy at the expense of the
former – so Darcs’ &lt;a href=&quot;http://darcs.net/manual/node8.html#Patch&quot;&gt;theory of
patches&lt;/a&gt;, although insightful and
beautiful, just didn’t match my workflow.&lt;/p&gt;

&lt;p&gt;Git’s problem is its complexity. Half of that is because it’s actually more
powerful than the other systems: it’s got features that make it look scary but
that you can ignore. Another half is that Git uses nonstandard names for about
half its most common operations. (The rest of the VCS world has more or less
settled on a basic command set, with names such as “checkout” and “revert”. Not
Git!) And the third half is the index. The index is a mechanism for preventing
what you commit from matching what you tested in your working directory. Huh?&lt;/p&gt;

&lt;h2 id=&quot;git-without-the-index&quot;&gt;Git without the index&lt;/h2&gt;

&lt;p&gt;I got through my first four months of Git by &lt;a href=&quot;http://git.or.cz/course/svn.html&quot;&gt;pretending it was
Subversion&lt;/a&gt;. (A faster implementation of
Subversion, that works offline, with non-awful branches and merging, that can
run as a client to Perforce – but still basically Subversion.) The executive
summary of this mode of operation is that if you use “&lt;code class=&quot;highlighter-rouge&quot;&gt;git commit -a&lt;/code&gt;” instead
of “&lt;code class=&quot;highlighter-rouge&quot;&gt;git commit&lt;/code&gt;”, you can ignore the index altogether. You can alias &lt;code class=&quot;highlighter-rouge&quot;&gt;ci&lt;/code&gt; to
“&lt;code class=&quot;highlighter-rouge&quot;&gt;commit -a&lt;/code&gt;” (and train yourself not to use the longer &lt;code class=&quot;highlighter-rouge&quot;&gt;commit&lt;/code&gt;, which I hadn’t
been doing anyway), and then you don’t have to remember the command-line
argument either:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ cat ~/.gitconfig
[alias]
  ci = commit -a
  co = checkout
  st = status -a
$ git ci -m 'some changes'
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;adding-back-the-index&quot;&gt;Adding Back the Index&lt;/h2&gt;

&lt;p&gt;Git keeps copies of your source tree in the locations in this diagram&lt;sup id=&quot;fnref:1&quot;&gt;&lt;a href=&quot;#fn:1&quot; class=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;. (I’ll
call these locations “data stores”.)&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://images.osteele.com/2008/git-transport.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The data store that’s new, relative to every other DVCS that I know about, is
the “index”. The one that’s new relative to centralized VCS’s such as Subversion
and Perforce is the “local repository”.&lt;/p&gt;

&lt;p&gt;The illustration shows that “&lt;code class=&quot;highlighter-rouge&quot;&gt;git add&lt;/code&gt;” is the only (everyday) operation that
can cause the index to diverge from the local repository. The only reason (in
Subversion-emulation mode) to use “&lt;code class=&quot;highlighter-rouge&quot;&gt;git add&lt;/code&gt;” is so that “&lt;code class=&quot;highlighter-rouge&quot;&gt;git commit&lt;/code&gt;” will see
your changes. The &lt;code class=&quot;highlighter-rouge&quot;&gt;-a&lt;/code&gt; option to “&lt;code class=&quot;highlighter-rouge&quot;&gt;git commit&lt;/code&gt;” causes “&lt;code class=&quot;highlighter-rouge&quot;&gt;git commit&lt;/code&gt;” to run
“&lt;code class=&quot;highlighter-rouge&quot;&gt;git add -u&lt;/code&gt;” first – in which case you never need to &lt;code class=&quot;highlighter-rouge&quot;&gt;run &quot;git add -u&lt;/code&gt;”
explicitly – in which case the index stays in sync with the repository head.
This is how the trick in “git without the index” works: if you always use commit
via “&lt;code class=&quot;highlighter-rouge&quot;&gt;git commit -a&lt;/code&gt;”, you can ignore the index&lt;sup id=&quot;fnref:2&quot;&gt;&lt;a href=&quot;#fn:2&quot; class=&quot;footnote&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;

&lt;p&gt;So what’s the point of the index? Is it because Linus likes complicated things?
Is to one-up all the other repositories? Is it to increase the complexity of
system, so that you have a chance to shoot yourself in the foot if you’re not an
alpha enough geek?&lt;/p&gt;

&lt;p&gt;Well, probably. But it’s good for something else as well. Several things,
actually; I’ll show you one (that I use), and point you to another.&lt;/p&gt;

&lt;p&gt;But first, a piece of background that helps in understanding Git. Git isn’t at
its core a VCS. It’s really a distributed versioning file system, down to its
own &lt;a href=&quot;http://www.kernel.org/pub/software/scm/git/docs/git-fsck.html&quot;&gt;fsck&lt;/a&gt; and
&lt;a href=&quot;http://www.kernel.org/pub/software/scm/git/docs/git-gc.html&quot;&gt;gc&lt;/a&gt;. It was
developed as the bottom layer of a VCS, but the VCS layer, which provides the
conventional VCS commands (&lt;code class=&quot;highlighter-rouge&quot;&gt;commit&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;checkout&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;branch&lt;/code&gt;), is more like an
uneven veneer than like the “porcelain” it’s sometimes called: bits of file
system (git core) internals poke through.&lt;/p&gt;

&lt;p&gt;The disadvantage of this (leaky) layering is that Git is complicated. If you
look up how to diff against yesterday’s 1pm sources in &lt;a href=&quot;http://www.kernel.org/pub/software/scm/git/docs/git-diff.html&quot;&gt;git
diff&lt;/a&gt;, it will
send you to &lt;a href=&quot;http://www.kernel.org/pub/software/scm/git/docs/git-rev-parse.html&quot;&gt;git
rev-parse&lt;/a&gt;
from the core; if you look up &lt;a href=&quot;http://www.kernel.org/pub/software/scm/git/docs/git-checkout.html&quot;&gt;git
checkout&lt;/a&gt;,
you may end up at
&lt;a href=&quot;http://www.kernel.org/pub/software/scm/git/docs/git-check-ref-format.html&quot;&gt;git-check-ref-format&lt;/a&gt;.
Most of this you can ignore, but it takes some reading to figure out which.&lt;/p&gt;

&lt;p&gt;The advantage of the layering is that you can use Git to build your own
workflows. Some of these workflows involve the index. Like the other fancy Git
features, building your own workflows is something that you can ignore
initially, and add when you get to where you need it. This is, historically, how
I’ve used the index: I ignored it until I was comfortable with more of Git, and
now I use it for a more productive workflow than I had with other VCS’s. It’s
not my main reason for using Git, but it’s turned to a strength from being a
liability.&lt;/p&gt;

&lt;h2 id=&quot;my-git-workflow&quot;&gt;My Git Workflow&lt;/h2&gt;

&lt;p&gt;Added: By way of illustration, here’s how I use Git. I’m not recommending this
particular workflow; instead, I’m hoping that it can further illustrate the
relation between the workspace, the index, and the repository; and also the more
general idea of using Git to build a workflow.&lt;/p&gt;

&lt;p&gt;I use the index as a checkpoint. When I’m about to make a change that might go
awry – when I want to explore some direction that I’m not sure if I can follow
through on or even whether it’s a good idea, such as a conceptually demanding
refactoring or changing a representation type – I checkpoint my work into the
index. If this is the first change I’ve made since my last commit, then I can
use the local repository as a checkpoint, but often I’ve got one conceptual
change that I’m implementing as a set of little steps. I want to checkpoint
after each step, but save the commit until I’ve gotten back to working, tested
code. (More on this tomorrow.)&lt;/p&gt;

&lt;p&gt;Added: This way I can checkpoint every few minutes. It’s a very cheap operation,
and I don’t have to spend time cleaning up the checkpoints later. “&lt;code class=&quot;highlighter-rouge&quot;&gt;git diff&lt;/code&gt;”
tells me what I’ve changed since the last checkpoint; “&lt;code class=&quot;highlighter-rouge&quot;&gt;git diff head&lt;/code&gt;” shows
what’s changed since the last commit. “&lt;code class=&quot;highlighter-rouge&quot;&gt;git checkout .&lt;/code&gt;” reverts to the last
checkpoint; “&lt;code class=&quot;highlighter-rouge&quot;&gt;git checkout head .&lt;/code&gt;” reverts to the last commit. And “&lt;code class=&quot;highlighter-rouge&quot;&gt;git
stash&lt;/code&gt;” and “&lt;code class=&quot;highlighter-rouge&quot;&gt;git checkout -m -b&lt;/code&gt;” operate on the changes since the last commit,
which is what I want.&lt;/p&gt;

&lt;p&gt;I’m most efficient when I can fearlessly try out risky changes. Having a test
suite is one way to be fearless: the fear of having to step through a set of
manual steps to test each changed code path, or worse yet missing some, inhibits
creativity. Being able to roll back changes to the last checkpoint eliminates
another source of fear.&lt;/p&gt;

&lt;p&gt;I used to make copies of files before I edited them; my directory would end up
littered with files like &lt;code class=&quot;highlighter-rouge&quot;&gt;code.java.1&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;code.java.2&lt;/code&gt;, which I would
periodically sweep away. Having Git handle the checkpoint and diff with them
makes all this go faster. (Having painless branches does the same for
longer-running experiments, but I don’t want to create and then destroy a branch
for every five-minute change.)&lt;/p&gt;

&lt;p&gt;Here’s another picture of the same Git commands, this time shown along a second
axis, time, proceeding from top to bottom. [This is the behavior diagram to the
last picture’s dataflow diagram. Kind of.] A number of local edits adds up to
something I checkpoint to the index via “&lt;code class=&quot;highlighter-rouge&quot;&gt;git add -u&lt;/code&gt;”; after a while I’ve
collected something I’m ready to commit; and every so many commits I push
everything so far to a remote repository, for backup (although I’ve got other
backup systems), and for sharing.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://images.osteele.com/2008/git-workflow.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;I’ve even added another step, releasing a distribution, that goes outside of
git. This uses rsync (or scp, or some other build or deployment tool) to upload
a tar file (or update a web site, or build a binary to place on a DVD).&lt;/p&gt;

&lt;h2 id=&quot;some-alternatives&quot;&gt;Some Alternatives&lt;/h2&gt;

&lt;p&gt;Ryan Tomayko has written an &lt;a href=&quot;http://tomayko.com/writings/the-thing-about-git&quot;&gt;excellent
essay&lt;/a&gt; about a completely
different way to use the repository. I recommend it wholeheartedly.&lt;/p&gt;

&lt;p&gt;Ryan’s workflow is completely incompatible with mine. Ryan uses the repository
to tease apart the changes in his working directory into a sequence of separate
commits. I prefer to commit only code that I’ve tested in my directory, so
Ryan’s method doesn’t work for me. I set pending work aside via &lt;code class=&quot;highlighter-rouge&quot;&gt;git stash&lt;/code&gt; or
&lt;code class=&quot;highlighter-rouge&quot;&gt;git checkout -m -b&lt;/code&gt; when I know I might need to interrupt it with another
change; this sounds like it might not work for Ryan. Neither one of these
workflows is wrong (and I could easily use Ryan’s, I’m just slightly more
efficient with mine); Git supports them both.&lt;/p&gt;

&lt;p&gt;There’s another way to do this particular task – of checkpointing after every
few edits, but only persisting some of these checkpoints into the repository.
This is to commit each checkpoint to the repository (and go back to ignoring the
index – at least for checkpointing – so this might work with Ryan’s), and
&lt;code class=&quot;highlighter-rouge&quot;&gt;rebase&lt;/code&gt; them later. Git lets you squash a number of commits into a single
commit before you push it to a public repository (and edit, reorder, and drop
un-pushed commits too) – that’s the &lt;code class=&quot;highlighter-rouge&quot;&gt;rebase -i&lt;/code&gt; block in the previous
illustration, and you can read about it
&lt;a href=&quot;http://blog.moertel.com/articles/2007/12/10/how-i-stopped-missing-darcs-and-started-loving-git&quot;&gt;here&lt;/a&gt;.
This is a perfectly legitimate mode of operation; it’s just one that I don’t
use.&lt;/p&gt;

&lt;p&gt;Both of these alternatives harken back to Git as being a tool for designing VCS
workflows, as much as being a VCS system itself. The reasons I don’t use them
myself bring us to Commit Policies, which I’ll write about
&lt;a href=&quot;/2008/05/commit-policies&quot;&gt;tomorrow&lt;/a&gt;.&lt;/p&gt;

&lt;hr /&gt;

&lt;div class=&quot;footnotes&quot;&gt;
  &lt;ol&gt;
    &lt;li id=&quot;fn:1&quot;&gt;
      &lt;p&gt;This picture shows just those commands that copy data between the local repository, the remote repository, the index, and your workspace. There’s lots more going on &lt;em&gt;inside&lt;/em&gt; these repositories (branches, tags, and heads; or, blobs, trees, commits, and refs). In fact, during a merge, there’s more going on inside the &lt;em&gt;index&lt;/em&gt;, too (“mine”, “ours”, and “theirs”). To a first approximation, all that’s orthogonal to how data gets &lt;em&gt;between&lt;/em&gt; data stores; we’ll ignore it. &lt;a href=&quot;#fnref:1&quot; class=&quot;reversefootnote&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:2&quot;&gt;
      &lt;p&gt;This isn’t quite true. You still need to use “&lt;code class=&quot;highlighter-rouge&quot;&gt;git add&lt;/code&gt;” a new file to tell git about it, and at that point it’s in your index but not in your repository. You still don’t need to &lt;em&gt;think&lt;/em&gt; about the repository in order to use it this way &lt;a href=&quot;#fnref:2&quot; class=&quot;reversefootnote&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
  &lt;/ol&gt;
&lt;/div&gt;
</description>
        <pubDate>Fri, 09 May 2008 18:01:00 -0400</pubDate>
        <link>https://blog.osteele.com/2008/05/my-git-workflow/</link>
        <guid isPermaLink="true">https://blog.osteele.com/2008/05/my-git-workflow/</guid>
        
        <category>git,</category>
        
        <category>illustrations</category>
        
        
        <category>Illustrations</category>
        
        <category>Software Development</category>
        
      </item>
    
      <item>
        <title>My No TV</title>
        <description>&lt;p&gt;We have a No TV in our living room.&lt;/p&gt;

&lt;p&gt;Sometimes I think it’s our most valuable possession.&lt;/p&gt;

&lt;p&gt;Our No TV gives the whole family somewhere between one and six extra hours every day.  It’s hard to add hours to a day, but the No TV does it.&lt;/p&gt;

&lt;p&gt;Miles uses the time for making stop-motion movies and Flash animations.  Charlotte uses it to read, and write, and compose pieces on the piano.  I use it for writing (code), and writing (English), and to teach myself algebra and geometry and management theory and finance.  Margaret uses it for her many projects too.  We wouldn’t have time for any of this, if it weren’t for our No TV.&lt;/p&gt;

&lt;p&gt;The No TV comes with other benefits as well.  It creates a few square feet of floor space.  And it pays out a few hundred dollars a year.&lt;/p&gt;

&lt;p&gt;In fact, we like our No TV so much, we’ve put one in each of the bedrooms too.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;&lt;strong&gt;Followups&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://pietersz.co.uk/2008/05/i-have-no-tv&quot;&gt;I have a No TV too&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Fri, 09 May 2008 10:18:39 -0400</pubDate>
        <link>https://blog.osteele.com/2008/05/my-no-tv/</link>
        <guid isPermaLink="true">https://blog.osteele.com/2008/05/my-no-tv/</guid>
        
        <category>family</category>
        
        
        <category>Family</category>
        
      </item>
    
      <item>
        <title>The Biofuel Economy</title>
        <description>&lt;p&gt;(Or, a &lt;a href=&quot;http://en.wikipedia.org/wiki/Cobordism&quot;&gt;Cobordism&lt;/a&gt; of Carbon.)&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://images.osteele.com/2008/biofuel-economy.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Here’s my understanding of &lt;a href=&quot;http://en.wikipedia.org/wiki/Food_vs_fuel#Impact_on_poor_countries&quot;&gt;this&lt;/a&gt; (with the energy cost dip greatly exaggerated).&lt;/p&gt;

&lt;p&gt;Oops! It takes a village (down) to raise an (American) child.&lt;/p&gt;

&lt;p&gt;Anyone want to make one of these with real numbers?&lt;/p&gt;
</description>
        <pubDate>Fri, 09 May 2008 10:18:20 -0400</pubDate>
        <link>https://blog.osteele.com/2008/05/biofuel-economy/</link>
        <guid isPermaLink="true">https://blog.osteele.com/2008/05/biofuel-economy/</guid>
        
        <category>illustrations</category>
        
        
        <category>Illustrations</category>
        
        <category>Visualizations</category>
        
      </item>
    
      <item>
        <title>Ambimation</title>
        <description>&lt;p&gt;&lt;img src=&quot;https://images.osteele.com/oflip.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;This is an &lt;a href=&quot;http://en.wikipedia.org/wiki/Ambigram&quot;&gt;ambigram&lt;/a&gt; by &lt;a href=&quot;http://scottkim.com&quot;&gt;Scott Kim&lt;/a&gt;, vectorized by &lt;a href=&quot;http://milessteele.com/&quot;&gt;Miles Steele&lt;/a&gt;, cleaned up by Dan Lewis, and put inside an OpenLaszlo application.  (If you don’t see it, click &lt;a href=&quot;https://images.osteele.com/oflip.html&quot;&gt;here&lt;/a&gt;.)&lt;/p&gt;
</description>
        <pubDate>Thu, 01 May 2008 19:43:11 -0400</pubDate>
        <link>https://blog.osteele.com/2008/05/ambimation/</link>
        <guid isPermaLink="true">https://blog.osteele.com/2008/05/ambimation/</guid>
        
        <category>illustrations,</category>
        
        <category>animations</category>
        
        
        <category>Illustrations</category>
        
      </item>
    
  </channel>
</rss>
