alex kuang

professional yak shaver

Vim Visual Block Mode

Friday Dev Demos are a big part of Bizo culture. Every Friday, developers take turn presenting a short 10-15 min demo on something cool they’d found that wasn’t necessarily work related. The topic could be anything from a neat snippet of code to a cool iOS application they’d just found to a fun web game. Dev demo day is great for the social aspect, but also for the chance to showcase (and draw inspiration from) ideas that might not come up in day-to-day discussion.

Unfortunately, the practice kind of fell by the wayside in the chaos of joining a new company and all the changes that entails. While I’m sure it–or something similar–will make a comeback, in the meantime I decided to try carrying on the torch by starting a weekly “Thing of the Week” email blast that is in roughly the same spirit. And I figured while I’m at it, why not stick it on the blog? If nothing else, it will mean more practice writing and more incentive for me to be proactive in learning new things to talk about.

So without further ado, the first “Thing of the Week” is a neat little feature in vim that I don’t think deserves enough attention–Visual Block mode. The visual modes in vim are very similar to highlighting in other editors, but I’ve always felt that Visual Block is the underrated cousin to Visual and Visual Line mode. Rather than trying to explain what it does in words, here’s a quick terminal cast to demonstrate via asciinema:

Baby’s First Alfred Workflow

Lately I’ve been spending a lot of my work time staring at CloudWatch metrics. Particularly, we have a Kinesis application that publishes metrics on how long a record spends hanging around in the stream before getting picked up by our processor. The problem is that the metric is published in milliseconds, which while precise, is not exactly human-readable for large enough durations.

I’ve been a huge fan of Alfred for a while, and I use its quick-launch and custom search functions nearly constantly. I only recently got around to ponying up for the powerpack, which lets you define custom “workflows”, so I figured–why not use a workflow to convert the milliseconds to something more readable?

Asciinema

I was tooling around the other day and discovered a service called asciinema which provides terminalcasts–essentially, “screencasts” with terminal I/O. This is awesome for a few reasons.

From a content consumer’s standpoint, it’s often hard to follow a blog post that’s trying to outline a command line tip, or a vim tip, for the simple fact that the static nature of writing alone isn’t optimal for showing the flow between “steps” (commands, keystrokes, what have you) and “output” (what you’re supposed to see after executing commands). Having a dynamic format for demos helps with this greatly. Sure, there are screencasts, but that involves dealing with videos and their associated heavy Flash Player bullshit. asciinema is rendered with just bits of html and js.

From a wannabe content producer’s standpoint… Writing is hard. Writing while crafting appropriate examples is harder. Doing all that while struggling with capturing the nature of the examples in plain text? No thanks. Again–Yes, there is the option of screencasts, but those are painful to set up. Screencasts means worrying about things like capturing software, background audio, What Tab Do I Have Open In My Browser, and Will Video Compression Screw My Text Legibility. As a consummately lazy person who only wants to do short self-contained clips for now… That’s way too big of a barrier. asciinema is easy–Just install, then asciinema rec from the terminal and <CTRL-D> to exit and upload.

And embedding takes 2 seconds–Check it!

Bracket Expansion in the Shell

Just a quick post to show of a neat little trick for those who are more command-line-driven: bracket expansion.

Basically, bracket expansion means that some-string-called-{x,y}-here desugars in the shell to some-string-called-x-here some-string-called-y-here. This is especially useful if, say, you’re in a Java-like directory structure and you accidentally placed your source class in your test folder, and you need to move it back:

1
2
# desugars into mv src/test/java/com/foobar/app/Class.java src/main/java/com/foobar/app/Class.java
mv src/{test,main}/java/com/foobar/app/Class.java

Or if you’ve already committed to source control, this also works quite nicely with git mv. Another nice example from recent memory is, say, if you were cleaning up some directories nested by date and wanted to only wipe a few months:

