<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">
  <channel>
    <title>Be Genius</title>
    <link>http://bjeanes.com</link>
    <description>  I am an Australian full-stack developer living and working in Chicago.  I strongly advocate open-source software and the community around it.  I currently work primarily in Ruby and Rails but have recently been  doing a lot of Clojure, Go, and Javascript, amongst others.  </description>
    <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/begenius" /><feedburner:info uri="begenius" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><geo:lat>27.504998</geo:lat><geo:long>153.052463</geo:long><item>
      <title>Two months without Twitter</title>
      <link>http://feedproxy.google.com/~r/begenius/~3/1qRghmBTQXk/two-months-without-twitter</link>
      <description>&lt;p&gt;Two months ago, frustrated with inability to focus on the things I cared about in life and at work, I formed a theory:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Twitter (et al.) has slowly been rewiring my brain to encourage rapid context switching. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;On average, it probably takes less than a second to read and process a tweet. There are often hundreds of new tweets between &amp;quot;hits,&amp;quot; which means that during vulnerable times of the day (e.g. in bed before sleep), &lt;strong&gt;my brain is rapidly context switching hundreds of times in a matter of minutes&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;For me, Twitter has always been about consuming information and learning. Despite the fear of &amp;quot;missing out&amp;quot; on interesting links or thoughts in my network[1], which is predominantly made of people I respect and trust, &lt;strong&gt;I decided that this rapid and varied consumption is not a healthy way to achieve this goal&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It's been two months since I uninstalled all Twitter (and Facebook) applications from all my devices. I still tweet occasionally (using iOS/Mac's Notification Center), but I make a point not to check the Twitter feed. &lt;strong&gt;I re-enabled email notifications&lt;/strong&gt; for mentions and only log in to the web interface to reply to mentions/messages.&lt;/p&gt;

&lt;p&gt;I love it. I want this to stick.&lt;/p&gt;

&lt;p&gt;&lt;small&gt;[1] &lt;a href="http://getprismatic.com"&gt;Prismatic&lt;/a&gt; is a pretty great way of countering this. It usually cuts through the noise and gives me meal-sized versions of the best content, instead of bite-sized versions of irrelevancy.&lt;/small&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/begenius/~4/1qRghmBTQXk" height="1" width="1"/&gt;</description>
      <pubDate>Fri, 10 May 2013 22:23:06 -0000</pubDate>
      <dc:date>2013-05-10T22:23:06Z</dc:date>
    <feedburner:origLink>http://bjeanes.com/2013/05/two-months-without-twitter</feedburner:origLink></item>
    <item>
      <title>A collaborative thought experiment on company environment, values, culture, and ethos</title>
      <link>http://feedproxy.google.com/~r/begenius/~3/DHvsOkSr72E/a-collaborative-thought-experiment-on-company-environment-values-culture-and-ethos</link>
      <description>&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt;: add your thoughts/experience on company values and culture to &lt;a href="https://github.com/bjeanes/culture"&gt;this repo&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Lately, I have been thinking a lot about the types of working environments and how they impact the productivity and happiness of the people who work in them.&lt;/p&gt;

&lt;p&gt;After many discussions on and research into the topics of leadership, management, and company culture, I felt like I had to start taking notes of how everything pieced together. Specifically, I wanted to write down what the culture and environment look like of a company that I would love to work at and/or start.&lt;/p&gt;

&lt;p&gt;Being a developer and contributor to open source software, it seemed clear to me that something like this could benefit immensely from a collaborative and open approach.&lt;/p&gt;

&lt;p&gt;And so, &lt;a href="https://github.com/bjeanes/culture"&gt;here&lt;/a&gt; is the ever-evolving work and distillation of this process.&lt;/p&gt;

&lt;p&gt;I'd love for people to contribute their input in the form of pull requests and discussions. And, where more appropriate, people or companies could fork the still-not-aptly-titled work to form the basis of a different set of values.&lt;/p&gt;

&lt;p&gt;If I were to start a company right now, a living document like this would be available for all employees to see, discuss, dispute, and change.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/begenius/~4/DHvsOkSr72E" height="1" width="1"/&gt;</description>
      <pubDate>Tue, 05 Mar 2013 23:01:14 -0000</pubDate>
      <dc:date>2013-03-05T23:01:14Z</dc:date>
    <feedburner:origLink>http://bjeanes.com/2013/03/a-collaborative-thought-experiment-on-company-environment-values-culture-and-ethos</feedburner:origLink></item>
    <item>
      <title>Critiquing Leadership (Part 1 of N on Leadership)</title>
      <link>http://feedproxy.google.com/~r/begenius/~3/MOeLSmJqaDc/critiquing-leadership-part-1-of-n-on-leadership</link>
      <description>&lt;p&gt;&lt;small&gt;This is part 1 of some unknown number of thoughts and essays on leadership. Your thoughts are welcomed in the comments.&lt;/small&gt;&lt;/p&gt;

&lt;p&gt;If leaders (or managers, as it were) are not constantly soliciting critique from their followers, their harshest critics won’t feel safe being honest or speaking up at all. &lt;/p&gt;

