At Khan Academy, we put a lot of effort into producing interactive math content (e.g., Drawing Polygons).
This kind of interaction is 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.
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:
(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.
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.
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.
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.
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.
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:
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.
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.
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.
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).
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.
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.
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.
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.