Isaac Cambron

Will Wilkinson has a piece on Barry Goldwater’s line “Extremism in defense of liberty is no vice”. I guess the idea is to use his criticism of that line as a sort launching point for a larger discussion about libertarianism. I don’t have any particularly strong opinions about libertarianism as a whole and I have no special affinity for that quote, but I think the piece ends up being pretty empty.

Here’s what seems like the core of the argument:

If, as Aristotle says, virtue is a mean between a vice of excess and a vice of deficiency—a middle-ground between two extremes—then to be virtuous is to have a certain kind of moderate temper. Extremes are vices by definition.

We also have that violence is part of the extremism bundle:

The questionable character of extremism is anyway right there on the surface of our ordinary understanding of the term. There is a whiff of violence, or at least danger, about extremism. Extremists reject mainstream opinion, including mainstream opinion about acceptable political tactics. To embrace extremism in defense of something is to at least flirt with the idea that violence isn’t out of the question.

I will give Wilkinson that no one’s moral system holds violence to be a virtue in itself, so I’m on board with this labeling. And if he wants to define virtue in such a way that it precludes extremism, who am I to argue, except to point out that sometimes maybe we shouldn’t be virtuous? But the problem is that Wilkinson doesn’t really believe that extremism=non-virtue is tautological for any useful sense of virtue:

Throughout its history, America’s white supremacist institutions have been so violently opposed to the liberty of black people that it was not unreasonable to believe that something extreme might need to be done to finally win them a modicum of freedom.

And:

Sometimes circumstances legitimately call for extreme measures. A civil war to free enslaved human beings would be a good example. Goldwater’s example, D-Day, is another case in which extreme, extremely violent, measures were not unvirtuously excessive.

I think there’s a great deal of danger in throwing around Aristotle’s definition of virtue haphazardously. It’s not that it’s wrong, it’s that it asks “excess” and “deficiency” to do the heavy lifting, while simultaneously relegating them to the background. Virtue is staying well between some hash marks, but who sets those hash marks, and are they set right? And in that last quotation, look how much work “legitimately” is doing. Extremism is unvirtuous except when it’s actually justified. In the case of, say, slavery, the problem is precisely that the hash marks were set so insanely wrong by society at large. How extreme of action your moral framework justifies is a function of how different the hegemonic definition of “excess” and “deficiency” differ from your moral framework’s. So “when is violent action justified?” is the actual question here, the thing on which the quote’s truth (or at least value) hinges. Its answer is “when it’s in defense of liberty”. Wilkinson disagrees, obviously, but doesn’t really tell us why. The concluding paragraph gives us a hint:

If you’re engaged in a literal war between good and evil, then maybe you’ve got to do what it takes and kill people. But politics is not war. If you’re a senator from Arizona, or a think tank scholar engaged in normal domestic politics of a stable liberal democracy, extremism is no virtue.

But just a hint. Politics clearly can be war—the American Revolution was a political war—but I think Wilkinson simply means everyday American politics. If the argument is merely that the stakes are too low to justify violent action—that the moral calculus doesn’t add up—then I agree, but then I wonder what bearing all the preceding paragraphs have. Perhaps the point is that Goldwater is wrong because he leaves out even a handwavy notion of proportionality; it’s clearly untrue that any imposition on your freedom justifies any action. But who interprets the line that way? No one, apparently:

Almost everyone who repeats Goldwater’s slogan is guilty of hyperbole and doesn’t really mean what they’re saying. Barry Goldwater himself certainly didn’t think that it is “no vice” to murder scores of innocent people in defense of liberty.

In fact, Wilkinson doesn’t even think the quote itself implies that:

That said, if extremism in defense of liberty is warranted, it doesn’t quite follow that it’s okay to use any means necessary to that defense. (Malcolm X certainly would not have endorsed, say, the nuclear annihilation of Manhattan in exchange for the end of systemic racial oppression in America.)