&lt;p&gt;This can create a bubble of false perception, by such leaders, that they are doing well. Instead of hearing the honest criticism (which, of course, still exists), it will spread laterally behind closed doors and manifest in alienation, resentment, and/or apathy. &lt;/p&gt;

&lt;p&gt;This can only perpetuate the problem.&lt;/p&gt;

&lt;p&gt;If you are a leader and you are not being openly critized by those you purport to lead, that is a warning sign. Note that, like all humans everywhere, you are not perfect; a lack of criticism is therefore a sign of something other than your successes. Likely, it’s a sign that you do not have a healthy relationship with your followers (or employees).&lt;/p&gt;

&lt;p&gt;Do not wait for criticism — seek it out. Do not form a bubble of complacency that limits your perception of reality and your ability to handle the inevitable, your loss of followers (or employees).&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/begenius/~4/MOeLSmJqaDc" height="1" width="1"/&gt;</description>
      <pubDate>Mon, 25 Feb 2013 14:46:43 -0000</pubDate>
      <dc:date>2013-02-25T14:46:43Z</dc:date>
    <feedburner:origLink>http://bjeanes.com/2013/02/critiquing-leadership-part-1-of-n-on-leadership</feedburner:origLink></item>
    <item>
      <title>Talk: SSH Can Do That?</title>
      <link>http://feedproxy.google.com/~r/begenius/~3/wOyzBvlerBQ/talk-ssh-can-do-that</link>
      <description>&lt;p&gt;Last night I gave a talk on the darker side of SSH at &lt;a href="www.meetup.com/ChicagoSC/"&gt;ChiSC meetup group&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Here's a video version (better quality one coming soon) for those who are interested:&lt;/p&gt;

&lt;iframe src="http://player.vimeo.com/video/54505525?byline=0&amp;amp;portrait=0&amp;amp;badge=0&amp;amp;color=cc7833" width="500" height="281" frameborder="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen&gt;&lt;/iframe&gt;&lt;img src="http://feeds.feedburner.com/~r/begenius/~4/wOyzBvlerBQ" height="1" width="1"/&gt;</description>
      <pubDate>Thu, 29 Nov 2012 15:23:36 -0000</pubDate>
      <dc:date>2012-11-29T15:23:36Z</dc:date>
    <feedburner:origLink>http://bjeanes.com/2012/11/talk-ssh-can-do-that</feedburner:origLink></item>
    <item>
      <title>Call Clojure function on a timer</title>
      <link>http://feedproxy.google.com/~r/begenius/~3/8L85deOXfeg/call-clojure-function-on-a-timer</link>
      <description>&lt;p&gt;In Clojure, I didn't see a nice way to simply call a function on a timer (e.g. to poll for changes in another service). &lt;/p&gt;

&lt;p&gt;I didn't find something in &lt;code&gt;clojure.core&lt;/code&gt; to achieve this readily (but &lt;code&gt;clojure.core&lt;/code&gt; is quite big, so I may have missed something obvious — let me know), so I whipped up the following to put in my project's &lt;code&gt;util.clj&lt;/code&gt; file:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;defn &lt;/span&gt;&lt;span class="nv"&gt;tick&lt;/span&gt;&lt;/code&gt;
&lt;code&gt;  &lt;span class="s"&gt;&amp;quot;Call f with args every ms. First call will be after ms&amp;quot;&lt;/span&gt;&lt;/code&gt;
&lt;code&gt;  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;ms&lt;/span&gt; &lt;span class="nv"&gt;f&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="nv"&gt;args&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;/code&gt;
&lt;code&gt;&lt;/code&gt;
&lt;code&gt;  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;future&lt;/span&gt;&lt;/code&gt;
&lt;code&gt;    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;doseq &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;f&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;repeatedly&lt;/span&gt; &lt;span class="o"&gt;#&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;apply &lt;/span&gt;&lt;span class="nv"&gt;f&lt;/span&gt; &lt;span class="nv"&gt;args&lt;/span&gt;&lt;span class="p"&gt;))]&lt;/span&gt;&lt;/code&gt;
&lt;code&gt;      &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;Thread/sleep&lt;/span&gt; &lt;span class="nv"&gt;ms&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;/code&gt;
&lt;code&gt;      &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;f&lt;/span&gt;&lt;span class="p"&gt;))))&lt;/span&gt;&lt;/code&gt;
&lt;code&gt;&lt;/code&gt;
&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;defn &lt;/span&gt;&lt;span class="nv"&gt;tick-now&lt;/span&gt;&lt;/code&gt;
&lt;code&gt;  &lt;span class="s"&gt;&amp;quot;Call f with args every ms. First call will be immediately (and blocking)&amp;quot;&lt;/span&gt;&lt;/code&gt;
&lt;code&gt;  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;ms&lt;/span&gt; &lt;span class="nv"&gt;f&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="nv"&gt;args&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;/code&gt;
&lt;code&gt;&lt;/code&gt;
&lt;code&gt;  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;apply &lt;/span&gt;&lt;span class="nv"&gt;f&lt;/span&gt; &lt;span class="nv"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;/code&gt;
&lt;code&gt;  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;apply &lt;/span&gt;&lt;span class="nv"&gt;tick&lt;/span&gt; &lt;span class="nv"&gt;ms&lt;/span&gt; &lt;span class="nv"&gt;f&lt;/span&gt; &lt;span class="nv"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;There are two variants. &lt;code&gt;tick&lt;/code&gt; waits &lt;code&gt;ms&lt;/code&gt; milliseconds and then calls &lt;code&gt;f&lt;/code&gt; with &lt;code&gt;args&lt;/code&gt; and repeats indefinitely. &lt;code&gt;tick-now&lt;/code&gt; does the same thing except it calls &lt;code&gt;f&lt;/code&gt; with &lt;code&gt;args&lt;/code&gt; &lt;em&gt;before&lt;/em&gt; starting the timer.&lt;/p&gt;

