<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <id>drunkencoder.net</id>
  <title>Drunken Coder</title>
  <updated>2012-05-04T00:00:00+00:00</updated>
  <link rel="self" href="http://drunkencoder.net/feed.xml"/>
  <link rel="alternate" href="http://drunkencoder.net"/>
  <author>
    <name>Isaac</name>
  </author>
  <entry>
    <title>Just fucking say it</title>
    <id>drunkencoder.net,/if_you_want_to_curse_curse</id>
    <updated>2012-05-04T00:00:00+00:00</updated>
    <link href="http://drunkencoder.net//if_you_want_to_curse_curse"/>
    <content type="html">&lt;p&gt;&lt;a href="http://www.smbc-comics.com/index.php?db=comics&amp;amp;id=1446#comic"&gt;&lt;img src="/content/smbc.gif" alt="Haha, she hates dashes!"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I hate the term &amp;quot;pet peeve&amp;quot;, but that doesn&amp;#39;t stop me from having them in spades. Most of them are just geeky annoyances: if you use various programming phrases imprecisely, I will lecture you. At length. Obnoxiously, even, and probably only for the benefit of my own ego. If you act obliviously to the concept of sunk cost, I will put you into the Stupid Until Proven Otherwise bucket. I&amp;#39;m a judgmental prick like that. Maybe you&amp;#39;re pathologically incapable of being honest when I ask you a direct question. I will roll my eyes and talk about something else, forever incurious about your future opinions. So a lot of things bug me. But this post isn&amp;#39;t about the stuff that just bugs me; this post is about the one thing that boils my blood, that sends me into hysterical fits of primordial rage, the ice pick in my brain that keeps me up at night. Especially when I&amp;#39;m drunk, which, right now, I am. I will try to remain calm while writing this.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If you want to curse, curse. If you don&amp;#39;t, don&amp;#39;t.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;An example&lt;/h2&gt;

&lt;p&gt;This might require an example. So here you are, on Facebook, writing a post about your awesome job. Or Twitter or Tumbler or Gmail (this anger of mine is medium-independent). You want to say something strongly worded, something to express on no uncertain terms how great your day at work was. So far, so good. I love my job too; no shame in sharing on the internet. But then, in your excitement, you type out, &amp;quot;My job is the sh*t!&amp;quot;. You hit enter. Everyone can see it now: your job is the sh*it.&lt;/p&gt;

&lt;p&gt;If there were such a thing as baby angels, you would have just killed six-hundred and twenty of them.&lt;/p&gt;

&lt;p&gt;&amp;quot;Shit&amp;quot; has an &amp;quot;i&amp;quot; in it. I&amp;#39;m pretty sure. Now, I&amp;#39;m not a great speller either, and one of the weapons &lt;strong&gt;not&lt;/strong&gt; regularly stocked in my arsenal of petty neuroses is anger about spelling. But you knew that &amp;quot;shit&amp;quot; doesn&amp;#39;t have any asterisks in it, didn&amp;#39;t you? And you wrote it anyway. On purpose. Why did you do that? WHY DID YOU DO THAT?&lt;/p&gt;

&lt;p&gt;I honestly, seriously, in all earnestness, do not understand. You misspelled a word with four letters in it.&lt;/p&gt;

&lt;p&gt;&lt;img src="/content/facebook.png" alt="Need to start rationing exclamation marks"&gt;&lt;/p&gt;

&lt;p&gt;You said the curse word. You wrote it to express the word and you successfully communicated that word to your audience, along with any associated meaning and connotation. So why the game of replace-the-letter?&lt;/p&gt;

&lt;h2&gt;It&amp;#39;s everywhere&lt;/h2&gt;

&lt;p&gt;Once something like this bugs you, you see it everywhere. It&amp;#39;s in &lt;a href="http://gizmodo.com/5846087/stop-already-with-the-fcking-infographics"&gt;articles&lt;/a&gt;. It&amp;#39;s in &lt;a href="http://www.bugcomic.com/comics/crappin-on-cartwheels/"&gt;web comics&lt;/a&gt; (Jesus, you self-censor your own web comic? Why do you even have one?). &lt;a href="http://www.amazon.com/Sh-t-My-Dad-Says/dp/0061992704"&gt;Book titles&lt;/a&gt;. &lt;a href="http://www.amazon.com/Greatest-Tits-Lords-Acid/dp/B0000C0F8Q"&gt;Album covers&lt;/a&gt;. Magazines (Newsweek used to kill me with this, but it has apparently &lt;a href="http://www.theatlanticwire.com/entertainment/2012/02/spy-already-covered-tina-browns-love-profanity/48633/"&gt;stopped&lt;/a&gt;). It&amp;#39;s in emails from your coworkers.&lt;/p&gt;

&lt;p&gt;Since there doesn&amp;#39;t seem to be an appropriately &lt;a href="http://english.stackexchange.com/questions/15036/what-name-for-bowdlerisation-with-asterisks-e-g-fck"&gt;specific word for this&lt;/a&gt;, I&amp;#39;ve decided to call it cursfuscation. It&amp;#39;s a subspecies of bowdlerization. And it&amp;#39;s one of the most irritating things on Earth.&lt;/p&gt;

&lt;p&gt;It bothers me because it&amp;#39;s utterly pointless; it detracts from the readability without changing the content. Sure, you can read it, but you can also read th*s and it&amp;#39;s still annoying. And no one has a cogent explanation for why they do it. Part of some shared fiction about properness? Just a thoughtless habit? An honest fear of the literal letters in curse words?&lt;/p&gt;

&lt;p&gt;If &amp;quot;LOL&amp;quot; is the nervous tick of the internet, then cursfuscation is its stutter.&lt;/p&gt;

&lt;h2&gt;Don&amp;#39;t pretend you&amp;#39;re not cursing&lt;/h2&gt;

&lt;p&gt;Maybe you don&amp;#39;t like cursing. You think it&amp;#39;s crass or just wrong. We differ in this respect, but fine, you think there are certain combinations of consonants and vowels which are off-limits to polite human communication. I sort of get where you&amp;#39;re coming from, actually, and there are a few words I don&amp;#39;t make a habit of saying. But you know what? I respond to my qualms about those words by not saying them. For example, I don&amp;#39;t use the word &amp;quot;nigger&amp;quot; because I think it&amp;#39;s shitty word that expresses a bunch of stuff I don&amp;#39;t want to express. But, by trivial extension, I also don&amp;#39;t write &amp;quot;n*gger&amp;quot; or &amp;quot;n----r&amp;quot; or say &amp;quot;nignog&amp;quot; and pretend I&amp;#39;m in the clear, because &lt;em&gt;it&amp;#39;s the same word&lt;/em&gt;. If the word is so bad, then why are you saying it? Do you really think that the morally reprehensible part of the word is the little vertical line with a dot above it? How has your &lt;code&gt;s&amp;#47;i&amp;#47;\*&lt;/code&gt; avoided whatever culpability you feel for having used the word, in all of its actually-spelled-correctly glory? What&amp;#39;s offensive about &amp;quot;shit&amp;quot; that isn&amp;#39;t offensive about &amp;quot;sh*t&amp;quot;?&lt;/p&gt;

