The internet is in an uproar over the recent suicide of Aaron Swartz and the federal prosecution that helped push him to it. My thoughts:

  • I first heard about the suicide on Reddit, on a Python community thread named something like “Author of web.py framework found dead”.
  • There was nothing atypical about the way this prosecution was handled. It’s commonplace for prosecutors to intimidate through claims of outrageous punishments for those who won’t plead guilty. If you only get upset about this practice when it hits a sympathetic person like Aaron, then you’re part of the problem.
  • The Aaron Swartz story now has the masses clamoring for scaling back the Computer Fraud and Abuse Act (CFAA), which makes it a federal crime to “exceed authorized access” to a computer. Where were you guys a couple years ago when the same law was being used to throw the book at Lori Drew, the woman who made a fake MySpace profile to cyberbully her daughter’s classmate, and drove her to suicide? It’s a good thing that we can’t vote on court case verdicts the way we can on American Idol contestants.
  • Orin Kerr’s legal analysis of the case is far more reasoned and well-informed than anything you’ll get through the mainstream media.
  • It’s been a slow news week. Would we have been this upset about Aaron Swartz if his suicide had happened in late October (with the election approaching)?
  • Zoe Lofgren (congresswoman for me and most of Silicon Valley) is proposing an amendment to CFAA and calling it “Aaron’s Law”. Orin Kerr points out that her amendment wouldn’t have actually done much for Aaron’s case, though we may get a better result if we wait for the Supreme Court to resolve the lower court split over how the CFAA should be interpreted. (Thank you Orin for linking me to Kozinski’s opinion in the Nosal case, which is excellent.)


Puerto Rico just approved a non-binding initiative to become a state. The next step is Congressional approval. I hope it happens.

I Fixed a Bug in Python

This is my bug. There are many like it, but this one is mine.

Rent Seeking Auto Dealers

Auto Dealers Whine That Tesla Stores Are Illegal

States have varying laws around auto dealerships, ostensibly to protect consumers. Conveniently for existing dealers, these old laws also protect them from competition disruptive startups. Tesla has found a way around that. Regardless of whether Tesla’s approach is illegal in some states, is there any serious argument that it’s harmful to consumers?

The Tacocopter in the Coal Mine

A persuasive argument from the Economist that outdated, burdensome regulations are the more serious constraint on innovation than the absence, as Tyler Cowen would say, of “low hanging fruit.”

Second Thoughts on CSS Minification

The conventional wisdom these days is that you ought to minify your CSS in order to reduce the amount of data sent over the wire and reduce the load time of your page. In practice, minification means stripping out whitespace and comments, which are useful for human readers but unnecessary for browsers.

But I’ve been thinking about gzipping lately, which most web browsers and servers will do for you transparently. A good compression algorithm ought to compress away most of the whitespace (though it won’t strip out comments, obviously). So I ran some numbers on the main.css from one of my websites. I saved both the unminified version, and one minified with the YUI Compressor. Their sizes:

brent.tubbs hedy tmp $ ls -lh *css
-rw-r--r--  1 brent.tubbs  staff    38K Feb 10 09:13 main-minified.css
-rw-r--r--  1 brent.tubbs  staff    53K Jan 23 14:31 main.css

A 15K savings. Not bad, but probably also not noticeable. Then I gzipped both. Their sizes after gzipping:

brent.tubbs hedy tmp $ ls -lh *gz
-rw-r--r--  1 brent.tubbs  staff   8.4K Feb 10 09:16 main-minified.css.gz
-rw-r--r--  1 brent.tubbs  staff    11K Feb 10 09:16 main.css.gz

After gzipping, the difference in file size is 2.6K.

I’m not going to dispute that smaller is better, but I seriously wonder whether such a small improvement is worth the costs, such as the time spent integrating minification into your workflow, and the inability for a human to read the css on the live site. I tend to think it’s not.

You Should Learn a Language with List Comprehensions

In a post linked from Hacker News today a guy named David Jacobs explains how he moved from Java to Ruby because of awesomeness like first class functions, giving an example of how Ruby lets you create your own function and pass it to array.select in order to filter an array on whatever criteria you like. He uses selecting only the even numbers from a list as his example.

array = [1, 2, 3, 4, 5, 6]
criterion = lambda {|n| n % 2 == 0 }

array.select &criterion
# => [2, 4, 6]

The equivalent Java code was huge, and would would have to be 90% copy/pasted to make similar filtering functions like “give me just the odd numbers”. Well done Ruby. David’s post goes on to say that he’s now learning Python (because of the availability of scientific computing packages like numpy and scipy). He also says Python is ugly. BATTLE STATIONS! Here’s how Python does that.

somenumbers = [1, 2, 3, 4, 5, 6]

[x for x in somenumbers if x % 2 == 0]
# result is [2, 4, 6]

I <3 that you can use list comprehensions to do something like that without even having to declare a function or lambda. In Ruby you can accomplish the same thing with either chained select/collect or map/compact calls, but I’ll pick Python’s list comprehensions in a beauty contest.