&lt;p&gt;They are simple to use:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code&gt;&lt;span class="nv"&gt;user=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;tick&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt; &lt;span class="o"&gt;#&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;println &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;hi&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;/code&gt;
&lt;code&gt;&lt;span class="c1"&gt;; 500ms delay&lt;/span&gt;&lt;/code&gt;
&lt;code&gt;&lt;span class="nv"&gt;hi&lt;/span&gt;&lt;/code&gt;
&lt;code&gt;&lt;span class="c1"&gt;; 500ms delay&lt;/span&gt;&lt;/code&gt;
&lt;code&gt;&lt;span class="nv"&gt;hi&lt;/span&gt;&lt;/code&gt;
&lt;code&gt;&lt;span class="c1"&gt;; 500ms delay&lt;/span&gt;&lt;/code&gt;
&lt;code&gt;&lt;span class="nv"&gt;hi&lt;/span&gt;&lt;/code&gt;
&lt;code&gt;&lt;span class="nv"&gt;...&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;In my project, I'm using them like so:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;defn &lt;/span&gt;&lt;span class="nv"&gt;start-fetchers&lt;/span&gt;&lt;/code&gt;
&lt;code&gt;  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;api-token&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;/code&gt;
&lt;code&gt;&lt;/code&gt;
&lt;code&gt;  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;future&lt;/span&gt;&lt;/code&gt;
&lt;code&gt;    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;let &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;minutes&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;partial * &lt;/span&gt;&lt;span class="mi"&gt;60&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;&lt;/code&gt;
&lt;code&gt;      &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;tick-now&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;minutes&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;/code&gt;
&lt;code&gt;                &lt;span class="nv"&gt;update-project-list!&lt;/span&gt;&lt;/code&gt;
&lt;code&gt;                &lt;span class="nv"&gt;api-token&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;/code&gt;
&lt;code&gt;&lt;/code&gt;
&lt;code&gt;      &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;tick-now&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;minutes&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;/code&gt;
&lt;code&gt;                &lt;span class="nv"&gt;fetch-milestones!&lt;/span&gt;&lt;/code&gt;
&lt;code&gt;                &lt;span class="nv"&gt;api-token&lt;/span&gt;&lt;/code&gt;
&lt;code&gt;                &lt;span class="nv"&gt;projects-to-fetch&lt;/span&gt;&lt;/code&gt;
&lt;code&gt;                &lt;span class="nv"&gt;milestones-by-project&lt;/span&gt;&lt;span class="p"&gt;))))&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/begenius/~4/8L85deOXfeg" height="1" width="1"/&gt;</description>
      <pubDate>Thu, 20 Sep 2012 16:07:00 -0000</pubDate>
      <dc:date>2012-09-20T16:07:00Z</dc:date>
    <feedburner:origLink>http://bjeanes.com/2012/09/call-clojure-function-on-a-timer</feedburner:origLink></item>
    <item>
      <title>Pure Evil</title>
      <link>http://feedproxy.google.com/~r/begenius/~3/aF5kykp-A38/pure-evil</link>
      <description>&lt;p&gt;I love Vim. I take that back — I love &lt;strong&gt;modal editing&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;Actually, I think very few people like &lt;em&gt;Vim&lt;/em&gt;, it just happens to be the best kid on the block at modal editing. But, after using Vim (and, God, does it take a while to learn to &lt;em&gt;use&lt;/em&gt; it), you are reduced to a &lt;q&gt;&lt;a href="http://haldean.org/docstore/?vim-problems"&gt;pathetic teary wreck every time [you] have to use a text editor that isn't vim&lt;/a&gt;&lt;/q&gt;.&lt;/p&gt;

&lt;p&gt;And why &lt;em&gt;is&lt;/em&gt; it so debilitating to use something other than Vim for those who have honed their modal editing skills? Frankly, magic sauce of Vim is (mostly) made up from a few quite simple ingredients: motions, text objects, operators. There are plenty of cool tricks hidden inside Vim, but those three main things are the things you really miss, consistently, when using something else.&lt;/p&gt;

&lt;p&gt;Every now and then, when forced outside of the comforting (yet somehow cold) embrace of Vim, the Vimmer flirts with Sublime Text 2’s &lt;a href="http://www.sublimetext.com/docs/2/vintage.html"&gt;vintage mode&lt;/a&gt; or &lt;a href="http://plugins.intellij.net/plugin/?id=164"&gt;IdeaVIM&lt;/a&gt;. We may even be impressed — but, eventually, something falls apart and the abstraction leaks.&lt;/p&gt;