&lt;p&gt;My dad doesn&amp;#39;t curse, ever, out of a strong ethical commitment of some kind. I don&amp;#39;t understand it, but I give him props for &lt;em&gt;not actually cursing&lt;/em&gt;. He doesn&amp;#39;t say &amp;quot;freakin&amp;quot; or &amp;quot;effin&amp;quot; or &amp;quot;f&amp;amp;#!ing&amp;quot; or--pretending for a moment that he watches TV other than &lt;em&gt;Law and Order&lt;/em&gt;--&amp;quot;fraking&amp;quot;. He doesn&amp;#39;t pretend that the letters F-U-C-K form some kind of hyper-specific satanic incantation, the apocalyptic consequences of which can only be avoided by not saying the exact right combination of sounds involved, but which it&amp;#39;s perfectly reasonable to express the substance of whenever you feel like. He just doesn&amp;#39;t say &amp;quot;fuck&amp;quot; because he thinks it&amp;#39;s wrong to say &amp;quot;fuck&amp;quot;. Not complicated.&lt;/p&gt;

&lt;h2&gt;Who are you fooling?&lt;/h2&gt;

&lt;p&gt;Or maybe you&amp;#39;re OK with cursing, but only in certain contexts, like hanging out with your friends. Maybe you&amp;#39;re writing an email to a coworker and you want to be professional and serious. Professional, serious people, you think, speak only in the set of English words minus this particular seven. Maybe innocent children or prudish grandmas will read your writing, and they will be corrupted or offended by the raw power of your words. Fine, I get there are boundaries, sensibilities you don&amp;#39;t want to offend. Mores. &lt;/p&gt;

&lt;p&gt;But who are you fooling? You think those bosses, children, and octogenarians will have &lt;em&gt;no idea&lt;/em&gt; what you mean by &amp;quot;b*tch&amp;quot; and couldn&amp;#39;t possibly figure it out? They&amp;#39;ll think it says &amp;quot;botch&amp;quot;, right? Right?&lt;/p&gt;

&lt;p&gt;You&amp;#39;ve only succeeded in insulting their intelligences. It&amp;#39;s not even censorship, really; it&amp;#39;s just minor obfuscation.&lt;/p&gt;

&lt;p&gt;But in fact, it&amp;#39;s even worse than that: the asterisk doesn&amp;#39;t even work if the reader doesn&amp;#39;t know what it means. The whole point of saying something is to communicate that something to the listener, and the only thing distorting your words can accomplish is to sabotage that goal. That&amp;#39;s why you made sure it was easy for everyone to understand by using a known cursifiscation convention. You wanted to make sure that everyone knew the word was &amp;quot;bitch&amp;quot; without, you seem to think, the word actually being &amp;quot;bitch&amp;quot;. You wanted to obfuscate your communication in name only, a sort of half-hearted nod and wink in the form of awkward reading. Who benefits?&lt;/p&gt;

&lt;p&gt;You said &amp;quot;bitch&amp;quot;; come to terms with that or stop saying it altogether. The middle road is wholly imagined.&lt;/p&gt;

&lt;h2&gt;Some kind of disconnect&lt;/h2&gt;

&lt;p&gt;&lt;img src="/content/on_bullshit.jpg" alt="Much better"&gt;&lt;/p&gt;

&lt;p&gt;Much better, right?&lt;/p&gt;

&lt;p&gt;As I understand it, cursfuscation started as a tacky way to circumvent obscenity laws, just like beeping on TV. In other words, the convention came about to make cursing in newspapers &lt;em&gt;easier&lt;/em&gt;. Those newspapers that used &amp;quot;f------&amp;quot; could have just &lt;a href="http://www.nytimes.com/2008/07/13/opinion/13pubed.html?_r=1"&gt;not cursed&lt;/a&gt;. They used dashes so that they &lt;em&gt;could&lt;/em&gt; curse; they wanted to say &amp;quot;fucking&amp;quot; without getting in trouble. It stands to reason that if they prefer to curse, they would simply have done so plainly, had they been allowed. How the convention turned into a knee-jerky way of pretending &lt;em&gt;not&lt;/em&gt; to curse is beyond me. Those laws are either no longer on the books or don&amp;#39;t apply to you anyway, and you&amp;#39;re allowed to curse to your heart&amp;#39;s content. And you&amp;#39;re making cursing &lt;em&gt;harder&lt;/em&gt; for yourself and everyone who reads your writing. Why would you do that?&lt;/p&gt;

&lt;p&gt;So stop. Please. No more cursfuscation. Your intentionally transparent word manglings do no one any good. It&amp;#39;s insulting to our intelligences and cringe-inducing to read. You will offend no one who won&amp;#39;t be offended regardless. Spare us your dashes, your asterisks, your beeps, your twisted versions of the words you&amp;#39;re trying, awkwardly, to communicate to us and &lt;em&gt;just fucking say it&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Or don&amp;#39;t say it.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Twix.js</title>
    <id>drunkencoder.net,/introducing_twix_js</id>
    <updated>2012-01-09T00:00:00+00:00</updated>
    <link href="http://drunkencoder.net//introducing_twix_js"/>
    <content type="html">&lt;p&gt;&lt;img src="/content/twix.png" alt="So delicious!"&gt;&lt;/p&gt;

&lt;p&gt;I&amp;#39;ve been working on a simple project for handling date and time ranges in JS. I have a long ways to go, but I have the first part working well: formatting date ranges. And that makes for a good introduction to the topic as a whole, so I figured I&amp;#39;d blog about it.&lt;/p&gt;

&lt;h2&gt;Displaying time ranges&lt;/h2&gt;

