An idea for bookifying the web

I use Pocket, a handy “read it later” tool. The idea is that I can “pocket” a web page by clicking a bookmarklet (or browser extension), and the page is:

  • added to a reading list
  • delivered to my device(s)
  • reformatted for readability (the main content is extracted and the page noise is stripped away)

You can see that there are 3 distinct use cases here, which happen to work well together. I’d like to suggest a 4th use case, which I’ll call PocketBook.

A PocketBook is a manifest of web pages that comprise a unit. In its simplest form, it might look something like:

"book": {
    "title": "The Things",
    "pages": [
        "http://thing.com/article1.html",
        "http://thing.com/article2.html",
        "http://thing.com/article3.html"
    ]
}

(One could imagine adding levels of hierarchy to represent chapters.)

Given such a manifest, a Pocket client (including a regular HTML5 page) could slurp up all the content, format it and organize it for sequential reading.

A more sophisticated client would generate nice navigation and a table of contents, say. More so, it could be automatically translated into EPUB or PDF, and sent along to a Kindle.

Among the advantages: you always get the latest version of the “book”. You’ll note that even in the age of Kindle we don’t see book updates or corrections very often. The Pocket client could easily refresh. (And HTTP has well-defined, mature cache rules!)

The manifest could also include licensing information. Since these resources are all simply public web pages, I don’t see a place for protecting the content, but certainly the author could put purchase options in there:

"book": {
    "title": "The Things",
    "chapters": [
        "title": "Chapter 1: The thingening",
        "pages": [
            "http://thing.com/article1.html",
            "http://thing.com/article2.html",
            "http://thing.com/article3.html"
        ],
    ],
    "purchase": [
        "paypal": "some url",
        "hardcover": "some url",
        "btc": "some address"
    ]
}

Of course there is nothing special about Pocket here, I just chose them cuz I use them and it allows for a clever name. Instapaper or Readability could do the same.

Readability, for example, has Readlists, which I’ve used and are quite nice and do some of these things. But as far as I can tell, they must be created and hosted on readlists.com, and I don’t see an obvious update mechanism. A simple manifest format that one could create programmatically would open more possibilities.

(My motive, by the way, is a desire to see this excellent site packaged up.)

Web Components: have we not been here before?

Addy Osmani describes Web Components, of which an important part is custom tags. The promise:

In one word, a future with Web Components is declarative. JavaScript still exists in this future, but is relegated back to a role where it acts as a glue holding the other bits of a component together. Web Apps in the near future will be composed almost entirely from elements (tags). Some of these elements (like the <audio> tag) will be given to you by the browser but others like <slide-show> will be custom elements provided by UI libraries or you can write it yourself.

Programming with tags. Where have we heard this before?

Starting in the 90′s (and through to the present), there’s ColdFusion. It offers quite a library of custom tags — for everything from control flow (<cfif>) to database interaction (<cfinsert>).

Microsoft has ‘em too — called Web Controls  — abstracting away things like authentication and (again) database access. Drop in a tag, get a fully-functioning login form.

Logic as markup. So tempting, and so wrong.

Markup is nouns and adjectives. It doesn’t have verbs. It describes, but it does not impel.

Unless we start from the assumption that we want our logic to be declarative! In which case we end up with tags representing verby things like “authenticate the user, hit the database, and iterate the results”.

Now, expressing a syntax tree in markup is just as syntactically “correct” as any other way. If you want to wrap your if statements and subroutines in angle brackets, no problem, you can do that. If you want function arguments expressed as attributes, OK.

But why would we? We’ve got languages — lots of them. And we make new ones all the time. Why retrofit HTML?

ColdFusion and Web Forms were not unsuccessful. Lots of people adopted them, and there was a marketplace for custom tags. The same will probably go for Web Components.

I suspect, however, we’ll go through a time of irrational exuberance before realizing that everyone has created their own weird-ass pseudo-language with angle brackets.

discuss on hacker news

Nesting is state

There are stylistic debates about how much nesting or indentation one should choose in code. This slide and the one that follows illustrate the issue well. The slide refers to “cognitive load” without explaining, and it occurs to me that nesting is state.

In the first example, if we want to debug around the highlighted line, what do we need to keep in mind?

func (g *Gopher) WriteTo(w io.Writer) (size int64, err error) {
    err = binary.Write(w, binary.LittleEndian, int32(len(g.Name)))
    if err == nil {
        size += 4
        var n int
        n, err = w.Write([]byte(g.Name))
        size += int64(n)
        if err == nil {
            err = binary.Write(w, binary.LittleEndian, int64(g.AgeYears))
            if err == nil {
                size += 4
            }
            return
        }
        return
    }
    return
}

Answer: the truth of each of the if statements that precede it. Each of those bits of truth is a piece of state. Now look at the alternative:

func (g *Gopher) WriteTo(w io.Writer) (size int64, err error) {
    err = binary.Write(w, binary.LittleEndian, int32(len(g.Name)))
    if err != nil {
        return
    }
    size += 4
    n, err := w.Write([]byte(g.Name))
    size += int64(n)
    if err != nil {
        return
    }
    err = binary.Write(w, binary.LittleEndian, int64(g.AgeYears))
    if err == nil {
        size += 4
    }
    return
}

In this case, the highlighted line “cares” very little about what came before — all it needs to know is that we got there.