&lt;p&gt;Usually, this failure happens because the Vi(m) emulation layer often doesn’t implement motions, text objects, and operators. They just implement some keystrokes that appear to do the same thing in the same way — until you try something the developer didn’t preempt.&lt;/p&gt;

&lt;p&gt;If I could have an editor that did these things &lt;em&gt;properly&lt;/em&gt;, I would have no real attachment to Vim. I have other things about Vim that I love and would hate to lose but they aren’t unique and other editors (can) have them, too.&lt;/p&gt;

&lt;p&gt;Luckily for me, I’ve been doing too much Clojure to ignore Emacs forever and 2 weeks ago, I switched. Here's how it played out:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Nope — not for me... But, wait! Let us try this &lt;a href="http://emacswiki.org/emacs/Evil"&gt;Evil Mode&lt;/a&gt; so we can mock their pitiful attempt at modal editing (*evil laugh here*).  What’s this‽ It’s actually good!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Inner dialogs aside, I’m not kidding; Evil Mode is stunning. It doesn’t have &lt;em&gt;everything&lt;/em&gt; — but everything that it does have is built up using the same &lt;strike&gt;functions&lt;/strike&gt; macros that you can use to extend it. Those are: &lt;code&gt;(evil-define-state)&lt;/code&gt; (“mode” is an existing term in Emacs so what Vim calls modes, Evil Mode calls “states”), &lt;code&gt;(evil-define-motion)&lt;/code&gt;, &lt;code&gt;(evil-define-operator)&lt;/code&gt;, &lt;code&gt;(evil-define-text-object)&lt;/code&gt;, and a &lt;a href="https://gitorious.org/evil/evil/blobs/raw/doc/doc/evil.pdf"&gt;few others&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Evil Mode correctly implements the plumbing to wire these things together so that the Vim “language” which becomes natural and reflexive (e.g. &lt;code&gt;di”&lt;/code&gt; -&amp;gt; “&lt;strong&gt;d&lt;/strong&gt;elete &lt;strong&gt;i&lt;/strong&gt;nside double quotes”, &lt;code&gt;vt&lt;/code&gt; -&amp;gt; “&lt;strong&gt;v&lt;/strong&gt;isually select &lt;strong&gt;t&lt;/strong&gt;ill space`) is completely preserved. If you wanted to define a new text object (e.g. a Ruby block), it is trivial to do so and all of the motions and operators will work flawlessly with it immediately. Frankly, it’s not even that nice in Vim.&lt;/p&gt;

&lt;p&gt;At the end of the day, I’ve always hated things like VimScript and Vim’s single-threadedness but I could never walk away from a truly powerful (and mostly extensible) modal editing system. Now, that has changed; I get ELisp (which, for all its faults, is exponentially better than VimScript), a saner package system, and a level of extensibility that, by design, can never be matched by Vim. All that and I don’t have to give up modal editing? Hell yes!&lt;/p&gt;

&lt;p&gt;Bonus points: one of the “states” that Evil implements is an Emacs state; this leaves Emacs and all it’s default behavior and keymappings 100% intact, meaning you can pair fearlessly with Emacsen, or slowly learn more about the Emacs way of doing things, if desirable.&lt;/p&gt;

&lt;p&gt;So far, I’ve rarely noticed I’m not in Vim and am constantly surprised when I employ Vim reflexes in Emacs and they work &lt;em&gt;exactly&lt;/em&gt; as expected or better (seriously, try &lt;code&gt;:%s/foo/bar/g&lt;/code&gt; in Evil mode and tell me you don’t squeal with joy).&lt;/p&gt;

&lt;p&gt;I refuse to pick a single side, so I’m picking both. I’m going to edit modally in Emacs and I’m going to be happy doing it! I don’t care if I simultaneously piss off Vim users and Emacs users — hell, they need more things in common anyway...&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/begenius/~4/aF5kykp-A38" height="1" width="1"/&gt;</description>
      <pubDate>Fri, 07 Sep 2012 04:31:19 -0000</pubDate>
      <dc:date>2012-09-07T04:31:19Z</dc:date>
    <feedburner:origLink>http://bjeanes.com/2012/09/pure-evil</feedburner:origLink></item>
    <item>
      <title>Happier as a Hacker</title>
      <link>http://feedproxy.google.com/~r/begenius/~3/6-5-zVGnKZk/happier-as-a-hacker</link>
      <description>&lt;p&gt;I’ve grown a lot in the last few years, personally and, specifically, in my career. My values have changed and it’s affected the way I think and work.&lt;/p&gt;

&lt;p&gt;There has been a gradual progression towards caring more and more about the Right Way™ to do things. For example, more than ever before, I value simplicity and clarity over ease and cleverness (an epidemic that greatly afflicts the Ruby community, in my opinion).&lt;/p&gt;

&lt;p&gt;But, these values have come at a cost to me. Somewhere along the way, I complacently let &lt;em&gt;getting it right&lt;/em&gt; become far more important than &lt;em&gt;getting it done&lt;/em&gt;.” Don’t get me wrong, getting things right is very important — where I went wrong was valuing getting it right the &lt;strong&gt;first&lt;/strong&gt; time. &lt;/p&gt;