Certainly, Goldwater himself had a hard time articulating how the imposition of being forced to let black people use your supposedly public bathroom can be usefully compared to the threat of Axis domination of the world, and thus justifies morally equivalent action. But as Wilkinson points out, “it requires a special sort of obtuseness to insist that Goldwater was only making some sort of abstract, historically acontextual point about the politics of liberty.” In other words, the reason that Goldwater thought the delta between how the world ought to work and how it works was only sufficiently big, in his mind, to justify violence is that he was profoundly racist. Which doesn’t tell us anything other than racism can make people jerks.

On the one hand, I’d certainly be sympathetic to the point that the “extremism in defense of liberty is no vice” doesn’t really constitute a principled moral position, that it isn’t dispositive on any actual questions of right and wrong. But on the other hand, that’s also why, once we’ve waded through a lot of definitional fiat, it ends up being a banal point to quibble with. What’s missing here is an engagement with the moral philosophy of libertarianism as it relates to this quote: when should you resort to extreme measures on behalf of freedom, and how does that compare to how people apply that line?

My startup has been building our product in Clojure. It’s been awesome, and overall, it’s been pretty easy to learn and be productive with, since our team was already in a functional programming mindset. But we’re still learning some of the edges. Specifically, today I was trying out a newish feature called transducers, which allow you to compose transformations on data without having to care much about its “container” type, so long as that container provides a way to reduce itself.

Just playing around with it, I got confused for a bit that my transducers kept composing in the opposite order I expected. Specifically, this (which I’ll explain in a second):

It took me a bit to figure out what was happening at all, and when it dawned on me (“oh, it goes the other way!”), I wondered why the hell does it do that? I asked about it on the ClojureScript IRC channel, where David Nolen told me to go look at the source. That’s a totally fine answer (it’s not his job to sit around and write out detailed answers to my questions), but it’s of course more useful if there’s an explanation written up, hence this post.

I actually didn’t look at the source; instead, I took a nap and when I woke up I was pretty confident I knew the answer.

A quick review of composition

The order of composition obviously matters; f(g(x)) is not the same of g(f(x)).

(defndoubler[x](*2x))((compdoublerinc)2);=> 6, the result of (doubler (inc 2))((compincdoubler)2);=> 5, the result (inc (doubler 2))

If you want to apply that composition to each element of a sequence, you’d do something like:

(map(compdoublerinc)[123]);=> (4 6 8)

But perhaps you have a bunch of functions that operate on sequences, and you want to compose those. You end up with the uglier, less efficient, and no less correct composition of maps:

