Reviewing Code from Both Sides

At Khan Academy, code review is a key step in our engineering workflow—we use it as a mechanism for quality control, context sharing, and more. (See: Code reviews at Khan Academy.)

In making the jump from university (I graduated in June) to Real Engineering™, code review was one of my weak points. I hardly knew anything about it. At school, you never review code. On the job, you're reviewing daily.

With five months of consistent reviewing under my belt, I've begun to notice that where I read code influences the types of observations I can and am compelled to make.

Getting up and Running with Robolectric

Robolectric is a useful tool for testing code that touches parts of the Android SDK without building to a device, made possible by Robolectric's reimplementation and "de-fanging" of parts of the Android SDK, which allows them to run on a regular JVM, rather than an emulator.

I recently integrated Robolectric into our app at Khan Academy—we've been looking into ways to let us write more and more efficient tests, and Robolectric fit the bill nicely (at least for some cases—many tests are best left as functional or integration tests; but I won't get into that here).

Setup was relatively painless, but I did hit a few snags along the way. In this post, I'll outline those snags—and how we got around them—to save you time and effort in your own Robolectric integration battle.

Learning Android in Production

Back in August, a few weeks before I'd joined Khan Academy full-time, our Head of Engineering, Ben Kamens, shot me an email asking if I had any interest in working on the Android team.

I'd never touched Android before, but I was pleasantly surprised to see that email, since the vision of bringing Khan Academy to Android devices had intrigued me for a while. If you imagine a world in which every student, everywhere has access to a free, world-class tutor in their pocket, Android is a big part of it. Joining the team struck me as a fantastic opportunity for impact.

So, I conveyed my excitement to Ben; but I couldn't help but ask:

Is it an issue that I have no experience developing on Android?

In his response, Ben explained that this move would be part of a long-term effort to scale up Khan Academy's Android expertise. And that it was expected that there'd be a significant learning curve to getting me up and running on the platform.

Three months later, and I've built out new features, fixed nasty bugs, and grown to the point where I can meaningfully contribute to our team's technical discussions, as an Android voice. All having started from scratch in mid-September.

It's a wonderfully weird feeling.

The Bitcoin Script Playground

This semester, I've been taking a course on Bitcoin and Cryptocurrencies, offered by Princeton's Center for Information Technology Policy, and co-taught by Arvind Narayanan and Joseph Bonneau (with help from Ed Felten and Andrew Miller).

Inspired by the course, I spent some time this semester on a Bitcoin Script-to-JavaScript compiler and a real-time playground for the browser: the Script Playground. It's a great way to familiarize yourself with the semantics of and philosophies behind Bitcoin Script.

The ES6 source is available on GitHub; you can also download the interpreter as the bitcoin-script package on npm.

Exploring Flow, Facebook's Type Checker for JavaScript

At September's @Scale conference, Facebook introduced Flow, a static type checker for JavaScript.

The stated goal of Flow is to "find errors in JavaScript code with little programmer effort". To paraphrase project lead Avik Chaudhuri: Flow aims to enforce the benefits of a type system while maintaing the "feel" of JavaScript.

Avik promised that Flow would be open-sourced by the end of the year and, true to his word, the project appeared on GitHub a few months later.

I wanted to give Flow a whirl, so I decided to integrate it into a small project to which I've contributed: RCSS. You can find my Flow-annotated fork on GitHub.

(More Than) Doubling SVG FPS Rates at Khan Academy

At Khan Academy, we put a lot of effort into creating interactive math content (e.g., Drawing Polygons).

The kinds of interactions we focus on are particularly important on touch devices: to create an engaging mobile experience, we strive to provide interactive content that feels effortless and fun—tightening the feedback loop as much as possible and enforcing the illusion of complete control.

Poor performance kills this illusion: if a user drags his or her finger across the screen and the polygon lags behind noticeably, the shapes feel heavy and the interaction becomes a chore.

So, when we recently discovered that many of our interactive exercises run at rates as low as 12 FPS on tablets, it was pretty startling.