&lt;p&gt;It may not plague others to the extent that it has me, but this misplaced obsession has gotten in the way of progress. It’s caused a type of analysis paralysis not unlike writers’ block; I discard ideas and directions too early because they aren’t “good enough.” But exploring a potentially bad direction is still being better than having no direction — which is the only place you end up when you discard ideas before they have a chance to blossom.&lt;/p&gt;

&lt;p&gt;In the eternal words of &lt;a href="http://en.wikipedia.org/wiki/Into_the_Woods"&gt;Little Red Ridinghood&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Isn't it nice to know a lot?&lt;br/&gt;
And a little bit not.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I was happier as a hacker, blissfully ignorant as I was, because I got things done. &lt;/p&gt;

&lt;p&gt;It’s time to become a hacker again; it’s time to be creative and explorative, and work towards &lt;em&gt;approximating&lt;/em&gt; the Right Way™, iteratively. Truly, this is one of the great realizations of Agile — focus on progress instead of planning and pre-empting every possible outcome.&lt;/p&gt;

&lt;p&gt;I can’t forget that.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/begenius/~4/6-5-zVGnKZk" height="1" width="1"/&gt;</description>
      <pubDate>Thu, 06 Sep 2012 00:22:42 -0000</pubDate>
      <dc:date>2012-09-06T00:22:42Z</dc:date>
    <feedburner:origLink>http://bjeanes.com/2012/09/happier-as-a-hacker</feedburner:origLink></item>
    <item>
      <title>Motivate your lazy sequences</title>
      <link>http://feedproxy.google.com/~r/begenius/~3/LqTQ_HV8gWU/motivate-your-lazy-sequences</link>
      <description>&lt;p&gt;I &lt;em&gt;love&lt;/em&gt; Clojure’s laziness.&lt;/p&gt;

&lt;p&gt;Recently, I’ve been using &lt;code&gt;lazy-seq&lt;/code&gt;  to consume remote collections via APIs, fetching pages of data transparently and only as needed. &lt;a href="http://gfredericks.com/"&gt;Gary Fredericks&lt;/a&gt;, &lt;a href="http://mikelikesbikes.com/"&gt;Mike Busch&lt;/a&gt;, and I applied this to a project of ours that had to crunch tens of thousands of records from Salesforce. I’m also doing something similar with a personal project that has to fetch a lot of Pivotal Tracker stories to &lt;code&gt;reduce&lt;/code&gt; them.&lt;/p&gt;

&lt;p&gt;In cases like these, consuming (potentially unbounded) resources in a lazy manner allows one to start processing data earlier and to make as few requests as possible to get only the data you need.&lt;/p&gt;

&lt;h2&gt;&lt;em&gt;Mostly&lt;/em&gt; Lazy&lt;/h2&gt;

&lt;p&gt;I want to talk about a neat little thing I did in my project to get a nice little performance boost on top of this laziness, without having to think about any low-level concurrency concerns.&lt;/p&gt;

&lt;h3&gt;Laziness&lt;/h3&gt;