&lt;p&gt;See, formatting date ranges so they can be read naturally isn&amp;#39;t very easy. The general format on the web is something like:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;Jan&lt;/span&gt; 26&lt;span class="p"&gt;,&lt;/span&gt; 7&lt;span class="p"&gt;:&lt;/span&gt;00 &lt;span class="n"&gt;PM&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;Jan&lt;/span&gt; 26&lt;span class="p"&gt;,&lt;/span&gt; 9&lt;span class="p"&gt;:&lt;/span&gt;00 &lt;span class="n"&gt;PM&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Which isn&amp;#39;t something you&amp;#39;d ever say, but it&amp;#39;s what happens when you treat a date range as nothing more than two dates, call &lt;code&gt;toString()&lt;/code&gt; on each one, and then join them with a dash. It&amp;#39;s easy, so everyone does it.&lt;/p&gt;

&lt;p&gt;But what I want to say is:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;Jan&lt;/span&gt; 26&lt;span class="p"&gt;,&lt;/span&gt; 7 &lt;span class="o"&gt;-&lt;/span&gt; 9 &lt;span class="n"&gt;PM&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;You might disagree. Maybe you live in France or something, and you want to say:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;Jan&lt;/span&gt; 26&lt;span class="p"&gt;,&lt;/span&gt; 19&lt;span class="p"&gt;:&lt;/span&gt;00 &lt;span class="o"&gt;-&lt;/span&gt; 21&lt;span class="p"&gt;:&lt;/span&gt;00
&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Or maybe you&amp;#39;re just the verbose type and want:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;Thursday&lt;/span&gt; &lt;span class="n"&gt;January&lt;/span&gt; 26&lt;span class="n"&gt;th&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 7&lt;span class="n"&gt;pm&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; 9&lt;span class="n"&gt;pm&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;

&lt;h2&gt;Twix&lt;/h2&gt;

&lt;p&gt;In any case, I have a JS library that can handle that. It&amp;#39;s called &lt;a href="https://github.com/icambron/twix.js"&gt;Twix.js&lt;/a&gt;, and it&amp;#39;s pretty cool. Here are those three examples:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="c1"&gt;//takes dates or parses them&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;twix&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Twix&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;1/26/2012 7:00 PM&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;1/26/2012 9:00 PM&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;twix&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;format&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;                           &lt;span class="c1"&gt;//=&amp;gt; Jan 26, 7 - 9 PM&lt;/span&gt;
&lt;span class="nx"&gt;twix&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;format&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="nx"&gt;twentyFourHour&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;     &lt;span class="c1"&gt;//=&amp;gt; Jan 26, 19:00 - 21:00&lt;/span&gt;

&lt;span class="c1"&gt;//so I admit, this one is complicated&lt;/span&gt;
&lt;span class="nx"&gt;twix&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;format&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="nx"&gt;showDayOfWeek&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;weekdayFormat&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;dddd&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;monthFormat&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;MMMM&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;dayFormat&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Do&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;groupMeridiems&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;spaceBeforeMeridiem&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;meridiemFormat&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;a&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;                                     &lt;span class="c1"&gt;//=&amp;gt; January 26th, 7pm - 9pm&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;It can also handle all sorts of different range sizes as well as all-day events.&lt;/p&gt;

&lt;h2&gt;Get it&lt;/h2&gt;

&lt;p&gt;I have a lot left to do, but the formatting stuff seems usable. Comprehensive docs, downloads, and finger paintings live on &lt;a href="https://github.com/icambron/twix.js"&gt;Github&lt;/a&gt;.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Another year, another editor</title>
    <id>drunkencoder.net,/another_year_another_editor</id>
    <updated>2011-12-24T00:00:00+00:00</updated>
    <link href="http://drunkencoder.net//another_year_another_editor"/>
    <content type="html">&lt;h2&gt;The constant search&lt;/h2&gt;

&lt;p&gt;I&amp;#39;m pretty much always looking for a new text editor. Every once in a while, I get pissed off enough at Emacs to sit down with a six-pack and a freshly downloaded editor and see if I can, you know, use the damn thing. I usually last about 15 minutes before I go scurrying back to Emacs, tail between my legs and slightly drunk.&lt;/p&gt;

&lt;p&gt;&lt;a href="/content/emacs.png"&gt;&lt;img src="/content/emacs_small.png" alt="Where I spend my day"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The thing is, I hate Emacs. It&amp;#39;s terrible at so many things. Its ecosystem is a clusterfuck of poorly maintained modes and broken extensions. It&amp;#39;s chalk full of  interface idiosyncrasies that make it painful when toggling between other programs. The default keybindings require you to make a cat&amp;#39;s cradle with your fingers. The shell is broken in half a dozen ways. ELisp is weird. And goddamn is Emacs slow.&lt;/p&gt;

&lt;p&gt;And yet...I come back to it every time. It&amp;#39;s the editor I can&amp;#39;t break up with. This is not because it has some special place in my heart; it&amp;#39;s because every other editor really blows. They require you to use the mouse to do the most basic things. They throw weird dialogs at you, and those dialogs break all the conventions the rest of the editor uses. They think in files instead of buffers. They provide you cool autocomplete and go-to-definition features but ignore your need to actually edit text. They come with crummy defaults and then make them painful to change.&lt;/p&gt;

&lt;p&gt;All that, and I&amp;#39;m actually a &lt;em&gt;casual&lt;/em&gt; Emacs user. I&amp;#39;m not one of those guys with 5000-line .emacs files who check their email in it. For all my time using it, I&amp;#39;m a noob in Emacs land, struggling to efficiently edit text. It&amp;#39;s just that it sucks less than other editors.&lt;/p&gt;

&lt;p&gt;But that doesn&amp;#39;t stop me from trying to do better. Here at Drunken Coder, we&amp;#39;re always stumbling blindly into the arms of new, shiny editors, having sloppy one-night stands with them, and never calling them back.&lt;/p&gt;

&lt;h2&gt;A brief history of time&lt;/h2&gt;

