No Award

Nothing should dilute or adulterate the exalted joy of watching the chess engine you've toiled over for the better part of three weekends start to suggest moves (from a basic 3-ply negamax search with a simple point-counting position evaluation heuristic), unless it's the slight(ly overdetermined?) suspicion that you're overcompensating for something, that you've proved your point by now, that bringing yet another moderately-sophisticated side project in a not-the-most-popular programming language over the threshold of "really cool-looking proof-of-concept" isn't going to show Everyone that you are Smart and should be Respected any more than the last seven already did. Some people actually use software for something other than a trophy, to automate some aspect of the world that otherwise would have been done more poorly. So you've heard. If one were to hypothesize, for the sake of argument (but perhaps not only for the sake of argument) that there can exist diminishing marginal returns to some games, that Respect from Everyone is not a real thing that can be won, that there are treasures and masteries you'd never imagine while chasing GitHub stars, much like how you know there are treasures and masteries that you'd never imagine while chasing school marks—what strategies would that imply, now that you know there is such a thing as being strategic? And how would you tell the difference?

Because People Will Have Brain-Computer Interfaces or Something

Oftentimes I awake from a coding dream with the realization that I'm physically in bed without a keyboard and that the machine is asleep in the other room, from which I can infer that I must have been asleep, too, and only dreaming about solving problems. But there will probably only be a few more decades during which not having a keyboard is evidence of anything in particular.

Studying on the Weekend

Studying on the weekend as a working professional is like keeping a diversified investment portfolio, in stocks, bonds, commodity futures, cash, silver, ammunition, and Bitcoin in encrypted paper wallets; it's like coming in first by half a lap in the thirty-two hundred meters of your Division III college's track and field meet, and then not stopping, continuing out of the stadium, desperately, bleeding, acknowledging nothing but the need to put ever more distance between you and your hypothetical pursuers, until days later (halfway to Nevada), a classmate leans out of a car window and pleads, "You can stop now! Can't you see you've already won?" incapable of predicting or comprehending your reply murmured between inhalations, "The reason ... I won ... is because ... I don't ... believe in finish lines."

RustCamp Reminiscences

On Saturday the first, I attended RustCamp, the first conference dedicated to the newish (in development for fiveish years, but having just hit version 1.0.0 this May, with all the stability guarantees that implies under the benevolent iron fist of semantic versioning) programming language Rust!

badge_and_lambda_dragon_shirt