As geeks do (and as I’ve done here), the commenters on David’s post rushed to defend their favorite languages. In Java’s case, they say, the extra code is buying you type safety that Ruby (or Python) can’t give you.

I call shenanigans. You can have both. Behold, the Haskell version:

justEvens :: Integral a => [a] -> [a]
justEvens xs = [x | x < - xs, even x]
-- load that up in ghci and you get this:
-- ghci: justEvens [1, 2, 3, 4, 5, 6]
-- [2,4,6]

It’s a function around a list comprehension. The type declaration on the first line gives you the type safety that Python and Ruby lack. The second line does the work. So it is possible to have terse, clean, expressive syntax at the same time as first class functions and type safety. That’s what makes Haskell my current geek-crush.

(Aside: Python’s list comprehensions were specifically borrowed from Haskell. Python’s syntax just uses words where Haskell’s notation uses symbols.)

UPDATE: As effusively as I praised Haskell up there, I still sold it a little short by neglecting to mention Haskell's type inference. Long story short, you don't even need the type declaration line in the Haskell example above. Given this definition...

justEvens' xs = [x | x < - xs, even x]

... you can inspect that expression in ghci and check its type signature against the one we explicitly declared:

ghci: justEvens' [1, 2, 3, 4, 5, 6]
ghci: :t justEvens'
justEvens' :: Integral t => [t] -> [t]
ghci: :t justEvens
justEvens :: Integral a => [a] -> [a]

Their type signatures are the same. Haskell took the implication of us using the 'even' function inside the list comprehension, and from there inferred that our function must accept a list of Integrals. (Haskell's strict type system results in there being a few kinds of integers.)

Now this doesn't mean that you should turn Haskell programs into code golf and omit type signatures wherever you can. It's wise to keep them because 1) they serve as a check on your understanding of the function being the same as the Haskell compiler's, and 2) they'll reduce the amount of time it takes future programmers to understand your code.

hg branch != git branch

At work we’ve been talking a lot lately about how to branch and merge code when we do releases and build new features.  It’s a fundamental law of the internet that every git vs mercurial flamewar must include a comment along the lines of “they’re both pretty much equivalent, just pick one”.  This leads to the impression that commands in one mean pretty much the same thing as corresponding commands in the other.  When it comes to the ‘branch’ command, this assumption gets you into trouble.

The short version: If you think you should do a ‘git branch’, you’re probably right.  If you think you should do a ‘hg branch’, there’s a pretty good chance you’re wrong.

Further reading:

Stages of Learning

Awesome quote from Derek Sivers:

They say there are a few stages of learning:

  1. unconscious incompetence
  2. conscious incompetence (< -- me)
  3. conscious competence
  4. unconscious competence

I’m not sure which “they” he’s referring to since I’ve never heard that before, but I think it’s profound.

It strikes me that the quality of communication between people in those stages will vary greatly. Someone who is in stage 3 will be an excellent teacher of someone who’s in stage 2. Someone who’s in stage 1 is hard to teach, because the move from blissful ignorance to conscious incompetence is humbling and painful. A lot of people give up and tune out rather than enter that world. (Think of every person you know who thinks “I’m not really good with computers.”)

Fish in Water

The most difficult communication is between stage 4 people and stage 1 people. A fish swimming through water does not have to think to itself “swish tail right, swish tail left, swish tail right…” as it swims. It just does it, and isn’t even conscious that there is such a thing as “water.” Likewise a fluent computer programmer spends almost no time thinking about syntax. Instead time is spent thinking about higher level abstractions that are not even visible to the novice who is still coming to grips with all the parentheses and curly braces. Stage 4s have so completely immersed themselves in the topic that its basics now require no thought. They will take for granted and skip over the hundreds of little details that are now second nature, and will sound to stage 1s like they are spewing irrelevant jargon.

In most parts of life that’s fine. Stage 4 computer people can call themselves “geeks” and go to conferences together. Stage 4 musicians can form bands or orchestras and create art that most of us can’t fully appreciate. The obvious problem that arises is when stage 4s are asked to work on a project with stage 1s, or even worse, when the person in charge of a project is at stage 1 on its key areas of expertise and asked to supervise workers at stage 4. This boss will make decisions that are incomprehensible to the rest of the team, ignoring their advice because he (or she) has no context by which to judge the input’s relevance or worth.

Stage 1/Stage 4 Conflicts in Web Design

The frustrations of stage 1/stage 4 mismatches are keenly felt within the web design world. Most web design work is done on a project basis. So while a web designer is working on his or her 50th site, the client is probably doing its first or maybe second. And it gets worse. Just like everyone thinks they have a good sense of humor and are above average drivers, the typical web design client falls into these traps:

  1. Having strong opinions on a website’s appearance, and substituting these opinions for reasoned consideration of design.
  2. Giving short shrift to “usability”, either thinking that it’s obvious or that it means “whatever I already thought about how the website should work.”
  3. Believing that they’re a naturally above-average manager, and don’t need to worry about management pitfalls like designing by committee or making end-runs around the project leader.

Huge mismatches of competence are so common in the web design world that dealing with them is a common topic of blog posts, client education materials, and even web comics.