((comp#(mapdoubler%)#(mapinc%))[123]);=> (4 6 8)

Transducers, briefly

Transducers manage to compose the same sort of transformations, but do it in a way that doesn’t create intermediate sequences (even lazy ones) and for which the transformations themselves are agnostic about what kind of container they’re transforming elements from (or into). It does this by defining various transformations (e.g. map, take, filter, etc) in terms of reduce and then parameterizing them with the reduce function itself. So map in the transducer world doesn’t mean “take each element from a sequence and call this function on them and put the results in another sequence”. It means “given some way (let’s call it foo) of reducing something, give me a way of reducing things that increments each thing and then reduces it with foo”.

You create a transducer by calling one of the standard listy functions without a collection arg, like (map inc). That transducer can be handed to pieces of machinery that know what transducers mean, like the transduce function:

(transduce(mapinc)conj[123]);=> [2 3 4](transduce(mapinc)+[123]);=> 9

What’s really neat is that different containery things can implement reduce differently without having to define its own specific transformations (or even make you do it differently for your different use cases). For example, you could use some transducers you built to transform a vector, while your core.async channels can use the same transducers to transform values pushed through them. That works because those async channels can provide their own definition of reduce, and the transducers only depend on that having the right shape.

Reversals

So why does composing transducers mean they get evaluated “backwards” or “inside out”? Well, on reflection, it makes a lot of sense. What transducers really do is transform reducing functions, not actual values; they take one reducing function and return another one that works by transforming its values and passing the results to that passed-in reducing function. When you compose them, you’re using the function returned by the “inner” transducer as the reduction function for the “outer” transducer. So if I have (comp (map double) (map inc)), I’m saying that (map inc) provides a reducing function that takes a value, increments it, and feeds into the reducing function it gets passed. I’m then passing that reducing function into the doubling tansducer, which returns another reducing function that doubles the values and then feeds the answer into the map-incrementing reducer the doubler took as an argument. So double then inc.

Instead of bubbling values out like in a simple compose, you’re building a set of concentric spheres, each capable of taking a value from the outside and pushing it in.

I’ll make that more concrete in a moment, but first, note that this inside-outness is a common feature of composed higher order functions that use their arguments as their “outermost” invocation. Compare our original composed maps to these, which also don’t use transducers at all:

If that makes sense to you, the next part will be easy. One interesting way to better understand all this is to implement a simplified version of transducers. We’ll skip a bunch of complications, like stateful transducers, and we won’t bother with a really important thing about transducers: making the actual reduction polymorphic. But here goes:

(defnmy-transduce[xformfinitcoll](let[reducerreduce;todo: this should depend on the type of colldoit(xformf)](reducerdoitinitcoll)))(defnmy-into[toxformfrom](my-transducexformconjtofrom))(defnmy-map[f](fn[rf];rf is like conj or +(fn[resultinput];can be passed to a reducing function(rfresult(finput)))));this is the inversion that answers the question(my-into[](comp(my-mapdoubler)(my-mapinc))[123]);=> [3,5,7]

That’s the whole thing. my-map returns a transducer, i.e. a function that takes a reducing function and returns a different one. Since it does its transformation and then delegates the actual core reduction work to its argument, the order of composition from the standpoint of the individual values is…well, I still say it’s backwards. But it makes good sense.

There was a recent article in the Wall Street Journal about how all of the people who gave Occulus money feel a bit screwed by the acquisition. I think the article has some flaws, but it reminded me of a point I’ve been making recently. I posted a short writeup of that point on Hacker News, and I like how it turned out enough to post it here (with some minor edits):

I’ll just say it: Kickstarter is for suckers. When you give money to a project, you’re doing one of two things:

Making a donation to a company.

Preordering something that hasn’t been built yet.

Doing 1 is silly, since you don’t really get anything in return. “But it makes it more likely that this thing I want will happen!” In some tiny marginal way, sure, but mostly it’s going to happen because other people donate (or fails to happen because they don’t). Don’t be the fool who tries to personally take on the collective action problem. And stop trying to make other people rich out of the goodness of your heart.

Of course, as the WSJ fails to make clear, most of Oculus’s Kickstarter money wasn’t straight-up donations; it was preorders of the Rift. That’s obviously not a donation, but it’s not a good idea either. As the buyer, you bear the risk that it never ships at all. “But I’m compensated with a discount!” Essentially, you’re making an investment in which your returns come in the form of future discounts on a product. Forget that you like the Oculus Rift for a second; is this a wise investment structure? If someone set up a VC company that did that instead of buying parts of companies, would you think that was smart? Did you do any kind of analysis that suggests this is actually works out to be a good investment? Do the potential returns even justify that analysis? Do you think of other consumer products this way, or only shiny electronic things?

Will you even get a discount? Why would you?

Or to think about it a different way: imagine if someone set up a store that worked like this: you take your item to the counter, where they don’t actually let you buy the item. Instead what you can do is pay the price minus n% and then they roll this big roulette wheel to decide whether you get the product (m% success rate). If you win you get to keep the product and if you lose it goes back on the shelf and they keep your money. To spice things up, they don’t tell you what n and m are either, just the price to play and whether you get the item. Now, it’s possible—though unknown—that m and n work out that you’re EV positive here. But would you really shop at that store? Especially when there’s another store next door that just sells you the same stuff at a known price (i.e. just buy the Rift when it comes out).

The fact of the matter is that you’re aren’t pre-buying the Rift on a rational basis. You’ve been convinced by clever marketing to shoulder risk for a company because it seems cool and feels good. Total sucker move. That probably explains why it tastes bitter when the company whose capital requirements you fronted rolls that into a $2 billion dollar acquisition.

FbFriends is a new jQuery plugin for picking Facebook friends from a
dialog using the Facebook JS SDK. It’s written in CoffeeScript and Less;
you can find the docs and demos here and
the code here.

For the lazy, here’s a screenshot (and apologies to my friends who showed up here):

Go check it out; I think it’s pretty cool.

Not a ton to say, but here are a few interesting notes about it:

I went with the idea that the caller has to provide the dialog
component. It just seemed dumb to bake in my own and likely you’ll want to make
it look consistent with the dialogs/modals/whatever in the rest of
your app. So you provide callbacks to open and close whatever
dialog you want. FbFriends just provides the content.

I really didn’t want to build this. In fact, the Facebook SDK used to
have this ability, and they dropped support for it. I wish they hadn’t.

A lot of Quarrels Harris Port was consumed during the making of this
library.

TL;DR

It’s a jQuery plugin I wrote that turns unordered lists into nifty timelines. Docs here. Code here. Check it out.

Why did I build it?

Timestack is a small library and didn’t take long to write, but I had a few thoughts about the process that I wanted to share.

When you build software for a living, you make a lot of compromises. You start with a vision of what you want to build, you get to work, and you run into obstacles. Maybe the technology you wanted to use doesn’t exist. Maybe it does exist but doesn’t work the way you wanted it to. Sometimes the right thing to do is to fix that technology or just build your own before moving on to the actual work. But usually that’s not the right move. Usually, you compromise your vision, make do with the pieces you have, make some quirky work-arounds, and move on. If you don’t, you’ll end up rewriting your entire stack from scratch to make every little part just right and you’ll never actually get anything done. You’ll have a bunch of (maybe) cool infrastructure for something that hasn’t been built yet. Knowing when and how to make this kind of tradeoff is part of being a good engineer.

One of the nice things about a personal side project is that it allows you to absolutely, totally ignore that whole last paragraph. You can compromise as much or as little as you want. And if you’re like me, personal projects are an awesome opportunity to solve problems totally tangential to your goal, getting distracted by problems you encounter solving those tangential problems, and so on into fractal oblivion. That’s just fun. That’s what a personal project is. If I had to actually deliver it, even to myself, it would be a job. Jobs are fine, but they’re not the best context for depth-first exploration.

Anyway, here I was trying to make a nice interactive resume for a simple “Hi, I’m Isaac. I build things.” website. I wanted a timeline that showed when I worked where, because I think that’s more interesting than a boring bulleted list. I looked around and there are a few components out there that do this:

After trying out Timeline (it is pretty), I decided it was too big and heavyweight— it’s a timeline, not an application framework. It doesn’t need themes or its own script loader. Importantly, it also didn’t really do what I wanted, partially because it imposes some constraints I don’t like, and partially because it just isn’t meant for my use case. Simile is similar, but unmaintained and worse looking. I wanted something really simple:

It should turn some list items into timeline bars. No-JS fallback FTW.

It should create an interval key (the times at the bottom).

It should be able to do stuff when the user clicks on the timeline items. Note that I don’t want it to show me stuff; I just want a callback. Component does less = more flexibility for the user.

It should be small, simple, and hackable. Libraries for handling simple things should be simple, and tweaking them should be trivial.

It’s not important that it work in old browsers.

So I put aside the website and jumped down the rabbit hole.

Notes on building it

Since I’m terrible at UI design, I looked around and quickly found Matt Bango’s Pure CSS Timeline. It looks pretty good and the CSS is simple. It’s hand-cranked, though; the widths of the bars are just hardcoded for the particular times he needed. So all I had to do was write some code to generate those widths. I also added colors, because why not?

Some things I think I know now:

The look and feel of web UI widgets should be customized by the user through CSS. CSS already gives you inheritance, overrides, and all that jazz. Just keep it simple and tell your users to override the CSS you ship. Easy.

Give widgets a width of 100%. The user can decide how big to make the container box.

Go for cheap extensibility over configuration. Instead of adding a whole bunch of flags into the options list, I just put the functions I wanted to make customizable into the options defaults and let the users override them.

When dealing with tricky spacing problems in HTML, use box-sizing: border-box. It’s takes away that problem where you need to set the div width to realWidth - border - padding, which would have been really painful here. In fact, I’m increasingly convinced that border-box should just be the default browser behavior.

If you need to work with dates and times in JS, you should use Moment. It’s just more pleasant than dealing with native dates and times.