Why RustCamp? (It's a reasonable rhetorical question with which to begin this paragraph: going to a conference has opportunity costs in time and money; things worth blogging about are occasionally worth justifying—even if no one actually asked me for a justification.) A lot of the answer can be derived from the answer to a more fundamental question, "Why Rust?" And for me, I think a lot of the answer to that has to do with being sick of being a fake programmer living in a fake world that calls itself Python.

Don't get me wrong: Python is a very nice place to live: good weather, booming labor market, located in a good school district, with most of the books you might want already on the shelves of the main library and almost all of the others a mere hold request away. It's idyllic. Almost ... too idyllic, as if the trees and swimming pools and list comprehensions and strip malls are conspiring to hide something from us, to keep us from guessing what lurks in the underworld between the lines, the gears and gremlins feeding and turning in the layers of tools built on tools built on tools that undergird our experience. True, sometimes small imperfections in the underworld manifest themselves as strange happenings that we can't explain. But mostly, we don't worry ourselves about it. Life is simple in Python. We reassure our children that that legends of demon-king Malloc are just stories. Everything is a duck; ducks can have names and can be mutable or immutable. It all just works like you would expect from common sense, at least if you grew up around here.

Continue reading

$

I used to think of $ in regular expressions as matching the end of the string. I was wrong! It actually might do something more subtle than that, depending on what regex engine you're using. In my native Python's re module, $

[m]atches the end of the string or just before the newline at the end of the string, and in MULTILINE mode also matches before a newline.

Note! The end of the string, or just before the newline at the end of the string.

In [2]: my_regex = re.compile("foo$")

In [3]: my_regex.match("foo")
Out[3]: <_sre.SRE_Match object; span=(0, 3), match='foo'>

In [4]: my_regex.match("foo\n")
Out[4]: <_sre.SRE_Match object; span=(0, 3), match='foo'>

I guess I can see the motivation—we often want to use the newline character as a terminator of lines (by definition) or files (by sacred tradition), without wanting to think of \n as really part of the content of interest—but the disjunctive behavior of $ can be a source of treacherous bugs in the fingers of misinformed programmers!

Continue reading

The Second R

I want to code all of the things, but I also want to write at least some of the things, but sometimes putting things in words—simple things, things I know—can be hard. Every other day I dream of getting in some writing in the night after I return from the code mines across the bay, but the box where the writing tool lives is the same as the box where you can read everything that anyone else has ever written, and you can guess what I really do then, when it's easier to read than to farm, to eat than to write.

But writing is important, because we can imagine nearby possible worlds in which the distribution of verbal skills is incompetenceward of our own, and the people in those worlds are sadder and poorer than us, the clumsiness of their attempts at communication leaving them less effective at coordinating their activities to dominate nature: colleagues maneuver against each other, ineffectually; television is less interesting; lovers stare into each others' eyes having less idea than you of what they're really looking at.

And in our own world, where people can say more, but not enough—I can read, but I'm missing something ... I can reckon with 'rithmetic, which serves a purpose, but cannot in human terms express the richness of vision that courses through ... something. And it cannot be a part of inner peace and glory until paired with something that does, high though the price may be for that something!

The second R, which is yet not an R. I want this more than I can say.

__pycache__/shibboleth.cpython-34.pyc

Sometimes I worry that people with power in Society will look down on me for my pronunciation of the .pyc extension for Python bytecode files. I always want to say pike-cee, even though many would argue that the c should either be hard (pike) or said as the name of the letter (py-cee), but certainly not both in sequence!

Smalltalk

(8:5x a.m., an office on the someteenth floor of the twenty-somethingth tallest building in San Francisco)

"Good morning!"

"'Morning."

"How was your weekend? Did you do anything exciting? Maybe you went to a movie, or to the beach—"

"No—"

"Or embarked on some heroic endeavor of engineering, the likes of which threaten to upend our understanding of the nature of computation itself?"

"No, nothing like that," (sighing, resignedly) "how was your weekend?"

(pretending to inspect his or her fingernails) "My weekend? Oh, nothing special—hung out, did some grocery shopping—"

"Uh huh."

"—wrote a compiler—"

The Foundations of Erasure Codes

(cross-posted from the SwiftStack Blog)

In enabling mechanism to combine together general symbols, in successions of unlimited variety and extent, a uniting link is established between the operations of matter and the abstract mental processes of the most abstract branch of mathematical science. A new, a vast, and a powerful language is developed for the future use of analysis, in which to wield its truths so that these may become of more speedy and accurate practical application for the purposes of mankind [sic] than the means hitherto in our possession have rendered possible.

Ada Lovelace on Charles Babbage's Analytical Engine, 1842

Dear reader, if you're reading [the SwiftStack Blog], you may have already heard that erasure codes have been added to OpenStack Swift (in beta for the 2.3.0 Kilo release, with continuing improvements thereafter) and that this is a really great thing that will make the world a better place.

All of this is entirely true. But what is perhaps less widely heard is exactly what erasure codes are and exactly why their arrival in Swift is a really great thing that will make the world a better place. That is what I aim to show you in this post—and I do mean show, not merely tell, for while integrating erasure codes into a production-grade storage system is (was!) an immense effort requiring months of work by some of the finest programmers the human race has to offer, the core idea is actually simple enough to fit in a (longish) blog post. Indeed, by the end of this post, we will have written a complete working implementation of a simple variant of Reed–Solomon coding, not entirely unlike what is used in Swift itself. No prior knowledge will be assumed except a working knowledge of high-school algebra and the Python programming language.

Continue reading

T.O.P.

"Don't worry, we've got our T.O.P. engineer working on it," said the support man on the phone with our most important customer, glancing meaningfully across the open-plan office in my direction; I winced briefly, then spasmed back towards my screen and fumbled with the keyboard, intending to return my attention to the definition of the DeviceAssignmentRuleComponentManagerFactory, but somehow fat-fingering C-x C-c along the way, every awkward, ungainly movement bearing testimony to the most casual of onlookers that I was Totally Observably Pathetic.

Epistolary

(Previously.)

[19:26:50] <bob>    alice: you still around?
[19:27:08] <alice>  bob, sort of
[19:27:20] <bob>    alice: ok. never mind.
[19:27:41] <alice>  bob, what were you going to ask? I am at the office, 
                    trying to finish up an email but I'm really slow at 
                    choosing words
[19:28:21] <bob>    alice: i was just wondering if you happened to know a 
                    way to manually foo the bar-quuxing device
[19:28:22] <alice>  perhaps because of my overly-ornate and wordy writing 
                    style, which, for not-well-understood psychological 
                    reasons, I nevertheless continue to use despite its 
                    obvious disadvantages in business communication

XXX III

const PSEUDO_DIGITS: [char; 7] = ['M', 'D', 'C', 'L', 'X', 'V', 'I'];
const PSEUDO_PLACE_VALUES: [usize; 7] = [1000, 500, 100, 50, 10, 5, 1];

#[allow(unused_parens)]
fn integer_to_roman(integer: usize) -> String {
    let mut remaining = integer;
    let mut bildungsroman = String::new();
    // get it?? It sounds like _building Roman_ (numerals), but it's
    // also part of the story about me coming into my own as a
    // programmer by learning a grown-up language
    //
    // XXX http://tvtropes.org/pmwiki/pmwiki.php/Main/DontExplainTheJoke
    for ((index, value), &figure) in PSEUDO_PLACE_VALUES.iter()
        .enumerate().zip(PSEUDO_DIGITS.iter())
    {
        let factor = remaining / value;
        remaining = remaining % value;

        if figure == 'M' || factor < 4 {
            for _ in 0..factor {
                bildungsroman.push(figure);
            }
        }

        // IV, IX, XL, &c.
        let smaller_unit_index = index + 2 - (index % 2);
        if smaller_unit_index < PSEUDO_PLACE_VALUES.len() {
            let smaller_unit_value = PSEUDO_PLACE_VALUES[smaller_unit_index];
            let smaller_unit_figure = PSEUDO_DIGITS[smaller_unit_index];

            if value - remaining <= smaller_unit_value {
                bildungsroman.push(smaller_unit_figure);
                bildungsroman.push(figure);
                remaining -= (value - smaller_unit_value);
            }
        }
    }
    bildungsroman
}

XXX II

// XXX: old_io is probably facing deprecation if names mean anything
#![feature(old_io)]
use std::old_io;
use std::collections::HashMap;

fn main() {
    let things_to_ask_about = ["name", "age", "username"];
    let mut collected_information = HashMap::new();
    for askable in things_to_ask_about.iter() {
        println!("What is your {}?", askable);
        let input = old_io::stdin()
            .read_line()
            .ok().expect("failure message here");
        // XXX EVIDENCE OF MY IMPENDING DEATH in these moments when I
        // want to scream with the righteous fury of a person who has
        // been genuinely wronged, on the topic of what the fuck is wrong
        // with this bullshit language where you can't even trim a string
        // because "`input` does not live long enough" this and "borrowed
        // value is only valid for the block suffix following statement 1
        // at 21:48" that
        //
        // But what the fuck is wrong with this bullshit language is in
        // the map, not the territory
        //
        // on the balance of available evidence, doesn't it seem more
        // likely that the borrow checker is smarter than you, or that
        // the persons who wrote the borrow checker are smarter than you?
        //
        // and if you can't even follow their work even after several
        // scattered hours of dutifully trying to RTFM, will an
        // increasingly competitive global Economy remain interested in
        // keeping you alive and happy in the decades to come?
        //
        // I am not a person who has been genuinely wronged, just a man
        // not smart enough to know any better
        collected_information.insert(askable, input.trim());
    }

    for (askable, response) in collected_information.iter() {
        println!("You claimed that your {} is {}.", askable, response);
    }
}

"Pi Day" Is an Unholy Festival of Sin That Is Corrupting Our Children

Dear reader, it's the fourteenth day of the third month of the year, and if you're reading this blog, some charlatans or overenthusiastic youth (the subject of whose enthusiasm is not what they think it is) have probably tried to convince you to celebrate it as "Pi Day." You see (these quacks implored you) π is around 3.14, and March fourteenth is 3/14. And furthermore (they may have put to you) furthermore this year's Pi Day is special, because it's 3/14/15, which is like 3.1415! Why (an especially impudent few might have continued to venture), we should plan some grand spectacle on 9:26 a.m. on the day, which is like 3.1415926! With (and this is the part that is most inevitable and offensive) pie! Get it, because it sounds like pi and is shaped like a circle?

Dear reader, it is lies or it is worse than lies; it is blasphemy, treason, superstitious superficiality, degenerate folderol, and frivolous depravity! Do not mistake me; of course I can see as clearly as any other ape can that the numeric subsequence of the string "3.14" is same as that of the string "3/14". The former string represents an occasionally useful approximation of the circle constant which is ubiquitous in mathematics (give or take a factor of two); the latter is how people in my country abbreviate today's date. Perhaps to those who don't have anything really interesting to think about, this trivial coincidence might be worth a passing mention; apes love anything for an innocent distraction, and why begrudge that?

Continue reading