Rendering React Components on the Server

I love working with React. Like, a little too much (no thanks to my (amazing) internship at Khan Academy, where we use React in buckets).

For a recent side project, I wanted to render my React components on the server, rather than the client (this is often abbreviated as "server-side rendering", or SSR, for short).

Typical motivations for rendering on the server include:

  1. Faster page loads: by rendering on the server, you get to send down a complete webpage, cut out an HTTP request, etc.
  2. More reliable SEO: any crawler that navigates to your site will see a complete page filled with content, rather than an empty page that requires JavaScript execution.

(This isn't to say that SSR is strictly better than client-side rendering; it's just different.)

SSR is totally doable with React; but a lot of the SSR-related resources out there seem to assume prior knowledge. I thought I'd share what I've learned.

KhanQuest: Bringing Khan Academy-based Learning to a Fantasy Video Game

Thus marks the end of the Third Annual "Healthy Hackathon", Khan Academy's weekend-long celebration, which featured awesome improvements to our CS platform, awesome (and hilarious) fundraising efforts, and awesome (and hilarious) music videos, to name but a few of the fantastic hacks.

Statistics in Basketball: What's a "Good" Player?

I just finished Bill Simmons's absolute masterpiece and basketball Bible aptly titled The Book of Basketball (TBOB).

His thesis revolves around The Secret: that is, that the key to basketball isn't about basketball. The truly great teams in NBA history didn't win based on talent (alone). Instead:

... they won because they liked each other knew their roles, ignored statistics and valued winning over everything else. They won because their best players sacrificed to make everyone else happy. They won as long as everyone remained on the same page. By that same token, they lost if any of those three factors weren’t in place.

That said, what really got me thinking in TBOB was the role of statistics in basketball.

A Guide to CS Independent Work at Princeton

Last Spring, I did a semester of independent work (IW) with professor David Walker. My project was focused on rule optimization in Software-Defined Networks (more here), and it was probably the greatest learning experience of my Princeton career (so far).

I worked hard, and I learned a ton—not just about SDNs, but about the research process in general.

Every COS major will do IW at some point. The COS Department has a decent guide here, but after comparing and contrasting my experience with those of my friends, I wanted to jot down some notes about what worked and what didn't.

Compiling to JS: Comparing TypeScript, CoffeeScript, etc.

It seems like all the cool languages these days are compiling to JavaScript. (I joke, but replace 'cool' with 'relevant' and you might have a reasonable heuristic for evaluating the modernity of a programming language.)

Jeremy Ashkenas, the creator of CoffeeScript, has a great list of what seems like hundreds of languages, each of which helps prove my point.

PhantomJS: Common Gotchas for Beginners

Over the summer, I had a pet project to automate Helium.js, a tool for identifying unused style elements in your CSS. Currently, in order to generate a Helium report, you need to add some JavaScript to your webpage, open up your web browser, navigate to the page, and click on some buttons.

My goal was to automate the process using a headless browser (that is, a browser that runs without a GUI, allowing you to navigate the web and interact with web pages from your terminal). In this case, I chose to use PhantomJS.

I had a mixed experience. Headless browsing is notoriously difficult to debug, and this case was no different: errors were tough to reproduce, results were inconsistent, and producing informative output was challenging.

Once I got past the initial difficulties, however, PhantomJS was an impressive tool—hats off to the creators, as always.

In this post, I'd like to describe some of the common "gotchas" that I've found associated with PhantomJS and walk through their solutions. (I call them "common" due to: 1. my own experience, and 2. finding similar questions/issues documented on StackOverflow.)


Update: Quizzler was built as my entry into the Facebook Summer of Hack Hackathon in August 2013 and was selected as the winning hack. Thanks to Facebook for hosting a great event.

After playing a number of poorly-made iPhone quiz games, I decided to roll my own. But I didn't want to spend time creating my own corpus of questions. Thus, Quizzler was born, an attempt to build an iPhone quiz app that generates its own questions.