&lt;p&gt;Here’s a piece of code that provides an “infinite” lazy sequence. In this case, it is of tweets:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;require&lt;/span&gt; &lt;span class="o"&gt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;clj-http.client&lt;/span&gt; &lt;span class="ss"&gt;:as&lt;/span&gt; &lt;span class="nv"&gt;http&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;&lt;/code&gt;
&lt;code&gt;&lt;/code&gt;
&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;defn &lt;/span&gt;&lt;span class="nv"&gt;tweets-for&lt;/span&gt;&lt;/code&gt;
&lt;code&gt;  &lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nv"&gt;user&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;tweets-for&lt;/span&gt; &lt;span class="nv"&gt;user&lt;/span&gt; &lt;span class="nv"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;/code&gt;
&lt;code&gt;  &lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nv"&gt;user&lt;/span&gt; &lt;span class="nv"&gt;last-tweet-id&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;/code&gt;
&lt;code&gt;     &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;lazy-seq&lt;/span&gt;&lt;/code&gt;
&lt;code&gt;      &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;let &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;url&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;http://api.twitter.com/1/statuses/user_timeline.json&amp;quot;&lt;/span&gt;&lt;/code&gt;
&lt;code&gt;            &lt;span class="nv"&gt;params&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:limit&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="ss"&gt;:screen_name&lt;/span&gt; &lt;span class="nv"&gt;user&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/code&gt;
&lt;code&gt;            &lt;span class="nv"&gt;params&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="nv"&gt;last-tweet-id&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;assoc &lt;/span&gt;&lt;span class="nv"&gt;params&lt;/span&gt; &lt;span class="ss"&gt;:max_id&lt;/span&gt; &lt;span class="nv"&gt;last-tweet-id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;params&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;/code&gt;
&lt;code&gt;            &lt;span class="nv"&gt;response&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;http/get&lt;/span&gt; &lt;span class="nv"&gt;url&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:query-params&lt;/span&gt; &lt;span class="nv"&gt;params&lt;/span&gt; &lt;span class="ss"&gt;:as&lt;/span&gt; &lt;span class="ss"&gt;:json&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;&lt;/code&gt;
&lt;code&gt;            &lt;span class="nv"&gt;tweets&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:body&lt;/span&gt; &lt;span class="nv"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;&lt;/code&gt;
&lt;code&gt;&lt;/code&gt;
&lt;code&gt;        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;when &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;not-empty&lt;/span&gt; &lt;span class="nv"&gt;tweets&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;/code&gt;
&lt;code&gt;          &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;concat &lt;/span&gt;&lt;span class="nv"&gt;tweets&lt;/span&gt; &lt;/code&gt;
&lt;code&gt;                  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;tweets-for&lt;/span&gt; &lt;span class="nv"&gt;user&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:id&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;last &lt;/span&gt;&lt;span class="nv"&gt;tweets&lt;/span&gt;&lt;span class="p"&gt;)))))))))&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;So that’s cool. Now, note the following performance characteristics when contemplating the next section:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;def &lt;/span&gt;&lt;span class="nv"&gt;my-tweets&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;tweets-for&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;bjeanes&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;/code&gt;
&lt;code&gt;&lt;/code&gt;
&lt;code&gt;&lt;span class="c1"&gt;;; The following returns after a delay while we fetch the first page:&lt;/span&gt;&lt;/code&gt;
&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;first &lt;/span&gt;&lt;span class="nv"&gt;my-tweets&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;;=&amp;gt; {:text &amp;quot;Tweet 0&amp;quot; ...}&lt;/span&gt;&lt;/code&gt;
&lt;code&gt;&lt;/code&gt;
&lt;code&gt;&lt;span class="c1"&gt;;; This returns instantly because our `tweets-for` function fetches 10 tweets per page:&lt;/span&gt;&lt;/code&gt;
&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;nth &lt;/span&gt;&lt;span class="nv"&gt;my-tweets&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;;=&amp;gt; {:text &amp;quot;Tweet 9&amp;quot; ...}&lt;/span&gt;&lt;/code&gt;
&lt;code&gt;&lt;/code&gt;
&lt;code&gt;&lt;span class="c1"&gt;;; This returns after a delay because this tweet is on the next (still lazily unfetched) page:&lt;/span&gt;&lt;/code&gt;
&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;nth &lt;/span&gt;&lt;span class="nv"&gt;my-tweets&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;;=&amp;gt; {:text &amp;quot;Tweet 10&amp;quot; ...}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;Motivation&lt;/h3&gt;

&lt;p&gt;So laziness is pretty cool. But, sometimes, things can improve if you are ever so slightly less lazy. What if we could remove that little pause between the 9th and the 10th items in the list where we are just waiting around for the network request to Twitter to complete? We could be using our time to do more CPU-melting tweet crunching! Well, it turns out we can easily do it.&lt;/p&gt;

&lt;p&gt;Assume for a moment that we have some calculation (&lt;code&gt;process&lt;/code&gt;) that takes a considerable amount of CPU time to process:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;defn &lt;/span&gt;&lt;span class="nv"&gt;process&lt;/span&gt;&lt;/code&gt;
&lt;code&gt;  &lt;span class="s"&gt;&amp;quot;Do some really hard work with our tweets&amp;quot;&lt;/span&gt;&lt;/code&gt;
&lt;code&gt;  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;tweets&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;/code&gt;
&lt;code&gt;  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;map &lt;/span&gt;&lt;span class="o"&gt;#&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;Thread/sleep&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;tweets&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If we know we will be consuming a substantial amount of the lazy sequence, we could encourage the sequence to go ahead and start realizing the next chunk of our sequence. &lt;/p&gt;

&lt;p&gt;This would mean that instead of processing 10 tweets, waiting, processing 10 tweets, waiting, etc.:&lt;/p&gt;

&lt;p&gt;&lt;img src="/lazy.png" alt="lazy"/&gt;&lt;/p&gt;

&lt;p&gt;... we would be able to process tweets continuously back-to-back:&lt;/p&gt;

&lt;p&gt;&lt;img src="/motivated.png" alt="motivated"/&gt;&lt;/p&gt;