&lt;p&gt;Sometimes those one-night stands turn into flings, or get drawn out into rebound relationships driven by some particularly nasty fight with E (we&amp;#39;re going to call it E from now, I&amp;#39;ve just decided). They&amp;#39;re not necessarily any better than the quickly discarded JEdits and Bluefishes and so on; it&amp;#39;s just that they stuck around somehow. Maybe it&amp;#39;s just that they wanted me? Here are the ones who made it to a second date:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Eclipse&amp;#47;RAD - It knows Java and understood the &lt;s&gt;Byzantine boondoggle&lt;/s&gt; &lt;a href="http://en.wikipedia.org/wiki/IBM_Workplace"&gt;sophisticated project&lt;/a&gt; I was working on. Otherwise, Eclipse is just a bloated, sluggish mess of menus and modes and clicking and NullPointerExceptions.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="http://www.slickedit.com/products/slickedit"&gt;SlickEdit&lt;/a&gt; - It&amp;#39;s great at editing text, is hugely customizable, and has a few &lt;a href="http://www.slickedit.com/products/slickedit/cool-features#surroundwith"&gt;features&lt;/a&gt; I still miss. But it&amp;#39;s ugly, the UI is awkward, the customizations are in a weird C-like language, and--when I used it--it couldn&amp;#39;t parse non-ancient versions of C#. Oh, and it&amp;#39;s expensive and you have to pay each year to keep up.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Visual Studio - Can parse C#, but is completely unhelpful without an &lt;a href="http://www.jetbrains.com/resharper/"&gt;expensive third-party plugin&lt;/a&gt; (which is itself very nice). More importantly, VS may be the &lt;em&gt;worst text editor I&amp;#39;ve ever used&lt;/em&gt;. Seriously, just awful. And out of contention anyway -- I don&amp;#39;t run Windows anymore.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;RubyMine - It&amp;#39;s packed with nice Ruby features and it runs well on Linux, but it can&amp;#39;t escape its Eclipse heritage. Too clunky.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;My number one issue with random editors, if you want to know the slightly inebriated and tangential truth, is that they don&amp;#39;t treat their menus as first-class buffers. They&amp;#39;ve let you make whatever customizations you want to how text in the actual file is edited (ctrl+k for &amp;quot;kill line&amp;quot; or ctrl+~ ctrl+\ for &amp;quot;transpose then upcase then wrap in playful emoticons&amp;quot; or whatever), but those customizations don&amp;#39;t work when you&amp;#39;ve called up a file switcher dialog, because the guy who wrote it just used the system&amp;#39;s text box control. It&amp;#39;s fucking infuriating.&lt;/p&gt;

&lt;h2&gt;Sublime Text 2&lt;/h2&gt;

&lt;p&gt;I&amp;#39;ve been working in Rails and Node and random stuff for almost two years now, and I&amp;#39;m once again tired of E. In fact, it&amp;#39;s been doing this weird thing where sometimes the text disappears for no reason. Also, I have now tried every JS mode I can find and not one is even passable. I could debug all that or hack away at a JS mode until it does what I want, but then again, I could also be hacking on something new and exciting instead of old and broken, or, you know, doing actual work.&lt;/p&gt;

&lt;p&gt;Of course, it&amp;#39;s not like any of my old complaints about E have been magically fixed. That thing is stuck in time. It&amp;#39;s like hunting with a musket.&lt;/p&gt;

&lt;p&gt;It&amp;#39;s time for another breakup.&lt;/p&gt;

&lt;p&gt;Enter the new flavor of the week. &lt;a href="http://www.sublimetext.com/"&gt;Sublime Text 2&lt;/a&gt; is gorgeous, fast, and customizable. And it&amp;#39;s made it past round one: can I stand it?&lt;/p&gt;

&lt;p&gt;&lt;a href="/content/sublime.png"&gt;&lt;img src="/content/sublime_small.png" alt="Subliminal messages"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Bullet points? Bullet points:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;It&amp;#39;s really clean and acts like a real text editor.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It uses TextMate language modes, so it taps into a big existing ecosystem (I&amp;#39;ve been amazed at how much better its understanding of Ruby is than my Emacs mode).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It&amp;#39;s got that cool minimap. I can&amp;#39;t even imagine how that would ever be useful, but it&amp;#39;s sexy as hell. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The file switching and code browsing is quite good, though I&amp;#39;d rather get rid of the tabs and groups and just have a list of open files.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You customize it in Python and there seems to be a solid community around doing just that.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;The long hard road out of Hell&lt;/h2&gt;

&lt;p&gt;Switching editors is really hard, and I&amp;#39;m not where I want to be with Sublime yet. Partially that&amp;#39;s my desire to go whole hog. For example I&amp;#39;d like to give up the ctrl+x prefix on commands (I&amp;#39;m sick of mindlessly hitting them in other programs) even though I think they&amp;#39;re mostly reasonable. So there&amp;#39;s a steeper learning curve and I keep accidentally closing buffers trying to do kill-region, or cutting text while trying to save a file. It would be like coding drunk if I weren&amp;#39;t already coding drunk.&lt;/p&gt;

&lt;p&gt;Not there isn&amp;#39;t enough mental retraining to do just from switching editors.&lt;/p&gt;

&lt;p&gt;I also need to get it customized to where I&amp;#39;m actually reasonably productive relative to E, regardless of how painful E is. That&amp;#39;s a big time investment and one of the reasons I&amp;#39;ve dropped many would-be editors. It doesn&amp;#39;t help that the Sublime documentation is almost non-existent and you have to glean even the basic customization paradigm from the support forums. (I&amp;#39;m sure it&amp;#39;s harder for me; I have the feeling most of the user base is TextMate converts and have some relevant prior knowledge.)&lt;/p&gt;

&lt;p&gt;And I already have complaints:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;I can&amp;#39;t seem to make misspelled words not show up in retina-searing red. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Oh, and there seems to be some sort of bug about spell-checking words in brackets. See that in the screenshot?&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I can&amp;#39;t run a terminal in it (for Linux anyway; it has one for Mac). &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I don&amp;#39;t know how to override parts of a theme without forking the whole theme. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The mark&amp;#47;kill&amp;#47;yank stuff is poorly implemented and I had to pull in (and edit) a third-party plugin just for that.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It&amp;#39;s a tiny bit weird with line wraps.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;There&amp;#39;s what I suspect is Linux-specific clunkiness in opening files and projects.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So we&amp;#39;ll see. I might be slinking back to Emacs a few weeks.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Scale and Google's Customer Support</title>
    <id>drunkencoder.net,/google_profits_and_scale</id>
    <updated>2011-10-15T00:00:00+00:00</updated>
    <link href="http://drunkencoder.net//google_profits_and_scale"/>
    <content type="html">&lt;p&gt;&lt;a href="http://news.ycombinator.com/item?id=3099875"&gt;This Hacker News item&lt;/a&gt; is a complaint about a website being delisted by Google without a good, easily-understood explanation. &lt;a href="http://twitter.com/#!/mattcutts"&gt;Matt Cutts&lt;/a&gt;, who runs the webspam team at Google, jumped into the comment thread and provided some explanations. While the reasons he gave for delisting do make sense, one of the main counterarguments was that Google&amp;#39;s customer support for webmasters is terrible, and the company is rather opaque and abrupt about the process. Why did the site owner have to find out how to fix it by getting his post at the top of Hacker News? &lt;/p&gt;

&lt;p&gt;In the thread, Cutts says, in reference to a premium support option, &amp;quot;Normally when we consider it, we end up saying things like &amp;#39;Why don&amp;#39;t we just try to make it so that people don&amp;#39;t need that option?&amp;#39;&amp;quot; And that&amp;#39;s fine; not needing customer support is better than needing it. But until they figure that out, Google &lt;em&gt;does&lt;/em&gt; need it; you can&amp;#39;t just dismiss it with a hand wave and a vague goal. Google has a &lt;em&gt;huge&lt;/em&gt; transparency problem. Their rankings and delisting decisions are opaque and seemingly arbitrary. For good evidence of this, just take a look at &lt;a href="http://teddziuba.com/2010/06/seo-is-mostly-quack-science.html"&gt;how quacky&lt;/a&gt; the gigantic SEO industry is; witchcraft shouldn&amp;#39;t seem like a viable option here. More generally, Google just doesn&amp;#39;t have customer support worth much of anything, and they just don&amp;#39;t seem to care about it. Why?&lt;/p&gt;

&lt;p&gt;Cutts has an answer there, although I suppose I should point out that he&amp;#39;s not acting as some sort of official spokesperson for Google. In responding to the opacity&amp;#47;abruptness&amp;#47;support complaint, he says this:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I know that Google can seem abrupt sometimes, and I dislike that, but part of the issue is also scale. See &lt;a href="https://plus.google.com/117377434815709898403/posts/1hRWj489oEz"&gt;https:&amp;#47;&amp;#47;plus.google.com&amp;#47;117377434815709898403&amp;#47;posts&amp;#47;1hRWj489...&lt;/a&gt; that notes that if each Google user had a single 10 minute issue every three years, that would need 20,000+ support people to handle that load. Or consider that there&amp;#39;s 200M domain names, and all those webmasters want to talk to Google and ask questions.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For the record, I think this kind of direct engagement by important employees is great. But I don&amp;#39;t buy Cutt&amp;#39;s scale angle at all. Here&amp;#39;s the thing: &lt;strong&gt;20,000 seems like a lot of people, but it&amp;#39;s not.&lt;/strong&gt; Consider this statement I just made up:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I know McDonald&amp;#39;s can be impersonal sometimes, and I dislike that, but part of the issue is also scale. If each McDonald&amp;#39;s customer needed to be served a burger in person by a McDonald&amp;#39;s employee, that would require 400,000 employees to physically make and serve all those burgers.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And, of course, that&amp;#39;s exactly what McDonald&amp;#39;s does, and you&amp;#39;d be really annoyed if you walked into McDonald&amp;#39;s one day and your burger was sitting premade on a little heated tray that had been filled with foil-wrapped food hours earlier, and there was no one working there. McDonald&amp;#39;s is actually a somewhat smaller company than Google ($24 billion vs $29 billion) and has far lower profits ($5 billion vs $9 billion). So Google makes a lot more money per dollar it spends. Those are obviously very different companies, and there are a lot of reasons McDonald&amp;#39;s has lower profits than Google, but one of them is that &lt;em&gt;Google doesn&amp;#39;t employ tens of thousands of people to do customer support&lt;/em&gt;. But maybe it should!&lt;/p&gt;

&lt;p&gt;We could debate whether 20,000 support people is enough, or actually way more than they&amp;#39;d ever need, or whatever, but that&amp;#39;s not the point. The fact is that Google isn&amp;#39;t having difficulty scaling its customer support team. It&amp;#39;s just not trying to build one at all. Yet it could clearly afford one as big or bigger than the 20,000 people it thinks of as crazily huge.&lt;/p&gt;

&lt;p&gt;No, it&amp;#39;s simpler: Google doesn&amp;#39;t have an army of support people because it can make more money by having poor customer service. It has a monopoly on search, and if you want your website listed there, you&amp;#39;ll play their game no matter how difficult it is. It&amp;#39;s just not under any meaningful pressure to improve in this area. So instead of employing a bunch of people in call centers to answer your questions and fix mistakes, it pockets more money. Corporations are greedy--maximizing profits is their job--but we shouldn&amp;#39;t be giving them a free pass on this sort of thing just because they&amp;#39;ve complained it&amp;#39;s expensive. Making billions of dollars is supposed to be hard work. We should all be demanding better customer support from Google, and maybe we should be taking a good hard look at their competitive practices in this area.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Programming Languages Matter</title>
    <id>drunkencoder.net,/programming_languages_matter</id>
    <updated>2011-10-14T00:00:00+00:00</updated>
    <link href="http://drunkencoder.net//programming_languages_matter"/>
    <content type="html">&lt;p&gt;&lt;a href="http://en.wikipedia.org/wiki/Structure_and_Interpretation_of_Computer_Programs#Characters"&gt;Ben Bitdiddle and Alyssa P. Hacker&lt;/a&gt; are at a bar, at least three martinis deep. You&amp;#39;re at nearby table and overhear their loud conversation:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;BB&lt;/strong&gt;: I don&amp;#39;t want that job, because I&amp;#39;m a Java programmer and they&amp;#39;re a Python shop, and--&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;APH&lt;/strong&gt;: What do you mean, you&amp;#39;re a &amp;quot;Java programmer&amp;quot;?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;BB&lt;/strong&gt;: Well, you know, some people are Perl programmers, and other people are Java programmers, and other--&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;APH&lt;/strong&gt;: No. Of all the stupid ways you can sort programmers into buckets--back-end vs front-end, application vs operating system, enterprise vs consumer--why would you choose to define yourself by the programming language you typically use?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;BB&lt;/strong&gt;: Well, I know Java. I don&amp;#39;t know Python. It says &amp;quot;Java programmer&amp;quot; next to my name on my resume.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;APH&lt;/strong&gt;: If you want to put yourself into a box, then define yourself by the kinds of problems you want to solve, your style of problem solving, or something like that. A programming language is a tool; within certain parameters, you can do anything with any of them. I mean, honestly, how long does it take you to learn a new language? Some new syntax should be trivial compared to learning, say, how to architect a scalable system, and that&amp;#39;s the same in any language.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Then you go back to whatever more interesting conversation you were having. You&amp;#39;re pretty sure they go home together and have loud, punny sex. But let&amp;#39;s talk about what they said. To a first order approximation, APH &amp;gt; BB. As Steve Yegge has &lt;a href="http://steve-yegge.blogspot.com/2007/12/codes-worst-enemy.html"&gt;observed&lt;/a&gt;, &amp;quot;an &amp;#39;X programmer&amp;#39;, for any value of X, is a weak player.&amp;quot; It&amp;#39;s true enough, and I&amp;#39;m always annoyed when I&amp;#39;m called a [whatever language I&amp;#39;m using at the time] programmer. But APH is very wrong about &lt;em&gt;why&lt;/em&gt; BB shouldn&amp;#39;t care so much about his Java identity.&lt;/p&gt;

&lt;p&gt;Defining yourself as, say, a Java programmer has some serious pitfalls. First, Java isn&amp;#39;t the right tool for every job, and in fact is very awkward for some of them. As a trivial example, you wouldn&amp;#39;t use it to write a shell script to copy around some files. I think everyone gets that it&amp;#39;s just too verbose and structured to do job well.&lt;/p&gt;

&lt;p&gt;To generalize that, the reason BB and APH are both wrong is that defining yourself by a language limits your thinking. Like a real-life spoken language, you can&amp;#39;t think about &lt;a href="http://plato.stanford.edu/entries/language-thought/"&gt;things you can&amp;#39;t put into words&lt;/a&gt;. Language isn&amp;#39;t a way of capturing thoughts; it&amp;#39;s the building blocks of those thoughts. To give a simplistic example, people in some primitive cultures can&amp;#39;t differentiate green and yellow because they don&amp;#39;t have different words for them. Similarly, if you&amp;#39;re stuck thinking in Java (and you are, even if you&amp;#39;re thinking about something wildly abstract, like APH&amp;#39;s &amp;quot;architecting scalable systems&amp;quot;, whatever that means), then you&amp;#39;re missing entire programming paradigms, and the chances are you&amp;#39;re building something the wrong way. Maybe the best way to think about structuring your program is in terms of Lisp macros or Haskell existential types or continuations or Erlang actors or Node events or monads. But those aren&amp;#39;t primitives you know, so you can&amp;#39;t build the higher-level structures of your program around them.&lt;/p&gt;

&lt;p&gt;And worse, &lt;em&gt;you don&amp;#39;t even know it&lt;/em&gt;. You can&amp;#39;t even conceptualize it. If you&amp;#39;d never seen a &amp;quot;scripting&amp;quot; language, you &lt;em&gt;would&lt;/em&gt; start your little file-copying programs with &lt;code&gt;public static void main(String[] args)&lt;/code&gt;, and you wouldn&amp;#39;t think anything of it. It would just be The Way Things Are Done.&lt;/p&gt;

&lt;p&gt;In any language, I find myself mixing and matching programming paradigms borrowed from other languages, or approximating language features I don&amp;#39;t have available. Java programmers sometimes fake closures by creating anonymous inner types, and while it&amp;#39;s a pretty crummy approximation, it goes a long way towards solving some otherwise painful programming problems. But first you have to know what a closure is and what it&amp;#39;s good for. And you might know that because you&amp;#39;ve worked with programming languages where functions are first-class. To get more exotic, if I knew Haskell in any depth, I might use monads as part of problem solving toolkit, and that might allow me to structure, say, a Ruby program with better data abstractions. But I can&amp;#39;t really know that until I figure out what monads are all about. Note to self: learn Haskell.&lt;/p&gt;

&lt;p&gt;Of course, it goes deeper than language features: languages are more than just syntax trees. A lot more. In practice, languages are tightly coupled with standard libraries, platforms, and ecosystems. These are usually impedance-matched with the language itself; have you ever noticed that Java libraries tend to be verbose and explicit while Ruby libraries tend to be terse and slick? That extends to how the API interfaces are structured, the extension points, the level of programatic openness, everything. When you choose a language, you&amp;#39;re also choosing a programming philosophy, because everything built for you is built with that philosophy.&lt;/p&gt;

&lt;p&gt;You might have decided you strongly programming under a certain philosophy. Let&amp;#39;s say--and we&amp;#39;re being incredibly simplistic about the salient features of languages--you really like dynamic, hack-friendly languages with lots of syntactic shortcuts, because you&amp;#39;re a dynamic, hacky, slick kind of dude. That&amp;#39;s fine, I&amp;#39;m with you. But what happens when you come across a problem that&amp;#39;s best solved with a statically typed language with lots of imposed structure? Do you abandon the whole problem, or do you pigeon hole it into your programming aesthetic? You should instead learn some alternative techniques indigenous to other languages, or even just solve the problem in one of those languages. Do you really think your language is so perfect that it contains every concept you might need?&lt;/p&gt;

&lt;p&gt;There are some good reasons you might build something in Java (or any other language). But there are also an awful lot of bad ones, the greatest of which is that you just happen to know Java. So yeah, BB should maybe look more closely at that Python gig. And APH should think a bit harder about programming languages, and why they might be important.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Introducing Spandex</title>
    <id>drunkencoder.net,/introducing_spandex</id>
    <updated>2011-09-29T00:00:00+00:00</updated>
    <link href="http://drunkencoder.net//introducing_spandex"/>
    <content type="html">&lt;p&gt;So you&amp;#39;re a programmer, and you want to start a blog. You&amp;#39;ve got some pretty cool opinions about software construction and that wine from dinner has you thinking the entire world has just &lt;em&gt;got&lt;/em&gt; to know all about them. And maybe some neat posts about the aardvarks you&amp;#39;ve seen lately. Sitting down with your digestif, you get to work. You go the standard route: you find one of the dozen crummy WordPress hosts, pick a theme, and start typing your brilliance into a form in the admin section of your site. And it sorta works.&lt;/p&gt;

&lt;p&gt;But then you start thinking about it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Why can&amp;#39;t you use your favorite editor? I mean, you spent all this time customizing the crap out of your Emacs experience, and now you&amp;#39;re typing tons of content into a form in your &lt;em&gt;browser&lt;/em&gt;?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Man do these WISYWYG editors blow. Wouldn&amp;#39;t you rather be using a nice markup language, like maybe something similar to what &lt;a href="http://stackoverflow.com"&gt;StackOverflow&lt;/a&gt; uses?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;WP&amp;#39;s admin interface is your content management system. But you&amp;#39;re already very proficient with a much fancier, more powerful CMS: your source control system. You can use it from the command line instead of a clunky interface, and you can do a lot more with it. Why can&amp;#39;t you use that?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Your posts live in a database somewhere that you don&amp;#39;t really have access to.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;No, but really, did I mention your WP host totally sucks ass? I guess you could install WP on an EC2 instance, but that seems like overkill, right? Maybe you could host it on &lt;a href="http://heroku.com"&gt;Heroku&lt;/a&gt;?&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;A different model&lt;/h2&gt;

&lt;p&gt;A better idea might be a site that reads your posts from files (like, on the filesystem!) and generates web pages from them. Now you can manage those files in Git and edit them however you want. And if they&amp;#39;re built on a cool stack, you&amp;#39;ll be able to host it somewhere free and nice. So, you look around, and there are some pretty cool options:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/mojombo/jekyll"&gt;Jekyll&lt;/a&gt;: Generate static HTML pages from Textile or Markdown files and then host them wherever you want.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="http://nestacms.com/"&gt;Nesta&lt;/a&gt;: Dynamically generate a site from markup files. Themes, plugins, and all that jazz.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/cloudhead/toto"&gt;Toto&lt;/a&gt;: Another dynamic site that generates the blog from static Markdown files.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I&amp;#39;m sure there are others. I lean more towards the Nesta&amp;#47;Toto model of generating the HTML dynamically. That narrows my hosting options (because my host will have to support whatever web framework the engine runs on), but means there&amp;#39;s less for me to actually do (I don&amp;#39;t have to generate the site before pushing it to the host). But whatevs.&lt;/p&gt;

&lt;h2&gt;What&amp;#39;s a blog, anyway?&lt;/h2&gt;

&lt;p&gt;But you&amp;#39;re feeling a bit greedy and you want to do even more with less. So you think, what, in a technical sense, is a blog? It&amp;#39;s two things: 1) a simple content management system that keeps track of your posts, figures out which ones to show your user, turns them into HTML, and generates an RSS feed; and 2) a web application to actually show those posts in. A blog engine tackles both things. &lt;/p&gt;

&lt;p&gt;But here&amp;#39;s the thing: you&amp;#39;re good at building websites. You want to build your &lt;strong&gt;own&lt;/strong&gt; website, where you control what the URLs mean, and how the framing markup gets generated, and all that jazz. Maybe you want to integrate the blog into an existing site. Maybe you want customize the framing HTML (you know the chrome stuff like the title and footer and sidebars), but you really &lt;em&gt;hate&lt;/em&gt; Haml for some reason and Nesta uses it for just that purpose. And you don&amp;#39;t really want to think about &amp;quot;themes&amp;quot;; you want to have some HTML and write some CSS for it, and that&amp;#39;s that. The world has built you a bunch of awesome web frameworks to build sites with, and dammit you want to use them. It&amp;#39;s just the CMS part that&amp;#39;s annoying; there has to be some code somewhere that pulls the right files off of disk and formats them when the user, say, clicks on the links for posts tagged &amp;quot;aardvarks&amp;quot;. (You love aardvarks, it turns out. No one is sure why.)&lt;/p&gt;

&lt;p&gt;I&amp;#39;m going to assume, for no real reason, that you&amp;#39;re the kind of programmer who likes Ruby. It&amp;#39;s a good thing you are, because I have some good news: &lt;strong&gt;I wrote you the piece that does all the content management&lt;/strong&gt;. It&amp;#39;s called Spandex.&lt;/p&gt;

&lt;h2&gt;Spandex!&lt;/h2&gt;

&lt;p&gt;OK, so first of all, what kind of abject moron names a programming library &amp;quot;spandex&amp;quot;? When you hear it, all you can think about is this:&lt;/p&gt;

&lt;iframe width="420" height="315" src="http://www.youtube.com/embed/J1c2KzJbcGA" frameborder="0" allowfullscreen&gt;&lt;/iframe&gt;

&lt;p&gt;Yeah, I don&amp;#39;t know. The gem name wasn&amp;#39;t taken. Anyway, Spandex lets you do stuff like:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;some_posts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;spandex&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;find_articles&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:tag&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;aardvarks&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;some_posts&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;post&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Title: &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;post&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;
  &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Stuff about aardvarks: &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;post&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;How do you make these awesome posts about aardvarks? Here&amp;#39;s omg_aardvarks.md:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="err"&gt;Title:&lt;/span&gt; &lt;span class="err"&gt;Oh&lt;/span&gt; &lt;span class="err"&gt;my&lt;/span&gt; &lt;span class="err"&gt;God&lt;/span&gt; &lt;span class="err"&gt;I&lt;/span&gt; &lt;span class="err"&gt;saw&lt;/span&gt; &lt;span class="err"&gt;some&lt;/span&gt; &lt;span class="err"&gt;aardvarks!&lt;/span&gt;
&lt;span class="err"&gt;Tags:&lt;/span&gt; &lt;span class="err"&gt;aardvarks,&lt;/span&gt; &lt;span class="err"&gt;things&lt;/span&gt; &lt;span class="err"&gt;i&lt;/span&gt; &lt;span class="err"&gt;saw&lt;/span&gt; &lt;span class="err"&gt;today&lt;/span&gt;
&lt;span class="err"&gt;Date:&lt;/span&gt; &lt;span class="err"&gt;2011/9/2011&lt;/span&gt;

&lt;span class="err"&gt;I&lt;/span&gt; &lt;span class="err"&gt;was&lt;/span&gt; &lt;span class="err"&gt;just&lt;/span&gt; &lt;span class="err"&gt;riding&lt;/span&gt; &lt;span class="err"&gt;my&lt;/span&gt; &lt;span class="err"&gt;bike&lt;/span&gt; &lt;span class="err"&gt;down&lt;/span&gt; &lt;span class="err"&gt;the&lt;/span&gt; &lt;span class="err"&gt;street&lt;/span&gt; &lt;span class="err"&gt;and&lt;/span&gt; &lt;span class="err"&gt;**LO&lt;/span&gt; &lt;span class="err"&gt;AND&lt;/span&gt; &lt;span class="err"&gt;BEHOLD**,&lt;/span&gt; &lt;span class="err"&gt;an&lt;/span&gt; &lt;span class="err"&gt;aardvark!!!&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Yeah, your aardvark obsession is a bit creepy; let&amp;#39;s more on. The top part of the file consists of key-value pairs that provide metadata to Spandex. Stuff like whether it&amp;#39;s in draft mode. The bottom is the content. You can write it in any markup language supported by &lt;a href="https://github.com/rtomayko/tilt"&gt;Tilt&lt;/a&gt;; it&amp;#39;ll decide which to use based on the extension. And you can customize that through Tilt itself.&lt;/p&gt;

&lt;p&gt;There are a lot more details, examples, and awkward non sequiturs on Spandex&amp;#39;s &lt;a href="https://github.com/icambron/spandex"&gt;Github page&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Sounds easy, right? So finish your glass of port, get a sixpack of beer, and let&amp;#39;s build a blog.&lt;/p&gt;

&lt;h2&gt;Build ye blog&lt;/h2&gt;

&lt;p&gt;You&amp;#39;re going to want to start simple. A blog with some posts, an about page, something allows all of your avid fans to comment, and an atom feed.&lt;/p&gt;

&lt;p&gt;Let&amp;#39;s get to work. We&amp;#39;ve got our spandex on, so now we just need to build a website. Let&amp;#39;s use &lt;a href="http://sinatrarb.com"&gt;Sinatra&lt;/a&gt;, &lt;a href="http://haml-lang.com/"&gt;Haml&lt;/a&gt; (which I guess you don&amp;#39;t hate after all), and the SCSS variety of &lt;a href="http://sass-lang.com/"&gt;Sass&lt;/a&gt;. OK, here&amp;#39;s our directory structure:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;   &lt;span class="o"&gt;+-&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;rb&lt;/span&gt;              &lt;span class="c"&gt;# Your Sinatra app&lt;/span&gt;
   &lt;span class="o"&gt;|&lt;/span&gt;
   &lt;span class="o"&gt;+-&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ru&lt;/span&gt;           &lt;span class="c"&gt;# Config file for making Sinatra sing. Get it?&lt;/span&gt;
   &lt;span class="o"&gt;|&lt;/span&gt;
   &lt;span class="o"&gt;+-&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;             &lt;span class="c"&gt;# Bucket of your content&lt;/span&gt;
   &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
   &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;+-&lt;/span&gt; &lt;span class="n"&gt;omg_aarvarks&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;md&lt;/span&gt;   &lt;span class="c"&gt;# Your first post!&lt;/span&gt;
   &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
   &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;+-&lt;/span&gt; &lt;span class="n"&gt;about&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;md&lt;/span&gt;          &lt;span class="c"&gt;# Some stuff about you&lt;/span&gt;
   &lt;span class="o"&gt;|&lt;/span&gt;
   &lt;span class="o"&gt;+-&lt;/span&gt; &lt;span class="n"&gt;views&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;              &lt;span class="c"&gt;# HTML templates for the chrome&lt;/span&gt;
      &lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="o"&gt;+-&lt;/span&gt; &lt;span class="nb"&gt;index&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;haml&lt;/span&gt;       &lt;span class="c"&gt;# Shows all of the posts in descending order&lt;/span&gt;
      &lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="o"&gt;+-&lt;/span&gt; &lt;span class="n"&gt;layout&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;haml&lt;/span&gt;      &lt;span class="c"&gt;# Title bars and such&lt;/span&gt;
      &lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="o"&gt;+-&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;haml&lt;/span&gt;        &lt;span class="c"&gt;# Display and individual post and its comments&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;So, app.rb handles the web requests:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;sinatra&amp;#39;&lt;/span&gt;
&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;spandex&amp;#39;&lt;/span&gt;
&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;haml&amp;#39;&lt;/span&gt;

&lt;span class="n"&gt;content_dir&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;File&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;expand_path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;content&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;File&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dirname&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;__FILE__&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="vc"&gt;@@spandex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Spandex&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;content_dir&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;#render the index&lt;/span&gt;
&lt;span class="n"&gt;get&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;/&amp;#39;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;posts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="vc"&gt;@@spandex&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;all_articles&lt;/span&gt;
  &lt;span class="n"&gt;haml&lt;/span&gt; &lt;span class="ss"&gt;:index&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:locals&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:posts&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# render the atom feed&lt;/span&gt;
&lt;span class="n"&gt;get&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;/feed.xml&amp;#39;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;content_type&lt;/span&gt; &lt;span class="ss"&gt;:xml&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:charset&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;utf-8&amp;#39;&lt;/span&gt;
  &lt;span class="vc"&gt;@@spandex&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;atom_feed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;Tiny Blog of Doom&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;Your name here&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;tinyblog.net&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;/feed.xml&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# render stylesheets&lt;/span&gt;
&lt;span class="n"&gt;get&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;/css/:sheet.css&amp;#39;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;content_type&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;text/css&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:charset&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;utf-8&amp;#39;&lt;/span&gt;
  &lt;span class="n"&gt;scss&lt;/span&gt; &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:sheet&lt;/span&gt;&lt;span class="o"&gt;].&lt;/span&gt;&lt;span class="n"&gt;to_sym&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;#render individual posts&lt;/span&gt;