The 5-Minute Guide to a Perfect, Personal EC2 Instance

I like SSHing into things. So I went ahead and setup my own AWS EC2 instance. Under the free tier, you can get good mileage out of an instance and use it to do whatever you please.

But it took me awhile to get the thing up and running properly. Here are the things I wanted to have:

  1. Easy SSH access at the press of a button (i.e., without entering a password).
  2. Yet, safety and security from the attempted access of others (i.e., using RSA keys).
  3. My own account on the instance (rather than, say, using root).
  4. All the tools I use naturally on my local machine.

If that experience sounds good to you, keep reading. I've pulled together the assorted posts that I used to setup my EC2 instance and assembled The Idiot-Proof Guide.

A Human-Friendly API for Wikipedia

Motivation: There's a lot of information on Wikipedia, and people want to use it. Sometimes, these people are programmers; and sometimes, their customers aren't computers.

I needed to parse some information from Wikipedia programatically and present it in a human-readable format, i.e., for clients. I found that a bunch of other people had similar issues (e.g., here and here), so I've open-sourced my solution.

Setting up Your OCaml Development Environment on OS X

Last fall, I began exploring the subject of functional programming as part of Professor David Walker’s COS 326 at Princeton. Throughout the course, we did all of our programing in OCaml. I also spent the past spring using OCaml for my CS Independent Work. So in total, I’ve spent a reasonable amount of time around the language, and I think it’s fantastic: it’s got a great module system, plenty of useful open source tools, etc.

But OCaml isn’t that widely used. And as a result, there aren’t very many good write-ups out there for setting up an OCaml development environment.

In this post, I’ll provide a couple of choices for setting up such an environment when developing on a Mac.

Rule Optimization in Software-Defined Networks

I'm doing some independent work this semester with Professor David Walker, with whom I took functional programming last semester. My project is being implemented functionally, however the main focus is on rule optimization in network routers; specifically, routers within software-defined networks (SDNs).

True Parallelism in OCaml

OCaml provides a nice library for multi-threading. Problem is, according to my professor, under the hood, OCaml doesn't actually employ any parallelism at all! In truth, the compiler just interleaves instructions in a way that has the same computational effect as multi-threading, barring the 2x speed-up.

On the side, I've been working on an alternative to the small Futures module we used in class. Futures are very similar to threads but safer and easier to use. The interface itself is composed of a create method, which takes as argument an expression to compute and performs said computation on a new thread; as well as a force method, which blocks the main thread until the Future has finished its computation.

Streams and Lazy Computation

I was recently introduced to lazy computation in the context of streams—very cool (and powerful) stuff. In this post, I’ll go through streams first, then use lazy computation to address a problem specific to the data type before closing with an example.

iOS Performance: Shadows with Bezier Paths

I spent some time yesterday fixing some performance issues related to EveryCollegeCal (my iOS app). Basically, I was seeing very slow, choppy segues between the first two views (one of which is a welcome screen, the other a table view). On top of that, the scrolling performance of the latter view was equally gross.

In the end, the fixes were not too involved—i.e., they didn’t involve a spectacular amount of code (of course, this can’t be said of all performance issues, so I count myself lucky). And there were only two necessary changes: the choppy segues were fixed by swapping out my glossy button library, which was apparently very inefficient. But the second change demonstrates something cool about iOS performance tweaks: while they’re often subtle, the under-the-hood explanations are always logical.

First Thoughts on OCaml

N.B.: I wrote this post a few weeks after first using OCaml. Before that, 90% of my programing had been in Java. Looking back on these notes, perhaps a more accurate title would be "First Thoughts on a Functional Language After Only Knowing OOP", or something along those lines. But for posterity, I'll leave it as-is.

I’ve been learning to program in OCaml for one of my courses this semester (COS 326: Functional Programming) and I can't remember the last time I was this excited about anything CS-related. Learning to program functionally is like learning to program all over again.