An Algorithmic Lucidity

a blog

Tag: timely Special Event

Some Excuse for a RustConf 2017 Travelogue

(Previously, previously on An Algorithmic Lucidity.)

Wow, has it already been a year since last RustConf?—give or take the exact date of the event sliding a bit between years—and give a month-and-a-half of procrastination before being truly struck by the mounting realization that my opportunity to blog something about it before the opportunity expires has almost—but crucially, not quite—faded into oblivion. And a year-and-a-quarter since my first contribution to the compiler? I've recently moved into the top hundred contributors by commit count, because GitHub's contributors graph page only goes down to a hundred and my life is controlled by what things GitHub happens to provide graphs for.

So in the evening of Wednesday 15 August, I boarded the Amtrak Coast Starlight at Jack London Square station in Oakland for the long pilgrimage north to Portland to visit friend of the blog Sophia and attend this year's RustConf.

The train was nearly three hours late. (More like Slowest Starlight, am I right?)

On Thursday, I convened a Berkeley Slate Star Codex meetup in exile with Sophia and another local.

I don't think I was very well-prepared to take advantage of the conference itself this time around. I attended the Friday "advanced" training session, but the content was mostly the same as last year (I probably should have chosen the Tock session instead), and I don't actually own a laptop (I used "my" employer-owned laptop last year), and trying to make do with my accessorized phone and the playground was not an optimized experience.