&lt;span class="n"&gt;get&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;*&amp;#39;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;post&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="vc"&gt;@@spandex&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:splat&lt;/span&gt;&lt;span class="o"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;haml&lt;/span&gt; &lt;span class="ss"&gt;:page&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:locals&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:post&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;  &lt;span class="n"&gt;post&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:show_comments&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;The Haml files are also pretty simple. I won&amp;#39;t cover all of the details, but here&amp;#39;s page.haml:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="nt"&gt;%h2&lt;/span&gt;
  &lt;span class="nt"&gt;%a&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:href&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;post&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;}=&lt;/span&gt; &lt;span class="n"&gt;post&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;
&lt;span class="nt"&gt;%div&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;post&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;show_comments&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="no"&gt;ENV&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;DISQUS_NAME&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="no"&gt;Sinatra&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Application&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environment&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="ss"&gt;:development&lt;/span&gt;
    &lt;span class="nt"&gt;%script&lt;/span&gt; var disqus_developer = true;
  &lt;span class="nf"&gt;#disqus_thread&lt;/span&gt;
  &lt;span class="nt"&gt;%script&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:type&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;text/javascript&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:src&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;http://&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="no"&gt;ENV&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;DISQUS_NAME&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="nc"&gt;.disqus.com&lt;/span&gt;/embed.js&amp;quot;, :async =&amp;gt; true}
&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;That shows a single post and pulls in comments from &lt;a href="disqus.com"&gt;Disqus&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;You can run the whole thing with &lt;code&gt;shotgun config.ru&lt;/code&gt; or you can just check it into Git and push the whole thing to Heroku. The source for the entire tiny blog is &lt;a href="https://github.com/icambron/tinyblogofdoom"&gt;here&lt;/a&gt;. Check it out! DO IT NOW.&lt;/p&gt;

&lt;p&gt;You can also check out the &lt;a href="https://github.com/icambron/drunkencoder"&gt;code to this blog&lt;/a&gt;, which naturally uses Spandex, and does some other neato things.&lt;/p&gt;
</content>
  </entry>
</feed>