1
rm /posts/2014/{01,03,06,07}/*.html

Anyway, just a quick little post for a neat little trick.

Hello, Hardware World!

Recently, one of our tech leads at work previewed a talk that he’s planning to give on analog metrics for the upcoming Strange Loop conference. I’ve always wanted to play with microcontrollers, and this really gave me a kick in the pants to get started. Since I had a bit of amazon credit lying around, I decided to buy an arduino starter kit with all sorts of buttons, lights, and doo-dads, but not enough power to actually fry anything (I hope). I still can’t tell my head from my ass, but so far I can make a button turn on an LED.

Next step: world domination!

Hack Days Are Awesome

Earlier this week, we had a “hack day” at work. Or more precisely, two hack days. I think the name is pretty self-explanatory–work on whatever you want, which can be something helpful to or completely unrelated to your currently assigned tasks, as long as it’s something interesting. Now, “hack time” is a pretty established institution in the software world, especially amongst the hip startuppy companies. I’m sure everyone has heard of Google’s “20% time” idea by now, and the story of Microsoft’s Xbox starting as a side-project. Proponents (especially those who are trying to pitch a business case to managers with varying degrees of pointy-haired-ness) cite building camaraderie, stimulating creativity, and increasing morale as some of the biggest benefits.

None of this is news. But I came away this week with a surprising realization. When coding professionally for business use cases, things like resilience and stability are often at the top of the requirement list–Or at least, I’d really hope so. If it’s not, kindly give me the name of your company so I know what stock to not buy ;). To this end, coding is never as simple as just sitting down and banging away at a keyboard. It involves testing, discussions, design, thinking, more testing, more thinking, and so on and so forth.

Don’t get me wrong. These are all very, very good things. But I, at least, was surprised at how nice it was to just sit down and bang away at a keyboard with abandon. It sounds rather obvious in hindsight, but compared to the usual rigorously managed process of software development at work, it’s super liberating to just cowboy out some code with no considerations other than speed and getting the job done. And what’s more, I realized that I had constrained myself to the same careful management in all of my personal projects as well, especially when prototyping out potential MVPs and such. Again–Definitely a good thing, in most cases. But after this week I’m thinking that injecting some “hack day”-ish time into my personal projects is in order, if for no reason other than to let the crazy out.

tl;dr - Hack days are awesome. I should do more of them.

IAP and Mobile

In-app purchases and the free-to-play model have long been anathema to self-declared “real gamers” everywhere, but the recent release (or re-release?) of classics like Tales of Phantasia and Dungeon Keeper seems to have brought yet another wave of angry discussion to the forefront. Understandably, people are very angry that their beloved classics are being turned into f2p “cash farms”, but personally I think saying the model is “destroying the industry” is a bit hyperbolic.

In response, toucharcade recently published a post pointing out an article that takes a stance to the contrary. The original piece is definitely worth a read to anyone who cares about the topic; it makes a number of good arguments regarding pricing pressures and facing a realistic economy for the unprecedented levels of competition on iOS. But it also notes that the concept of paying for more content–the “original IAP”–dates back to the beginning of the industry with coin op arcade machines. This seems like a valid comparison superficially, but as someone who’s shelled out way too many quarters on the likes of Gauntlet Dark Legacy I feel like there are two fundamental differences that this argument glosses over.

First: arcade games always had a large skill component. It might take a while to get good enough, but it was always possible to beat the game consistently on sheer skill alone. The game might have been hard, but the balance was never so broken as to render completion impossible without the extra coins. Second: in the cases of the most nefarious IAPs, you’re not paying to spend more time with the game; you’re paying for the exact opposite. When an IAP does nothing but shorten a timer or increase a premium resource, you’re essentially paying more money to decrease the time you spend with the game. All “Skinner’s Box From Hell” arguments aside, that is probably what I object to the most. I don’t have an indiscriminate hatred for the f2p model–there are definitely cases of it being executed well–but I have a fundamental problem with paying more for less.

Adventures With Mail.app Gremlins

Background

Usually I don’t care too much if an email or two gets dropped en route. Between spam filters and sometimes-spotty (cough, mobile) connections, it’s not too much of a stretch to assume that things get lost once in a great while. But recently I was trying to set up an interview on the other side of the country, so naturally I paid a little more attention than usual. Everything was going quite well, correspondence was zipping back and forth, and I’d even bought a plane ticket for the trip. But then a lull came when it was time to receive confirmation for hotel arrangements and a rough schedule for the interview process.

Unbeknownst to me, the HR rep had already tried to send the information twice at this point, but for some reason the emails weren’t landing in my inbox. I sent one last-ditch follow-up when my flight was boarding, and got a reply with the info (thankfully) right before the plane took off. Along with the reply, the HR rep mentioned that the previous emails she’d sent had gone to waffles@mochify.com. (aside: While waffles@mochify.com isn’t the first email I’d give out professionally, I’m thankful it wasn’t something like sexbadger69@gmail.com … Actually, now I wonder if that address is open …)

The technical details

This was an old address that I’d added to my various devices previously, but then removed for inactivity; I certainly didn’t recall sending any recent email from it. But when I logged in to check the inbox, lo and behold the missing emails were staring me in the face, along with a few others that had been “dropped” not too long ago. Something smelled fishy. I checked over my Sent box for my regular email to no avail; all the correspondence was there, with the correct Froms and Tos. I ended up having to dig into the plain-text of the mime header to spot the issue:

1
2
3
4
5
6
7
From: Alex Kuang <[...]>
Content-Type: multipart/alternative;
    boundary="Apple-Mail=_7DA4001C-0AA1-48BD-80F5-00ACDBCCAE9C"
    Message-Id: <ADFD0F4C-6FE0-41F5-AA68-EF8E9845B360@gmail.com>
    Mime-Version: 1.0 (Mac OS X Mail 6.6 \(1510\))
    X-Smtp-Server: smtp.gmail.com:waffles@mochify.com
[...]

X-Smtp? What? After a bit of googling I discovered that Mail.app on the Mac keeps a list of outgoing smtp servers associated with your mail accounts, which you can see in Preferences -> Accounts -> “Outgoing Mail Server” -> Edit SMTP Server List. The problem is, the entry with the association persists even after an account is removed from the list: when I checked my smtp list, it included an entry for mochify as well as a few other one-off addresses that I’d added and removed in similar fashion. Most of my email (including mochify.com) is handled by google apps, which means that the smtp server the entries pointed to were all smtp.gmail.com, and the only difference was the username/authentication associated.

So what ended up happening here was that I’d sent the email from my regular account through Mail.app so it still carried the correct From/etc. However, for reasons unknown, the outgoing smtp entry for that account did not work at that moment. Since mochify’s smtp entry pointed at the same smtp.gmail.com server, I’m willing to bet that Mail.app decided it was a perfectly good fallback, added the X-Smtp-Server MIME header, and sent the email causing this weird reply-to behavior.

There is a checkbox in account preferences that will lock you into using one-and-only-one smtp server and prevent this from happening, but honestly after this ordeal I will probably just be even more biased towards composing my email using the web gmail ui. I’m just glad that everything worked out in the end, and anyway this is a good reminder that I should be more diligent in setting up auto-forwarding even for email addresses I don’t plan on using.

CMD Misadventures - Codebase Size

After watching the wat talk and trolling my friends with the aneditor talk for about the 200th time, I decided to finally purchase one season of the Destroy All Software screencasts, despite the (IMHO) steep price tag and my financial destitution. (So far? Totally worth it. But a full review of the screencasts is neither here nor there.)

I’ve always been a big fan of the unix power tools–find, grep, xargs, and so forth–but the DAS talks introduced an idea that had never occurred to me for some insane reason: combine them with git to extract some interesting information about your codebase. And so, I decided to go diving into my biggest scala project for insights about its code size.

One of the most common problems that code size can indicate is the presence of “god classes” or libraries, which know and do way too much and thus are correspondingly bigger than the rest of the code by orders of magnitude. This command was relatively simple and does not involve git, so here it is in its entirety:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
alexkuang@Orion [00:00:00] [~foobar/src/main/scala] [master]
-> % find . -type f -name "*.scala" | while read file; do wc -l $file; done | sort -n
       9 ./com/foobar/models/Permission.scala
      11 ./com/foobar/util/LocParams.scala
      14 ./com/foobar/util/OrgSettings.scala
      16 ./com/foobar/security/package.scala
      17 ./com/foobar/scripts/ReloadStageDB.scala
      18 ./com/foobar/scripts/oneoff/InitSchema.scala
      # ...
     231 ./com/foobar/js/Calendar.scala
     247 ./com/foobar/persistence/Access.scala
     287 ./com/foobar/snippet/BookingCalendar.scala
     307 ./com/foobar/lib/Registration.scala
     319 ./com/foobar/lib/Scheduler.scala

The output was slightly interesting, but nothing groundbreaking. 300 lines is not ideal to me, but manageable. Broken down quickly, find #... finds all files inside the current directory ending in ‘.scala’, reads each file in, and passes it off to wc -l, which does a linecount on the file, whitespace and all. sort does what its name implies, with -n making it sort 1 2 3 11 instead of 1 11 2 3. The information was slightly cool, but as a hack it’s not very interesting, so let’s throw some git in there to try to get a sense of how fast the codebase has grown over time. After all, superlinear growth is usually indicative of a ton of repetition and therefore unnecessary code complexity.

Clojure First Impressions

After achieving some measure of familiarity with Scala, and with newfound copious amounts of free time, I decided I wanted to see more of what the functional world had to offer. The obvious choices were Haskell and Clojure; but while Haskell has the upper hand in functional purity and a crazy advanced type system, I like to think I’m a pragmatic guy at heart and Clojure seemed more practical. I haven’t worked with it too extensively, but my experience so far can be summarized by two words: Simple and composable.

The language

Clojure is a refreshingly simple language. Despite my last foray into a Lisp being about half a decade ago, the learning curve was much gentler than I’d expected. Maybe it’s because I was already in a functional programming mindset, but the straightforward syntax and abundance of documentation probably helped. And on a completely subjective level: iDislikeCamelCase, and clojure-case-is-pretty-neat.

The ecosystem

Of course, the overall enjoyability of using a language doesn’t depend solely on the core language, but also the libraries and toolchain available. Most of the libraries I’ve seen keep in line with the design of the language: super lightweight, super simple, super composable, and as a result super easy to ramp up on and use. Theoretically that should just describe all good library design in general, but I feel like the clojure community takes it especially to heart.

Compojure, for example, chose to implement its url destructuring to closely follow the destructuring available in stock Clojure lets expressions. I can’t help but draw the comparison to Scala, where I’d be more likely to find that url decomposition exists only in the form of an exotic DSL. Another huge example for me is the difference between the simplicity of the Clojure build tool Leiningen and the craziness of Scala’s SBT. Sorry SBT–You work very well, but I’d rather not have to google what the <++= operator does every time I touch the build.

With vim

One of my original reasons for leaning clojure was its close integration with LightTable. As it turns out, the functionality I liked could be replicated in vim with fireplace.vim’s quasi-insta-repl and insta-doc, due in no small part to leiningen and nrepl’s awesomeness. Rainbow parentheses is also pretty cool, and has been useful enough that I will probably keep it on even when I don’t have to deal with the hardcore levels of parens in Lisps:

Overall

If programming languages could be graded on usability, Clojure would get full marks. It has been a breath of fresh air after dealing with the crazy complexity in Scala. Undoubtedly working through the latter had a part in making the former much easier, and Scala will always have a place with me, but for now I find myself slowly joining the rest of the Clojure bandwagon.