The flattening of the hierarchy plus lots of return-on-fail can be thought of as “shedding” state. I call this pattern “fail fast”: by the time you get to the bottom of the code, you really only need one piece of “state”, which is “we’ve gotten this far successfully”. You can forget the past.

Of course, the logic of these two examples is equivalent. I am speaking of the mental model — the list of “non-local” things that must be kept in mind when working with a local piece of code.

And for me, “list of non-local things” is a good definition of “state”.

discuss on hacker news

Ben Horowitz on wage-fixing

I am really, really enjoying Ben Horowitz’s The Hard Thing About Hard Things. It’s blunt and refreshing, and lives up to its title. It’s a nice counter to the notion that running a business is dreamy and life-affirming all the time.

But! I was a bit surprised to find him advocate the sort of behavior that has ensnared a bunch of tech firms in a wage-fixing suit.

A good rule of thumb is my Reflexive Principle of Employee Raiding, which states, “If you would be shocked and horrified if Company X hired several of your employees, then you should not hire any of theirs.” [...]

In order to avoid these sticky situations, many companies employ written or unwritten policies that name companies where it is not okay to hire without CEO (or senior executive) approval. With such a policy in place, you will be able to give your friend one last chance to save their employee or to object prior to you hiring them. (pp. 116-117)

On its surface, it seems like relationship advice: don’t take your friends’ or business partners’ employees.

But this is precisely what collusion is. Eric Schmidt and Steve Jobs didn’t aim to “collude”; they just intended to protect their relationships (and their interests). That they failed to notice that they were interfering in a market for employee talent is the problem.

discuss on hacker news

What Stack Overflow and Go have in common

I’ve been working at Stack for over three years now, and over the last six months or so I’ve been doing playing with a programming language called Go. Both are highly regarded and, for many, controversial, and I’ve realized what they have in common.

Stack Overflow and Go are both optimized for artifacts. Which is to say, their goal is to create good outcomes that last a long time. Note that this is not the same as optimizing for the pleasure of their users.

Stack users are sometimes frustrated the strictness of our policies, especially regarding the relevance and objectivity of questions. Go users often gripe about the need to constantly be handling errors at their source — bubbling and catching exceptions is just not a thing.

What both of these design choices have in common is that they help to ensure that what comes out the other side is actually of value.

And make no mistake, they are design choices. They are not technical shortcomings or oversights.

Now, these choices need to be balanced against the pleasure of the authors. If Go were hard to write, or Stack capriciously rejected good questions, neither would be a success.

What both of them demand is, do your homework. Stack questioner: take the time to research your question and express it clearly. Go programmer: that file system call can fail, and your code needs to account for that.

It’s a trade-off between the hedonic happiness of authors in exchange for a longer-term eudaimonia of end users.

discuss on hacker news

How I optimize conversations

I had an epiphany some years ago in working with a person at a previous firm. After many interactions, I noticed that my productivity, my happiness, my motivation consistently were diminished after dealing with this person.

In other words, I found that I came out of these conversations feeling more burdened than I had going in.

I noticed with certain other people, our conversations were exactly the opposite — I came away with fewer problems, or a new perspective, or food for thought, or feeling freshly challenged.

Once I came to notice this pattern, I resolved to be the latter person. This means optimizing conversations for the other person being glad that they dealt with you. This can take many forms, some more tangible than others.

The most tangible form, perhaps, is where you say “I’ll take care of it”, and it’s true, and they leave with a lesser burden. But it takes many other forms.

At Stack, for example, I’ve become a bit of a rubber ducky lately. There are several people — programmers and otherwise — who seek me out when they want to talk through technical or product challenges.

Now, I am very good programmer working at a place where the other programmers are more than very good. It’s unlikely that I’ll tell them what code to write.

But I might help them characterize the problem differently than they are currently doing. Maybe it’s a compression problem, or a caching problem, or a type problem, or a separation of concerns problem, but they haven’t recognized it as such.

More likely, I’ll nod and ask leading questions. Not because I am trying to lead them anywhere in particular, and not because I know the answer, but because I want to lead them away from rut they are in. I am optimizing the conversation for the other person having a new perspective.

But these are just examples. The point is to think creatively and empathetically about why a person started a conversation with you. Make it profitable.

Threshold thinking

I consider our industry’s current approach to ads to be wildly inefficient. Very “good” click-through rates are in the single-digit percentages, and more likely one or two orders of magnitude below that.

Let’s assume for the sake of argument that some brand advertising is valuable, which is to say that the impression serves a purpose even if the user doesn’t click.

So, being charitable, 90% of ads that we put on our sites are of no economic value, which is to say, of no value to the user.

This makes them a degradation of our product. We go to great lengths to get the design just-so, and then we mar it with an element that serves the user not at all.

I don’t say this because I am against ads; I am against ads for which there is no evidence of value.

I think of this in economic terms. Ads are negative consumer surplus in 90% of cases. They make our published product a worse value. Over time, customers should be expected to migrate to products that provide better value.

I don’t expect this to simply be solved by better targeting which nudges up click-through rates. There needs to be an order-of-magnitude change.

I’d like to see the first publisher or ad network that only chooses to serve ads for which it has evidence of economic value; in the absence of such evidence, an ad is not shown at all.

Our current method of ad delivery is spray-and-pray. If we are very good at targeting, 10% of the ads have value. What if we had higher standards than that?