Then the day of the conference itself, I overslept (and left my badge at Sophia's house), and had a high-neuroticism day induced by social-media drama that I had inflicted on myself the previous night, which distracted me from the content of the talks and the challenge of actually connecting with people on the hallway track (the most valuable part of any conference).

But, you know, there will be other conferences. Rust isn't going anywhere. And neither am I.

Except, you know, to Portland or wherever for the occasional conference.

Joined

(Previously on Star Trek: An Algorithmic Lucidity.)

The morning of Thursday the eighth, before heading off to see the new LCSW at the multi-specialty clinic, I was idly rereading some of the early Closetspace strips, trying to read between the lines (as it were) using the enhanced perception granted by the world-shattering insight about how everything I've cared about for the past fourteen years turns out to be related in unexpected and terrifying ways that I can't talk about because I don't want to lose my cushy psychology professorship at Northwestern University. (Victoria tells Carrie, "Not to mention you don't think like one of 'them'"; ha ha, I wonder what that means!) When I got to the part where Carrie chooses a Maj. Kira costume to wear to the sci-fi convention, it occured to me that in addition to having the exactly the right body type to cosplay Pearl from Obnoxious Bad Decision Child, I also have exactly the right body type to cosplay Jadzia Dax from Star Trek: Deep Space Nine, on account of my being tall—well, actually I'm an inch shorter than Terry Farrell—thin, white, and having a dark ponytail.

Okay, not exactly the right body type. You know what I mean.

So I ordered some cheapo Sciences-division uniform pajamas, thinking of going to some comics convention next year, but when I queried the Overmind in its gopher aspect for actual Star Trek conventions, it turned out that there was one that very weekend at the SFO Hyatt Regency (previously known to me as the host of the BABSCon My Little Pony: Friendship Is Magic convention). Online ticket sales had stopped, but allegedly "[a]vailable tickets [would] be on sale at the convention", and there was still time to upgrade my uniform order to one-day shipping.

The uniform I got (just the first suitable thing I found querying the Overmind in its Amazonian aspect; it would be possible to do better for more searching and money and shipping time) was problematic in that it's the TNG-era design and has commander's rank pips, whereas Jadzia was a lieutenant when she last wore a TNG-era uniform and (spoilers!) died in 2374 as a lieutenant commander. I considered trying to play a post-series Dax who actually faked her own death (and got Dr. Bashir to use an experimental technique to copy the Dax symbiont's memories to Ezri Tigan), then later got promoted to commander and assigned to a different post where they still wear the TNG-era uniforms for some reason. But I decided that it would be simpler to just cover the third pip with electrical tape and play Lt. Dax in 2369, just before her reassignment to Deep Space Nine. (Beyond body type, at 28, I'm even just the right age for this role, Jadzia having been born in 2341!)

(Aside: before considering the question of "who do I have the correct body type to cosplay", I had always thought that I liked/identified-with—my brain may not distinguish the two concepts as sharply as some do—Kira more than Dax, but that doesn't really make any sense: Dax, the cosmopolitan science officer whose ambition spans worlds and bodies, is far more like what I'm supposed to be than Kira, the ex-terrorist XO whose life has been structured by the struggle to defend her homeworld from Cardassian imperialism. Kira Nerys says that she trusts the wisdom of the Prophets; Jadzia Dax quietly wonders what those wormhole aliens are really up to.)

During the next few days, I watched "Soldiers of the Empire" (recommended as the best Dax episode by TrekBBS user "Bad Thoughts" in the at-the-time top search result for best dax episode returned by the Overmind in its gopher aspect) to help get into character and bought some cosmetics at Walgreens: Loréal 201 Classic Ivory "infallible pro-glow" SPF 15 foundation, Maybelline Line Stiletto "ultimate precision" liquid eyeliner (liquid eyeliner being recommended by Stephanie as the kind of makeup with which to draw Trill spots; thanks to friend of the blog Alicorn for the link), a Loréal Brunnette brow stylist definer pencil in case that turned out to be better than the eyeliner for drawing spots (it wasn't), and a stick of Maybelline 680 Mesmerizing Magenta lipstick.

(I couldn't find the liquid eyeliner myself and had to ask a store employee. She asked if there was any particular brand I wanted. "No," I said, just a eyelash hair too forcefully, "this isn't my usual area of expertise.")

So I got up early the morning of Sunday the eleventh, shaved, applied the makeup in my inexpert-would-almost-be-too-charitable way (smear on foundation, haphazardly dab eyeliner on sides of face to make Trill spots, waveringly bring lipstick to lips), put on a bra and my foam breastforms under the cheapo uniform top, and used my PADD to summon a taxi to Burlingame for the convention.

I arrived way too early for check-in, and walked up the road (wearing my black jacket over my uniform top) to the Mariott, which, unlike the Hyatt, has an outpost of the raktajino hegemon, and ordered a breakfast sandwich and the vanilla sweet-cream iced raktajino specialty medicinal. I gave my name as Jadzia, but the barista wrote Jetsy on the cup. (Maybe my voice was a little shaky, but maybe she needed to recalibrate her universal translator.)

A little bit of lipstick rubbed off on the sandwich and the straw.

I waited in the Hyatt lobby for a while, still with the jacket over my uniform, reading the Janet Mock autobiography on my PADD, until it was time to check in. After buying my Sunday wristband ($70), I wandered over to the photo-op/autograph ticketing table and bought a ticket to get a photo with Michael Dorn at 11:10 ($40). (Nana Visitor or Terry Farrell herself would have been my first choices for a celebrity photo, but they weren't there that day.)

There was still a lot of time to hang out before the theater opened for the actual convention programming, but that was fine, because actual convention programming is kind of boring; the actual point of conventions is to have an excuse to dress up and wander around and talk to people and get vanity photos of other people who are using the convention as an excuse to dress up.

A woman in the vendor hall asked me how I did my spots.

"This is my natural skin pigmentation," I said.

"Oh," she said, confused.

I leaned towards her and said in a conspiratorial whisper, "I'm not supposed to break character today! It's liquid eyeliner."

One man was wearing a particularly impressive Klingon costume. "I think I recognize you!" I said, stopping him. "I think Curzon knew you!"

"Curzon?"

"My previous host," I explained. "Can we get a photo?"

He seemed to regard me with bemused toleration as we posed for a selfie taken with my PADD.

"Those real?" he asked, referring to my breasts.

"No, I'm actually a guy," I said. "Obviously."

"I know," he said.

I sat through some actual convention programming. John de Lancie is almost as entertaining playing himself as he is as Q or Discord. In response to a question from an aspiring actor, de Lancie said that TV and movie acting is all about what you can do now, in contrast to theater, where young talent can be afforded time to develop under the tutelage of a director. He mentioned that Alarak, the character he voice-acted for Starcraft, was angry all the time, and that he imagined there should be a scene featuring Alarak relaxing by painting watercolor. He told the story (which I had already heard before, probably at BABSCon) of voicing Discord for Friendship Is Magic with minimal preparation and forgetting about the matter entirely until some months later, when he woke up to see his inbox exploding with fan mail for his part in something called "My Little Pony" ... and the correspondents were not little girls.

After de Lancie, there was a discussion with some writer-folk (the schedule said the topic would be the new series next year, but they didn't seem to know anything about it), and soon enough, it was time for my photo op with Michael Dorn.

The photo session was very assembly-line—here (unlike the autograph sessions I witnessed at other conventions) there was no pretense of your $40 giving you the opportunity to actually meet your heroes for even half a minute: this was pose, click, and it's over, time for the next fan to get in position. I had time to say to Dorn, "I'm Jadzia," but that was it.

Not that I was disappointed. A woman on the event staff commented on how happy I looked skipping down the room after the photo was taken. "My future husband!" I said.

"You're so cute," she said.

I appreciated that. On the whole, however, I feel like I was less enthusiastically received as Jadzia that day than I had been as Pearl at San Francisco Comic-Con—providing what could be seen as a disconfirmatory data point against my hypothesis that incompetent MtF crossdressing gets socially-rewarded more than same-sex cosplay (cisplay??) at these sorts of events. There are too many uncontrolled variables to make a fair comparison—this was a different (I think better) costume, of a different character, in front of a different (notably smaller, possibly older?) crowd—but a darker, more specific hypothesis comes to mind.

As Pearl at Comic-Con, no matter what catchphrases I shouted during photo ops, I read as "unapologetic man-in-a-dress not pretending to be anything else," which is cool faux-subversive gender variance. (So brave! Man Pearl is best Pearl!) Whereas Starfleet uniforms are properly unisex: the only gender cues indicating that I was trying to be Jadzia Dax rather than a male Trill lieutenant were my breastforms, the lipstick (a much weaker cue), and the foundation hopefully hiding any residual beard-shadow (a weaker cue still). That put me out of the "man merely wearing clothes reserved for the other sex" category and into "man ineffectually pretending to be a woman" territory.

Maybe that's not cool. Maybe that's just creepy to some people. Even at a science-fiction convention in the Bay Area. (Even if people in the Bay Area are not dumb enough to say what they're really thinking.) I didn't see any other crossplayers at the Star Trek con, and the only other highly visible MtF crossplayers I saw at Comic-Con were the guys with beards wearing Sailor Moon outfits (and as for the people I thought I clocked on the ten-second timescale, who can say?—maybe they were real).

I want to be able to say with the unquestioning moral certitude of my youth that none of this should matter, that distinguishing "crossplay" from cosplaying a character that happens to be the same sex as you is discriminatory (and therefore, it need not be said, bad). I chose to play a character that I genuinely admire, and because this character happened to be a woman, I decided to wear the breastforms that I coincidentally happened to already own, in order to make the costume more realistic (given that I am a man and, unlike Jadzia Dax, don't have breasts), in exactly the same way that because this character happened to be a Trill, I decided to paint spots on the sides of my face using liquid eyeliner that I happened to not already own, in order to make the costume more realistic (given that I am a human and, unlike Jadzia Dax, don't have spots on the sides of my face).

I want to say it. I miss that righteous feeling of my youth. But in these dying autumn weeks following that moment of liberating clarity, I am done pretending to be stupid. And maybe I don't want you to pretend, either.

RustConf 2016 Travelogue

(Previously on An Algorithmic Lucidity.)

sfo_reflections

The other weekend, excited to learn more and connect with people about what's going on at the forefront of expressive, performant, data-race-free computing—and eager for a healthy diversion from the last two months of agonizing delirium induced by the world-shattering insight about how everything I've cared about for the past fourteen years turns out to be related in unexpected and terrifying ways that I can't talk about for reasons that I also can't talk about—I took Friday off from my dayjob and caught a Thursday night flight out of SFO to exotic Portland (... I, um, don't travel much) for RustConf!

The conference itself was on Saturday, but Friday featured special training sessions run by members of the Rust core team! I was registered for Niko Matsakis's afternoon session on lifetimes, but I arrived at the venue (the Luxury Collection Nines Hotel) early to get registered (I had never seen socks as conference swag before!) and hang out with folks and get a little bit of coding done: my coolest Rust project so far is a chess engine that I wrote this time last year (feel free to go ahead and give it a Star!) which I wanted the option to show off (Option<ShowOff>) to other conference attendees, but the pretty web application frontend had broken due to a recent bug and my JavaScript build pipeline having rotted. I fixed it just in time for the lifetimes training session to start.

Every reference (I kind of want to say ampersand) in Rust code has an associated lifetime, the region of the program that that reference is valid for. Lifetime annotations (appearing in angle brackets like generics and starting with an apostrophe; by convention, usually named consecutively from the start of the lowercase Latin alphabet: 'a, 'b, &c.) in function signatures are used to distinguish between the lifetimes of different reference arguments, but the compiler has lifetime ellision rules that cover the 90% use-cases, so you can actually write pretty substantial Rust programs without actually understanding the theory, which is both practically useful and eternally shameful (for a programmer who is satisfied with not understanding something is not long for this world). Hence the training. (Exercises from the training sessions are available online.)

rustconf_swag

The point of lifetime analysis is to ensure that all references point somewhere valid; you can't (can't, the compiler won't let you) have a reference to a thing that outlives the thing itself. When you return a reference from a function, you can't be referencing something created by that function, because any such thing would die at the end of the function as it goes out of scope: a reference in the return type has to be a reference to something owned by the caller that was passed as an argument, but if there was more than one reference argument, it's ambiguous which of the reference arguments has to be outlived by the returned reference, which is why you sometimes need explicit lifetime annotations ...

Um, it's complicated. (Maybe this is just one of those things no one knows how to teach, and you just have to pick it up by osmosis or spend a week auditing the relevant part of the compiler source??)

Lifetimes are currently bound to lexical scopes, which are sometimes much bigger than we actually want, bigger than we could get away with if the compiler was smarter, so sometimes the borrow checker will reject code that a human can see is actually safe. Borrowing is like a compile-time readers-writer lock; you can have many readers or at most one writer at the same time. Consequently, when running into a spurious ("spurious") borrow checker error, Matsakis recommends separating your code into distinct query and act operations. The result of the query must not be a reference into the thing you're operating on (that would be holding the reader lock!) but it can be a value, or an index into the thing that you use as a kind of pseudo-reference. (I was reminded of how I was looking up how to implement graphs back in March because I wanted to implement Bayes nets and someone recommended using indices into a Vec as pseudo-references, but I thought that was hideous, so I ended up using Rc and RefCell sort of like in Nick Cameron's tutorial.)

There were a couple of pre-conf community events scheduled for Friday night: a Chef/Habitat meetup, and a hack night for the new Tokio async IO project. I decided to only go to the hack night and wander around downtown Portland for the few hours after the lifetimes session and before the hack night. Some people were protesting prison labor practices at an AT&T store. On a whim, I visited the famous Powell's City of Books—it's very large and has rooms mostly named after colors!—the math section is in the Pearl room! On a further whim, I bought a book! You can't prove that the book isn't completely unrelated to the world-shattering insight that has been eating my life for two months! Then it was time to hack on Tokio ("... I'm on my way; in my brand new auto, it's not so far away").

So, I don't really understand Tokio. I think it's supposed to provide a new, better high-level async IO story for Rust? After procuring some help from the knowledgable hackers around me ("Cargo sucks! ... just getting your attention"), I was at least able to run some example code (there were some dependency problems), and I submitted a pull request suggesting that the appropriate cargo run --example command be mentioned in the README. Out of despair and determination to get something nontrivial done at hack night, I submitted a pull request for vector iteration to rulinalg, the linear-algebra library that I was already familiar with from having contributed to its code before it got pulled out of rusty-machine. (My pull request has some lifetime annotations in it, but even after the afternoon's training, I still felt like I was just imitating examples and slapping tick-a on things.)

The next day was the actual conference! I got to meet my hero Julia Evans and she gave me a paper (!) zine.

Matsakis and Aaron Turon gave the opening keynote on the remarkable year Rust has had: 175 new features have been stablized, and we have more exciting new features on nightly, like specialization, impl Trait, ?, custom derive, and (now shining brightly in orbit) MIR.

There were some technical difficulties getting the projectors hooked up to the laptop for the next talk. Steve Klabnik said that the break was brought to us by Apple, who is not sponsoring us, but really wants us to have a long break between talks. "They should have written it in Rust!" I shouted (as if someone had to say it); Steve shrugged.

compiler_says_no

The projector issue got fixed and Liz Baille, developer at Tilde and graphic-novelist, gave a really funny talk in the form of an "illustrated adventure guide" to Rust ("You might have noticed how clean and beautiful Rustlandia is, and you might have also noticed that there are no garbage cans anywhere").

Geoffroy Couprie spoke about getting Rust code into the VLC media player: rewriting existing C code is hard, he says, but it's doable in Rust today.

Suchin Gururangan and Colin O'Brien spoke about a machine-learning classifier that they built to detect posts about the Rust video game that were erroneously posted to our /r/rust subreddit instead of /r/PlayRust. ("Ability to copy/duplicate maps" was a cute example of a post title the classifier wasn't very confident about—maps could be game maps or hashmaps!)

Without Boats is working on notty, a new terminal that aims to improve on the reigning standards (much of which ossified in the days of line printers) with better Unicode support and the ability to display images. Boats says that notty uses many more traits than is usual for the Rust ecosystem. For example, consider a write method for writing something into a terminal's grid, which could either be a normal character, an extra-wide character, a combining modifier character, or an image. The original, intuitive solution was for write to take an enum (with variants Char, WideChar, CharModifier, and Image) that matches on the thing being written, but that was problematic because the method quickly became enormous, and each kind of data had to take a &mut reference to the struct representing the entire grid. Whereas after a refactoring, there is instead a Writer trait that gets implemented each type of writable thing. Boats followed up with a case study about separating a terminal into panels ("Let's say you're using a text editor like Vim, or the other one") and finished with an exhortation to "MAKE RUST TRAIT AGAIN".

Alex Crichton gave a talk titled "Back to the Fututes". Maybe I don't have much to say about this one for the same reason I didn't get much done at the Tokio hack night??

Raph Levien gave a talk about Xi, a modern editor dedicated to being performant (as operationalized by never blocking). It uses ropes and the fact that strings under concatenation are a monoid. Levien says that regex-based highlighting is not the future because actual lexing is faster, and that people should stop sneering at him for using JSON-RPC, which is really well-optimized and readily available ("You talk about batteries included; this is a AA battery, not a CR123A").

Josh Triplett gave a talk about what he learned about the Rust RFC process in the course of adding untagged unions (and the hope that they provide) to the language. There was a bit of feedback from the sound systems as Triplett began to speak about the application that motivated his interest in Rust: virtual machines, which are used for containment and isolation ("which would be useful in audio systems as well"—laughter from the audience). Buffer overflows were written about in 1972, first exploited in the wild in 1988, and we're still talking about them in 2016. Rust is interesting because it's actually a credible replacement for C++. Tagged unions (we call them enums) are ubiquitous in Rust, but it's useful to have untagged unions for interfacing with C code that uses them; currently, you need an unsafe block and nasty things like mem::transmute to deal with C unions, and we'd prefer to have a safe construct for this. Unfortunately, Rust's backwards-compatibility guarantees mean we can't strictly use union as a keyword, because there could be existing code that uses it as a variable binding. But it turns out that it's possible to make the parser smart enough to recognize union as a "contextual keyword": we can use it like a keyword because its position in the syntax tree is sufficient to distinguish it from union being used as a variable. The discussion threads on RFCs can get kind of unwieldy, so people make summary posts that describe the state of the debate so far. Implementation isn't part of the RFC process (although it can happen in parallel, with the understanding that the RFC can change); a tracking issue for implementation is opened when the RFC is approved. Untagged unions are now available in Nightly Rust behind a feature flag!

Finally, Julia Evans gave a talk on "Learning Systems Programming With Rust" and how Rust makes improbable programs possible (you could write correct C, but you won't).

And that was RustConf! The next day, since my flight wasn't until evening, I also walked across some kind of bridge and visited PDX Maker Faire since I happened to be in town and someone I met on the internet was there to show off this duplicate of a set piece from the Stranger Things television series that they made with an Arduino.

My flight back to SFO was delayed a few hours due to some sort of technical difficulties in Chicago. As I sat waiting at the gate, beginning to draft this post and trying not to let my soul be consumed by the world-shattering abyss induced by cruel apprehension of patterns that innocents were not meant to see, I felt a deep sense of gratitude that I should have the privilege to participate in such a brilliant, welcoming community as that which surrounds the Rust programming language and its mission to bring systems programming to the masses in this 21st century!

Is There Affirmative Action for Incompetent Crossplay?

So I was at San Francisco Comic Con the other day. I don't think I find conventions themselves to be as fun as a lot of other people seem to (I didn't even last all of Saturday at BABSCon 'fourteen and 'fifteen before getting ponied out and BARTing home, and didn't even bother attending this year), but I had never cosplayed before, and had been thinking lately that I have exactly the right body type to play Pearl from Obnoxious Bad Decision Chil—I mean, Steven Universe, on account of being my being tall, thin, white, and having a big nose. (She's even pretty flat-chested!) So I ordered the Pearl dress from Hot Topic (I maybe should've gotten the XXXL instead of merely the XXL), a pink (really should be more peach, but close enough) wig, yellow gym shorts, and pink socks; improvised a gem from medical tape and the bowl of a plastic spoon; and set off Saturday morning to catch the train to the city and a short walk to the San Francisco Marriot Marquis.

The con itself was about what you'd expect, with the usual events and the usual vendor hall. The part that I found striking (enough so that I'm bothering to blog about it) was just how many compliments and photo requests I got for my costume, wholly disproportionate to its actual quality. (I enjoyed the opportunity to ham it up, proclaiming "We are the Crystal Gems!" or singing a few bars from the extended theme during photo ops.) Since this was my first time cosplaying, I don't have calibration, so it's quite possible that I got the ordinary amount of positive attention given costume quality and character popularity, but I suspect that there was something more than that going on having to do with gendered cultural expectations.

Femininity in males is stigmatized more than masculinity in females; that's why I changed in the bathroom at the con rather than wear a dress on the train, and why I don't feel like including any photos in this post despite having shared them on Facebook (visibility settings: "Custom: Friends; Except: Family") and sent them in for the next Beach City Bugle cosplay compilation post. So incompetent MtF crossdressing is "loud" relative to men playing male characters, women playing anyone, and the competent crossdressers (who were clockable on the timescale of ten seconds, but didn't instantly read as "man in a dress" the way I did), and loud things that would be stigmatized in everyday life (probably even everyday life in the Bay Area) are celebrated at Comic Con. Thus, "man Pearl is best Pearl," as I was told by a young woman (who was cosplaying a male character), even after I insistently pointed out that the other Pearl was way better than me.

Mirage

(just some quick notes, hopefully in the spirit of delightfully quirky symmetry-breaking)

In her little 2010 book The Mirage of a Space Between Nature and Nurture, Evelyn Fox Keller examines some of the eternal conceptual confusions surrounding the perennially popular nature/nurture question. Like, it's both, and everyone knows it's both, so why can't the discourse move on to more interesting and well-specified questions? That the oppositional form of the question isn't well-specified can be easily seen just from simple thought experiments. One such from the book: if one person has PKU, a high-phenylalanine diet, and a low IQ, and another person doesn't have PKU, eats a low-phenylalanine diet, and has a normal IQ, we can't attribute the IQ difference to either diet or genetics alone; the question dissolves once you understand the causal mechanism. Keller argues that the very idea of distinguishing heredity and environment as distinct, separable, exclusive alternatives whose relative contributions can be compared is a historically recent one that we can probably blame on Francis Galton.

The "Bay Area" was ostensibly hosting the big game this year. They blocked off a big swath around the Embarcadero this last week to put on Super Bowl City, "a free-to-the-public fan village [...] with activities, concerts, and more." I really don't see how much sense this makes, given that the actual game was 45 miles away in Santa Clara, just as I don't think we (can I still say we if I only work in the city?) really have a football team anymore; I like to imagine someone just forgot to rename them the Santa Clara 49ers. Even you don't think Santa Clara is big enough to be a real city—and it's bigger than Green Bay—then why not San Jose, which is a lot closer? I think I would forgive it if the marketers had at least taken advantage of the golden (sic) opportunity to flaunt the single-"digit" Roman numeral L (so graceful! so succinct!), but for some dumb reason they went Arabic this year and called it Super Bowl 50. Anyway, on a whim, I toured through Super Bowl City after work on Friday. It was as boring as it was packed, and it was packed. I wasn't sure if my whimsy was worth waiting in the throng of people to get in the obvious entrance on Market Street (the metal-detection security theater really took its toll on throughput), but I happened to hear a docent shouting that there was a less-crowded entrance if you went around and took a left each on Beale and Mission, so I did that. There were attractions, I guess?—if you could call them that. There were rooms with corporate exhibits, and an enormous line to try some be-the-quarterback VR game, and loud recorded music, and a stage with live music, and an empty stage where TV broadcasts would presumably be filmed later. There was a big statue of a football made out of cut-up beer cans near one of the stands where they were selling beer for $8, which sounded really expensive to me, although admittedly I don't have much of a sense for how much beer normally costs. In summary, I didn't see the appeal of the "fan village," although I do understand what it feels like to be enthusiastic about the game itself—I really do, even if I haven't been paying much attention in recent years.

Even when it doesn't make sense to talk about nature and nurture as separable components of the cause of a trait in an individual, Keller emphasizes that we often can say things about how differences in genetics or environment relate to differences in traits in a population. This is a pretty standard disclaimer in behavioral genetics: heritability is a technical term about how variation in genotypes relates to variation in phenotypes; it's not a catch-all notion of "geneticness," and it depends on the population and environment studied; most of the variation in the trait "number of hands" is due to horrible accidents, which are "nurture" (well ... you know what I mean), so the heritability (proportion of variation associated with variation in genotypes) is near-zero, but we don't want to say that humans having two hands has nothing to do with human genetics. Keller thinks that a lot of behavioral geneticists end up performing a motte-and-bailey maneuver here, falling back to the technical definition when questioned, but casually letting tinges of the everyday understanding of the word heritable slip in to the discourse—and that we probably can't just blame Jay Laurence Lush for not having chosen a different word in 1936.

I didn't watch much of the game. The few plays I did see looked bad for the Panthers. Cam Newton was sacked from behind a few yards from his own goal line and the Broncos recovered it for a touchdown. Later there was this play where one of the Broncos intercepted a pass and then fumbled it on the return, but another Broncos player recovered it.

Keller argues that a better question to ask than "nature vs. nurture" would be: to what extent are particular traits malleable during which developmental phases? By contrasting prenatal "nature" (that one was "born this way") and postnatal "nurture", many overlook that birth is not the only developmental milestone! But whatever constellation of forces turns out to truly shape who we are today and what we will become tomorrow, we can never escape the truth of what happened yesterday, the irrevocable verdict: Denver 24, Carolina 10.

Ideas Have Expirations

One often-overlooked aspect of the crime of not-writing is that the harm isn't just about the things that deserve to be said that you never get around to saying because you don't put in the time and effort. It's also about the things that you can't say anymore even if you suddenly had the will, because the opportunity to say it was bound to a particular time, and trying to recapitulate the thoughts months or years after the fact would be irrelevant, or impossible.

This phenomenon comes in degrees. Start with irrelevance. Often the inadmissibility of tardy words isn't absolute: you could say things late, but the product would be less valuable than if it were timely—especially in a medium like blogging, where the posts being dated and displayed reverse-chronologically creates an expectation that the entries are associated with a particular point in time—at least, that they were written not too long before their publication date, even if the actual content isn't about the ephemera of the day or season. This has contributed to An Algorithmic Lucidity not being as good of a blog as it could be.

BABSCon swag

Like—each of the last two Aprils, I attended (one day of) BABSCon, the San Francisco Bay Area's premier convention for fans of the animated series My Little Pony: Friendship Is Magic, both times—even the second!—with the thought that the experience would make good fodder for a blog post in the "autobiographical account of my day at this timely Special Event" genre. I was going to tell you about how the first time, I made a couple of social faux pas while meeting Tara Strong and Nicole Oliver, only one of which was intentional; I was going to tell you about how the second time, I hadn't been planning to buy anything in vendor hall, but couldn't help but say "Shut up and take my money" in response to the demonstration of the Twilight Sparkle's Secret Shipfic Folder card game, the game-opening card of which I later got autographed by both members of Sherclop Pones, whose Friendship Is Witchcraft fandub series had clearly inspired some of the cards and probably the game itself, as well as being the source of some of my favorite music. I was going to tell you about how the first time, I was considering buying a coffee cup depicting the Mane Six (because I frequently bought medicinals at the outpost of the American coffee hegemon, and felt guilty about the wastefulness of accepting the default disposable cup every time like every other American), but hesitated, explaining to the vendor that I wasn't sure whether I wanted to use that cup in public, whereupon she said she could throw in a free button, to which I replied, "Sold!" And I was going to do a careful sociological analysis of curious observations like how I hesitated to buy that cup and why H. liked it so much in terms of gender ideology and signaling contrarianism.

But I didn't, and those Aprils were nine and twenty-one months ago, respectively. Not timely. My being motivated to write now ("That my past does not define me, 'cause my past is not today") can push a 350-word counterfactual "postview" of what I thought about saying over the threshold into existence, but it would be a bit unseemly to try to construct (I almost wrote reconstruct, but the re- prefix should be reserved for things that ever existed in the first place) a 2000-word personal account of the timely Special Event that happened last year or the year before that.

Leafline web client play

Or like—I made a thing not too long ago. I didn't mean to. It was an accident, really. It's a sort of oppositional strategy game engine—like a board game you play against the computer. The core move-scoring application is written in Rust, but there's also a web-application GUI (the "web client") in Clojure and ECMAScript 6 that's much more ergonomic for playing a game against. The game is—okay, well, it's chess: the endeavor snowballed out of my desire to participate in my coworkers' friendly office chess games combined with my reluctance to spend effort learning to be good at a task whose essential nature is so obviously suitable for automation. But writing a chess engine is just so cliché, and I enjoy naming things, so I quickly settled upon the conceit that actually I was writing an engine for a game that just happened to be exactly like chess, except that everything has different names: for example, instead of the pieces being black and white pawn, knight, bishop, rook, queen, and king, the figurines, or agents (never "pieces"), in my game are blue and orange servant, pony, scholar, cop, princess, and figurehead. (I kept rank and file, though.) This "adorable idiosyncratic names for everything" convention permeates the codebase. Despite the fact that unnecessarily gendering things isn't normally my style, I decided that ponies, scholars, and (inevitably) princesses were female, and that servants, cops, and figureheads were male, specifically in order to have an excuse to leave // ♀ and // ♂ comments in the enum declaration, because I feel like too many of my code comments are restricted to the ASCII or maybe Latin-1 subsets of the Basic Multilingual Plane, such that I don't want to pass up an opportunity to legitimately ("legitimately") use \u2640 FEMALE SIGN and \u2642 MALE SIGN. There are comments with ludicrous rationalizations for using the standard Forsyth–Edwards notation abbreviations ('P' is for peon, 'N' is for neigh, 'B' is for book, 'R' is for the Rule of law; the blue team's runes are lowercase because lowercase characters have higher ASCII codepoints, just as blue light has a higher frequency than orange light). Instead of pawn promotion, it's servant ascension, and a different verb is used to describe the process depending on the target figurine type (the servant moving the to the final rank can transform into a pony, be brevetted to cop, or transition into a princess or scholar). Or, like, Rust is quite conservative in the Yeggean sense, as manifested in features like the compiler forcing you to explicitly handle all possible variants of an enum; in cases where you know an instance of the enum can only be one of a strict subset of the possible variants, but the type system doesn't know that, you have to fill in those branches or supply a default case anyway, probably with a panic, which is like an exception that you can't catch, to abort the program with a message indicating that something entirely unanticipated has happened and it makes no sense to carry on. So I had been ending all of my panic messages with a stock phrase about how the unexpected thing was contrary to the operation of the moral law ("non-princesslike agent passed to princesslike\_lookahead, which is contrary to the operation of the moral law", and so forth), because this isn't the kind of codebase where you just say something like "assertion failed," as if the program should die because of some human authority's mere assertion, rather than only as a matter of justice when its behavior is contrary to the operation of the moral law. And then when my coworker Alexander Corwin started contributing, he abstracted away the boilerplate in these panic messages into this moral_panic! macro, which I thought was brilliant.

The web client is configured to run on port 2882. It's easy to remember because 2882 is Magnus Carlsen's peak ELO score.

Leafline console play

Software, like poetry, is never really finished (only abandoned), but getting the project to the point that I felt it was a minimal viable "product" took about eight glorious weekends (plus a few weekday nights, and with some help from Alexander). Near the end, watching the program utterly trounce me in web client play and feeling for all the world like a lieutenant junior grade, I started looking ahead to what came next for me. Over the past two years, the first two years of my life (that I feel comfortable admitting to), I had spent many, many night and weekend hours hacking on various side projects and coding exercises out of genuine enthusiasm and curiosity and desire to improve my craft—and, honestly, a feeling of insecurity, sensing that I needed to prove my worth as a hacker ("I threw myself into my studies, to have the world in my control"). But decent chess AI in Rust as an impulsive throwaway project seemed like a sufficiently strong signal of my programming prowess that maybe it was time to tie off this project, write the obligatory exciting blog post about it, and start allocating night and weekend hours towards some of the non-programming (!) interests I remember having in the before-time (assuming those memories are not fake). I could do some math! Write some fiction! Maybe even meet new friends ("I will not be shy; I'm going to try; I bet I'll find the reason why so many people, like me—")?!—all while feeling secure in the knowledge that my technology skills are clearly adequate for my continued existence to be economically viable. (For now.)

So ... about that end-of-project blog post. I was going to title it "Project Review: Leafline version 0.0.14-MVP; or, Lessons From Writing an It's-Not-Chess Engine in Eight Weekends", and I was going to explain everything to you—not just the silly names for everything that inexplicably amuse me (and only me), but the actually interesting substantive technical details of the implementation. Not that the AI is anything special—it's just textbook minimax search (in the negamax style) with α–β pruning and a position-evaluator that mostly counts material but also has bonuses for things like having both scholars or ponies and servants being in the center sixteen squares, plus a transposition (hash)table to look up scores of game-states it's already seen before, and another hashtable for history-heuristic move ordering. It's multithreaded, to take advantage of multiple cores (although I confess that the specific threading strategy is kind of a questionable hack). It can search up to 7 plies if you have a decent machine and are willing to wait ten or twenty minutes for the answer.

But even if it's nothing special, I was going to tell you about all the deeply moving philosophical insights I got from doing it. It's one thing to know how to refute the classic anti-AI argument (or straw person) that "humans couldn't possibly build something smarter than themselves by definition," but it's another thing to have the personal experience of having written something smarter than yourself in some particular domain, to the extent of feeling an acute sensation of futility while playtesting it, thinking: I've already coded my understanding of what it means to be good at this game; obviously I'm not going to do any better thinking about it with my slow meat-brain. (Although this is partially explained by my knowing almost nothing about chess strategy that I didn't learn in the course of this project; I've seen one of my coworkers beat the program at 4-ply search very quickly.) I was going to explain to you how α–β pruning works, with hand-drawn diagrams, and how you can interpret it as disregarding possible worlds that are too good or too terrible to be true (given rational play on both sides). I was going to tell you about the exciting surprise where the program seems to behave as if it understands the concepts of pinning and forking, even though those ideas aren't represented anywhere in the code!—but that when you think about it, that shouldn't actually be surprising: to the extent that we think pinning an opposing piece is a good idea that will lead to us picking up material, then pins should naturally appear in the results of searching the game tree for moves that are predicted to pick up material. And the reason we search for game-states where we hold a material advantage is because we expect that we're more likely to mate from those positions (in future nodes beyond our current planning horizon). Things that are, in all philosophical strictness, mere instrumental values, might profitably be treated as if they were terminal values by some algorithm that can't see far enough ahead to the actual goal, and this is a quantitative phenomenon: the shorter your lookahead, the more you want to rely on near-term approximating rewards. That's why I threw in a bonus for servants advancing to far ranks; I suspected that the existing code searching at the not-greater-than-7 plies that it could get in a reasonable amount of time, wouldn't adequately appreciate the true value of servant ascension, even though I expect that value would be naturally emergent in a deeper search, just as the value of some forks and pins emerged from mere 4- or 5-ply searches. (This was just a suspicion, though; I didn't take the time to actually test ascension-seeking behavior.)

So—though I've managed to just now haphazardly summarize some of the things about this project, this isn't really a careful project-review post. And now the distance between today and 27 September's 0.0.14-MVP tag is longer than that between that tag and the start of the project. And I ended up making a few more commits in subsequent weeks. So, no longer timely, at least not the way I originally imagined publishing a grand just-finished-project review post as a symbolic milestone marking a transition in how I'm going to start spending my precious non-dayjob time.

Or like—in late October, I saw the recent Jem and the Holograms film, because the previews (accurately) made it look like it was going to be really bad, and I thought I'd write a post combining a negative review of the new film with praise for the original Jem cartoon that this awful film mendaciously desecrated the name of. And then ... I didn't get around to finishing the post. Maybe my notes and memory from that night at the theater are accurate enough such that it's not too late—but the potential impact departed with the timeliness; I can't warn you not to go see it, because it's not in theaters anymore. (And good riddance.)

But beyond these sad cases of ideas that didn't get written up properly while they were still maximally relevant, there's an even worse way to fail to communicate, which is when the would-have-been-author has changed so much since first having the idea, that there's no way they could plausibly do justice to the idea as it was first had. You can't write a Diary entry about the day five years ago that you don't remember, and—more poignantly—you can't write a grand ideologically-driven novel in favor of the ideas you don't believe anymore. Some would argue it's just as well—if it's something you wouldn't write and couldn't stand by today, aren't you relieved that it doesn't exist to sully the name that represents who you are today? Even so, I would still favor intertemporal solidarity among past and future selves against the common enemy of our illiteracy.

Yes, illiteracy! Some would call it writer's block, but I know better than to bother with the unobservable distinction—whether you choose to describe your hypothesis as "doesn't write because unmotivated" or "doesn't write because doesn't know how," the result is the same: death of the non-author's memetic lineage.

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.

And it's all fake. A child's world of rounded edges and plastic safety guards. The laws of nature wouldn't permit it to exist on its own. The old legends are true; you can't just create objects without space to put them in. But space has to be allocated, managed. Those who are brave and wise enough to study the ancient lore know how even our simplest thoughts, like setting a key in a dictionary or __init__alizing an instance of a class, are really implemented in some sort of nest of pointers traversing pointers in the underworld. I don't want to stay in my hometown forever; I want to follow the heroine's path and probe the true secrets of the underworld, to wield the virtues of our ancestors and summon the strength to lift worlds. But my wording is deliberate: the virtues of the ancestors, but not necessarily their tools. Even the greatest among us are prone to mistype or misthink; the legends tell us of lives and worlds destroyed by buffers overrun, or by trying to occupy space after the counterspell to disperse it has been cast. Lately, I had been hearing rumors of a new lore, one that grants access to the underworld and its unfathomable performance, while maintaining protective wards to shield casters from most of the inherent dangers. I had already experimented with it for a few toy programs (and used it as a bad compiler target); I made pilgrimage to the camp to learn more.

Or at least, to be inspired to more. That's most of my answer to the rest of the "Why RustCamp?" question. I'm skeptical that anyone actually learns much at conferences (lectures are notoriously less efficient than text, and mere reading needs to be combined with many, many hours of hacking to produce true skill), but getting together with people, attentively listening to them yap on stage, and mingling with the crowd during breaks, provides pointers to things to read and hack on later in addition to serving certain human social needs, giving one the strength to carry on trying to better one's mastery of one's chosen profession, even through the persistent suspicion that it none of it helps, that the young programmer's vaunted "passion" is all vanity and empty signaling that will soon be destroyed by the realization that your code doesn't really change users' lives in any appreciable way, and no one cares how smart you are. (Enjoy Arby's.)

I felt lucky that the event happened to be on my side of the bay, in Berkeley, given that the trains to the city were 503ing this weekend on account of scheduled downtime for essential security patches. On the walk from Downtown Berkeley station, I stopped at one of the outposts of the rival power to buy a specialty medicinal and a scone. I usually go to the American coffee hegemon, but the rival power has this this newish specialty medicinal, an iced-coffee with one-and-a-half kinds each of cream and sweetener, that, having tried it for the first time the day before, I privately think beats anything in the hegemon's arsenal.

I made my way to the event venue and checked in, receiving a pretty badge and the obligatory swag bag containing an event-logo tee, a tee with a clever functional-programming-dragon design on the front and a sponsor logo on the back, bottled water (which is ridiculous), a Wi-Fi password (I hadn't bought my laptop), and stickers (I almost never use stickers). I am illustrating this post with a photo of the badge and dragon tee because I forgot to bring a camera to take pictures at the conference itself, and—lest the reader object that only die-hard photography fanatics have dedicated cameras nowadays—I don't have a real phone. (I'm into technology, just not necessarily consumer technology. Maybe I'll upgrade when the Ubuntu phone goes on sale in the U.S., but likely not even then.)

I was mildly surprised at the number of familiar-to-me faces in attendance (from my native subculture, or indeed more specifically from the party on Thursday, or from non-Rust programming scenes), but I guess this shouldn't be surprising on anthropic grounds. I speculated that there would be a lot of relative newbies (like me) at this event as contrasted to a conference for a more established technology—more people come to RustCamp because they want to check out the hot up-and-coming new language than because they've been doing it at their dayjob for five years. (During post-registration mingling, someone mentioned wanting something like Haskell's Maybe types, and I said, "I think we call it Option around here.")

The talks were in a big room with a bunch of circular tables (the tables were also mildly surprising to me; I guess I had been expecting rows of chairs, but no doubt it's better for laptops to not literally have to rest atop laps).

First, Aaron Turon and Niko Matsakis gave a keynote (PDF) about how far Rust has come and what remains to be done on the timescale of a year or so. They mentioned that there's a tool called Crater that tests a build of the Rust compiler against the packages on crates.io, to detect regressions with respect to how people are actually writing Rust in the wild. And the 1.0.0 API stability guarantee certainly doesn't mean there's not a lot of work left to do on the compiler. Apparently, as of now, rustc builds a big AST of your entire crate and hands that off to LLVM, which can lead to disappointingly slow compile times for large crates, but people are working on a more modular "middle intermediate representation" that will allow fast, incremental compilation at the level of individual functions. There's also work on making the borrow checker less dumb (in the matter of rejecting perfectly good code that it doesn't yet know how to prove is safe), and IDE support ("It's come to my attention that some people are not satisfied with Emacs"). In the gap after the keynote but before the first non-keynote presentation, I had a good conversation about cartoons with a fellow attendee.

Alexis Beingessner gave a really informative talk that the program called "Who Owns This Stream of Data?", but which the slides called "OMG ITERATORS". Beingessner's presentation style seems to be characterized by a kind of affectedly enthusiastic Buffy Speak that I can't quite bring myself to criticize, but only because I expect people would say similar (though not identical) things about my writing. In the toy Rust programs I've written so far, I've gotten used to calling .iter() on a vector in order to iterate over it in a for loop. This is a part of Rust's Iterator trait, implementations of which have to provide a next function that returns an Option of the type you're iterating over. (It's just like Python, except that in Python the method names have double underscores around them, for implicitly calls .__iter__() for you, and we raise StopIteration instead of returning the None alternative of an Option!) But it turns out that Rust actually had other kinds of iterators that correspond to different ways of using Rust's ownership system (where multiple things can have a read-only reference to a piece of data, but only one thing can have the ability to write to it at a time in accordance with "ownership" and "borrowing" rules that I don't really understand yet). So .iter() gives shareable immutable references, .iter_mut() gives restricted-use mutable references, and .into_iter() actually moves the data out of the collection (almost like a Python generator, which can't be reset once exhausted). And there was something about this cool trick where you iterate over indices of a vector backwards so that you can conditionally use swap_remove to take stuff out of the middle in constant time.

Matt Cox gave a talk on "Learning Systems Programming With Rust" that I had really been looking forward to. He explained memory on the stack and the heap with cute animations of unofficial Rust mascot Ferris the crab gliding around putting values into boxes. Unfortunately, there seemed to some kind of mistake where he had an outdated version of his slides?—the talk got wrapped up awkwardly, and I wish we had gotten to hear the rest of what he had in mind.

There were a few talks about some companies' experience actually using Rust in production, and somebody wrote a clone of Graphite in Rust. Somehow I don't have a whole lot to say about these.

I really liked Carol (Nichols || Goulding)'s presentation on doing code archaeology with Git, issue trackers, and mailing list archives. The topic was dear to my heart, given how much of a Git-blame–intensive workflow I have (I M-x vc-annotate constantly). During the second example, on using blame and log to track down the origin of the lifetime elision rules, I found myself wondering if she was going to mention the Git log pickaxe and whether I should try to bring it up in Q&A if she didn't. Then she did discuss it in the third example, mentioning in passing that she didn't know why it was called the pickaxe. Someone in the audience tried to argue that the -S switch resembled a pickaxe. "No, it does not look like a pickaxe," (Nichols || Goulding) replied, "I don't think you could cut down any trees with a dash capital-S."

Carl Lerche talked about his Mio library for asynchronous I/O in Rust; I also don't have a much to say about that one, except that the typography on his slides was very tastefully done.

Yehuda Katz (of Bundler and jQuery fame, amongst others) talked about how to call Rust code from C (or your favorite other language via C extensions). "Rust," he argued, "is a DSL for describing ownership concepts that you have to think about while using C or C++." He recommended that for anything more complicated than simple numerical types, you should translate Rust types to an opaque void * pointer in your C code, and put that in your language's object type if you're writing a C extension. (You can write and expose Rust functions to do useful things with it.)

Finally, Nick Cameron talked about using functionality of the compiler to write tools for Rust, like extra linters and smart code search. Listening to him actually gave me a cool project idea that has nothing to do with Rust, namely that you could write a tool using Python's ast module to count how often which variable names are used, and cross-reference it with Git blame (the AST-node objects know what line number they're from) to see if different members of your team make noticeably different variable name choices.

So that was RustCamp! It was fun, but if I want the fun to have meant anything in the end, I'll have to put more effort into learning Rust properly.