&lt;p&gt;Wouldn't also be great if we didn't have to think about the parallelism at all? To this end, I present &lt;code&gt;motivate&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;defn &lt;/span&gt;&lt;span class="nv"&gt;motivate&lt;/span&gt;&lt;/code&gt;
&lt;code&gt;  &lt;span class="s"&gt;&amp;quot;Motivate a lazy sequence to seek slightly ahead of the sequence consumer&amp;#39;s position.&amp;quot;&lt;/span&gt;&lt;/code&gt;
&lt;code&gt;  &lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nv"&gt;coll&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;motivate&lt;/span&gt; &lt;span class="nv"&gt;coll&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;/code&gt;
&lt;code&gt;  &lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nv"&gt;coll&lt;/span&gt; &lt;span class="nv"&gt;motivation&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;/code&gt;
&lt;code&gt;     &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;lazy-seq&lt;/span&gt;&lt;/code&gt;
&lt;code&gt;      &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;future&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;nth &lt;/span&gt;&lt;span class="nv"&gt;coll&lt;/span&gt; &lt;span class="nv"&gt;motivation&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;/code&gt;
&lt;code&gt;      &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;cons &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;first &lt;/span&gt;&lt;span class="nv"&gt;coll&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;motivate&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;rest &lt;/span&gt;&lt;span class="nv"&gt;coll&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;motivation&lt;/span&gt;&lt;span class="p"&gt;)))))&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Let’s compare:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;time &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;process&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;take &lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;tweets-for&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;riblah&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;))))&lt;/span&gt;&lt;/code&gt;
&lt;code&gt;&lt;span class="c1"&gt;;=&amp;gt; “Elapsed time: 11545.011 msecs&amp;quot;&lt;/span&gt;&lt;/code&gt;
&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;time &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;process&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;take &lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;motivate&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;tweets-for&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;riblah&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;))))&lt;/span&gt;&lt;/code&gt;
&lt;code&gt;&lt;span class="c1"&gt;;=&amp;gt; &amp;quot;Elapsed time: 10394.769 msecs&amp;quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The speed difference is noticeable even when processing only a 100 tweets. If we were doing more than 100 milliseconds/tweet of processing, fetching a lot more data, or dealing with a slow upstream dependency, the speed improvements would be even clearer.&lt;/p&gt;

&lt;p&gt;The last (optional) parameter to &lt;code&gt;motivate&lt;/code&gt; is the “motivation factor”. If your CPU-bound work is long-running, this number can be smaller without a noticeable difference. The ideal number depends on how long each IO operation takes and much processing you do with each chunk. &lt;/p&gt;

&lt;p&gt;Essentially, the motivation you give to the lazy sequence is a trade-off between waiting for IO and wasting IO; that is, the lower the number, the more likely you are to wait on IO but the higher the number, the more IO you’ll perform unnecessarily (at least, if you aren’t guaranteed to consume the whole sequence.&lt;/p&gt;

&lt;p&gt;Hopefully this is handy to someone else out there. I wouldn’t at all be surprised if something like this already existed (&lt;strong&gt;UPDATE&lt;/strong&gt; Yup: &lt;a href="http://clojuredocs.org/clojure_core/clojure.core/seque"&gt;&lt;code&gt;seque&lt;/code&gt;&lt;/a&gt;) or if this completely obvious to seasoned Clojurian, but it was a pleasant moment discovering this possibility on my own.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/begenius/~4/LqTQ_HV8gWU" height="1" width="1"/&gt;</description>
      <pubDate>Mon, 03 Sep 2012 18:00:53 -0000</pubDate>
      <dc:date>2012-09-03T18:00:53Z</dc:date>
    <feedburner:origLink>http://bjeanes.com/2012/09/motivate-your-lazy-sequences</feedburner:origLink></item>
    <item>
      <title>Factories breed complexity</title>
      <link>http://feedproxy.google.com/~r/begenius/~3/8B-yNef2r3o/factories-breed-complexity</link>
      <description>&lt;p&gt;Having maintainable code is great. Maintainable code allows you to deliver improvements faster, happier, and more reliably. &lt;/p&gt;

&lt;p&gt;Furthermore, the measures that developers need to take and the strategies that we have to employ to achieve maintainable code have been understood for years, if not decades. Especially in the realm of object-oriented programming, but certainly not exclusively, most of these principles boil down to reducing coupling and system complexity. A system whose parts are coupled as loosely as possible is a modular system; the parts know little of each other and a lot about themselves and they have thin and specific interfaces between each other.&lt;/p&gt;

&lt;p&gt;Test-driven development is one of the many tools at a developer's disposal to achieve code quality. Unfortunately, there is a lot of naïveté around the benefits of TDD. A lot of developers see TDD as primarily a tool for verifying system correctness. While TDD does of course offer this benefit, and arguably better than retroactive automated testing, the real benefit of TDD is that it offers short feedback loops that guide the design/architecture of the system.&lt;/p&gt;

&lt;p&gt;Since it is accepted that a loosely-coupled modular system is a simpler system, it stands that tools, such as TDD, which guide a design towards modularity and simplicity are good tools. A module that is tightly coupled to another is not easily tested in isolation. However, if the isolated tests are written first, it is difficult to write a passing implementation for that module that maintains such a low degree of coupling. Therefore, good TDD should guide you towards a simpler design (though it is certainly not the only way).&lt;/p&gt;

&lt;p&gt;Unfortunately, factories work against this goal. Factories debilitate TDD's ability to give you feedback into the complexity of your design.&lt;/p&gt;

&lt;p&gt;To be clear, I am not talking about the &lt;a href="http://en.wikipedia.org/wiki/Factory_method_pattern"&gt;Factory Method Pattern&lt;/a&gt;
or the &lt;a href="http://en.wikipedia.org/wiki/Abstract_factory_pattern"&gt;Abstract Factory Pattern&lt;/a&gt; — both of which can be described
as ways to &lt;q src="http://en.wikipedia.org/wiki/Object_creation#Creating_objects"&gt;decouple a particular implementation
of an object from code for the creation of such an object&lt;/q&gt; (&lt;cite&gt;&lt;a href="http://en.wikipedia.org/wiki/Object_creation#Creating_objects"&gt;Wikipedia&lt;/a&gt;&lt;/cite&gt;). Instead, I am talking about the &amp;quot;factories&amp;quot; for replacing fixtures in tests — something which has seemingly obsessed the Ruby (Rails, especially) community. The two primary Ruby libraries for factory-based fixture replacement are &lt;a href="https://github.com/thoughtbot/factory_girl"&gt;factory_girl&lt;/a&gt; and &lt;a href="https://github.com/notahat/machinist"&gt;Machinist&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;A tool such as Machinist or factory_girl &lt;q&gt;generates data for the attributes you don't care about, and constructs any necessary associated objects, leaving you to specify only the fields you care about in your test&lt;/q&gt; (from Machinist's own &lt;a href="https://github.com/notahat/machinist/blob/master/README.markdown"&gt;README file&lt;/a&gt;). This sounds nice at first, because it makes your tests more readable and relevant. However, behind the scenes, these tools are still creating other objects and entities and introducing them into your test environment. By having data and objects in tests that are irrelevant to the functionality that is being tested (in &lt;em&gt;isolation&lt;/em&gt;, remember), a developer creates an environment that permits, if not invites, silent dependencies to creep into an implementation.&lt;/p&gt;

&lt;p&gt;Furthermore, and perhaps more significantly, by creating objects (and usually entire &lt;em&gt;hierarchies&lt;/em&gt; of objects) with such ease and opacity, you are outright masking the dependencies (*cough* complexity *cough* coupling) between your implementation and those entities. If forced to stub out all those intricacies, the system complexity would be screamingly obvious and a developer would quickly avail herself of a rewrite to reduce complexity or thin out the interface. &lt;/p&gt;

&lt;p&gt;Instead of having feedback that guides a developer to simplicity, fixture factories seem to guide developers to complexity by masking dependencies as one-line simplicity. In fact, that one (or five, whatever) line setup is a shotgun blast of environmental dependencies that are hidden from the architect. That complexity will come back for revenge after being ignored for so long.&lt;/p&gt;

&lt;p&gt;It seems that factory_girl and Machinist exist to make testing components more convenient. This is, at face value, an admirable and desirable goal. However, in unit tests, the cost is too high for any system of considerable size. &lt;/p&gt;

&lt;p&gt;Please, do the right thing and avoid the convenience and &amp;quot;fun&amp;quot; of the factory_girl temptress. You will trend towards a simpler system and as a bonus (in fact, an incredible one) your test suite will likely be exponentially faster which, in turn, will breed simplicity by letting you have more feedback more often.&lt;/p&gt;

&lt;p&gt;P.S. It shouldn't go without mention that factories can be absolutely awesome for integration tests. Integration tests aren't used for guiding system design nor testing in isolation so the drawbacks of these tools drop away. However, both factory_girl and Machinist use RSpec as some of their very first usage examples and this troubles me deeply.&lt;/p&gt;

&lt;p&gt;P.P.S. A lot of these arguments can be applied to fixtures too. However, they usually don't create hordes of objects invisibly and litter your environment with them. Also, they aren't as slow. But yes, the fewer factories &lt;em&gt;and&lt;/em&gt; fixtures in a test, the better.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Update for clarity&lt;/strong&gt;: Firstly, I am absolutely just talking about unit tests. If you are testing code that &lt;em&gt;integrates&lt;/em&gt; with ActiveRecord or number of levels of your stack, then factories and fixtures are certainly defensible (though I still prefer to steer clear). Secondly, I've tried to be careful about where I use the words simple, easy, complex, and difficult. For the definitions that I intend, please watch (at least the first 10 minutes of) &lt;a href="http://www.infoq.com/presentations/Simple-Made-Easy"&gt;Simple Made Easy&lt;/a&gt;. &lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/begenius/~4/8B-yNef2r3o" height="1" width="1"/&gt;</description>
      <pubDate>Sun, 26 Feb 2012 19:22:56 -0000</pubDate>
      <dc:date>2012-02-26T19:22:56Z</dc:date>
    <feedburner:origLink>http://bjeanes.com/2012/02/factories-breed-complexity</feedburner:origLink></item>
    <item>
      <title>New design</title>
      <link>http://feedproxy.google.com/~r/begenius/~3/scH3_3E6HFQ/new-design</link>
      <description>&lt;p&gt;Just a quick post to point out the new design for this blog. It's nothing special — I just needed a change.&lt;/p&gt;

&lt;p&gt;Hopefully, the change of aesthetics will motivate me to get back into blogging.&lt;/p&gt;

&lt;p&gt;Let me know if there is any weird display issues on your browser. I only tested the latest versions of non-IE browsers, but if there are any stupid obvious fixes to any browser, I'll implement them.&lt;/p&gt;

&lt;p&gt;Tell me what you think, keeping in mind I'm a developer not a designer :P.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/begenius/~4/scH3_3E6HFQ" height="1" width="1"/&gt;</description>
      <pubDate>Wed, 07 Dec 2011 05:56:59 -0000</pubDate>
      <dc:date>2011-12-07T05:56:59Z</dc:date>
    <feedburner:origLink>http://bjeanes.com/2011/12/new-design</feedburner:origLink></item>
  </channel>
</rss>
