2014-02-14 17:40:58 -0800

Riding home from the café this morning, I experienced a powerful sense of temporal displacement. The temperature, the color of the sky, the damp scent of flowers, the particular slant of the wind, the shade and shapes of the pavement transported me emotionally to Provo, Utah, 1982, riding my bike down the street away from the mountains homeward as the weight of an impending storm pressed from all sides. Swallowing to equalize the pressure in my ears, I watch eddies of leaves intermittently swirl up and then scatter haphazardly back to the ground. I feel a low, diffuse sense of anxiety–an urgency that has been cut with disappointment so often that it no longer tastes of immediacy, but still has that bile-bitter edge of expectancy. The future has been stripped of detail. The projections that adults weave like tendrils into otherwise unmapped time have suddenly withdrawn as if in flinching recoil from an unexpectedly repulsive sensation. All that is left are vague impressions of possibility; there are no appointments, no plans, no rituals, no assurances. What awaits is formless, raw. And there is a crackling excitement in that. No dread of inevitability. No deep-grooved tedium of habit. Just novelty and a long absent sense of infinite malleability humming as current through my nervous system. A sense of freedom sweeps over me, but it's a freedom so overwhelming it is frightening, almost unbearable, incongruously oppressive.

And then in an instant it's all gone: I'm back to the present, my calcifying future restored, the jaded pall of dull predictability draped again over the piled corpses of once overoptimistic ambitions, a quiet trembling in my chest, a tightness in my throat. I suck in a deep breath, slowly let it out, and then all this too passes, settling me back into an uncalibrated equilibrium, coasting down the street and through an intersection, balanced with familiar ease on a measured uncertainty.

github forking

2011-09-09 16:25:23 -0700

I don't think GitHub's default workflow for forking a repo is ideal for my needs. Most of the time when I fork a repo, my aim is to fix something or add a small new feature which I will eventually submit upstream as a pull request. While I am hacking away or living with my modifications for a while before I submit them, I want to continue to be able to easily pull in upstream changes as well. So whenever I fork a repo, I want the following:

  • The master branch will track the pristine upstream master. Whenever I have no changes of my own pending, I can just switch my work tree to use master to keep up with the latest changes with a simple git pull.
  • A volatile hack branch where I work on my changes. This is volatile since I'll regularly be rebasing onto the head of master.
  • A volatile pullme branch where I will put changes that are ready for a pull request submission. I may want to continue to hack away in hack while I'm waiting for the resolution of my pull request, so this is analogous to a release branch. But this is volatile since, for the sake of simplicity, I'll be resetting it whenever I'm ready to submit a new pull request.

(By volatile, I mean that I can feel free to rewrite the history on these branches without repercussions.)

So here's how I go about forking a GitHub repo:

git clone <upstream_repo>         # e.g. http://github.com/mxcl/homebrew.git
cd <upstream_repo_name>           # e.g. homebrew
git remote add fork <forked_repo> # e.g. git@github.com:SethMilliken/homebrew.git
git config branch.hack.remote fork
git config branch.hack.merge refs/heads/hack
git branch --no-track hack origin/master
git push fork hack:refs/heads/hack
git checkout hack

At this point here's how things look branches-wise:

$ git branch -r
* hack
  remotes/origin/HEAD -> origin/master

remotes/fork/master is what the GitHub website uses for it's default branch. I like to clean this up to remove any chance of ambiguity about the name master. To me, master always means the authoritative branch from the canonical repository, never a branch in my fork. Here is how I tidy this up:

  1. Click the Admin button on the forked repo's GitHub page.
  2. Change the Default Branch to "hack".
  3. Delete the forked repo's master with git push fork :master.

If there were a way to name the default branch when you first fork, or to subsequently rename it via a commandline git command, that would simplify things a bit.

To rebase my changes onto incoming upstream, which I do periodically as I'm hacking, and again immediately before submitting a pull request:

git pull --rebase origin master

When I'm finally ready to submit a pull request, here is what I do:

git branch -f pullme hack
git push fork pullme:refs/heads/pullme

This essentially replaces the pullme branch with the current state of the hack branch.

And after my pull request is accepted, I switch back to master.

git checkout master

regenerate missing public key

2011-05-11 17:57:21 -0700 I've had to do this a surprising number of times lately, and have had to figure it out anew each time. So here it is—for my future reference—how to regenerate from your private key the missing corresponding public key in such a way that it is usable in the ~/.ssh/authorized_keys file:
ssh-keygen -i -f <( ssh-keygen -e -f id_rsa ) > id_rsa.pub

hg stash

2011-02-28 21:34:32 -0800

I have become accustomed in Git to using git stash to temporarily set aside in-progress changes in my working directory before pulling from upstream. Whenever I use Mercurial now, I find myself wanting analogous functionality. The Googles don't seem to turn up any decent techniques for this, so I have repeatedly reinvented a series incantations to abuse Mercurial's mq extension to provide it. Yet I always manage to forget whatever trick I used by the time I want to do it again. I finally decided to fix it for good, giving myself hg stash and hg pop, allowing a workflow in a dirty working copy that goes something like:

hg stash
hg fetch
hg pop

Here are the relevant .hgrc lines:

stash = !hg qinit &>2 /dev/null; hg qqueue --create stash-temp && hg qnew stash && hg qfinish tip && hg strip tip && hg qqueue patches && hg qqueue --purge stash-temp
pop = !hg -R .hg/strip-backup/`ls -rt .hg/strip-backup/ | tail -1` diff -r tip | patch -p 1 -R

Breaking it down:

# hg stash
hg qinit &>2 /dev/null              # initialize mqueue in this directory
                                    # ignore error output since this has likely already been done
                                    # (this could be potentially be problematic if there is some other problem)
hg qqueue --create stash-temp       # create a new patch queue so we don't mess with any existing ones
hg qnew stash                       # create the 'stash' patch with the outstanding modifications
hg qfinish tip                      # apply the patch
hg strip tip                        # now strip it (for the side-effect of the backup bundle)
hg qqueue patches                   # switch back to original patch queue
hg qqueue --purge stash-temp        # delete the temporary patch queue
# hg pop
hg -R .hg/strip-backup/`ls -rt .hg/strip-backup/ | tail -1`     # use the strip bundle as the repository
                                                                # finding it with some shell tricks
                                                                # (likely a better, more portable way to do this)
diff -r tip                                                     # output it as a diff
patch -p 1 -R                                                   # apply that output as a patch
                                                                # and reverse patch since we spun things around
                                                                # with the bundle

Your working copy's .hg/strip-backup/ directory could start to fill up if you use this a lot, so you may want to clean it out occasionally. I decided to not have hg pop automatically cleanup the bundle just in case something goes wrong.

And why not just hg diff > stash.diff && hg revert --all to stash and patch -p 1 < stash.diff to pop? That doesn't really handle binaries, and somehow it feels a little too dangerous to me. But, yeah, for the majority of cases that would probably be sufficient. So I'll leave that here, too:

stash = !hg diff > stash.diff && hg revert --all
pop = !patch -p 1

Pentadacytl (or Vimperator) Form Field Editing

2010-03-16 20:05:32 -0700

I have been using Firefox as my primary browser for quite a while now. What held me back from switching initially were two things: 1) unacceptably poor non-native widgets, which have since improved dramatically and 2) no support for the Mac OS X Keychain, which is now available via the Keychain Services Integration extension. But eventually my desire for vim keybindings everywhere pushed me to switch despite these shortcomings. The vimperator pentadactyl Firefox extension allows for entirely keyboard-based browsing, using bindings similar to vim. And even better, it facilitates form field editing using vim via external editor support. So when I want to edit a form field, I type either "gi" (to enter the field) or "f#" (where # is the QuickHint mode number associated with the field; useful if there are multiple fields on the page) then hit Control-i. This creates a new tab with a buffer for that field in an existing instance of MacVim which is always running in the same Space as my browser, so it comes up almost instantaneously. I edit the contents of this buffer using all the goodness of native vim and then type ZZ. Thanks to a couple of autocommands in my .vimrc, this saves the buffer, saves a copy of its contents in a timestamped archive file, closes the buffer, and then hides MacVim, leaving Firefox active with the text I just wrote inserted in the form field, ready to submit.

Here are the requisite pieces of the puzzle:


This is the pentadactyl configuration file. You need to add a line to set your external editor to the script that opens MacVim.

set editor="~/bin/firefox"


Make a symbolic link to your mvim script so that the script can detect the context it should run in.

ln -s ~/bin/mvim ~/bin/firefox


This is the mvim script that comes bundled with MacVim, moved to ~/bin and modified. Add this bit to the 'case "$name" in' statement:

        opts="$opts --remote-tab-wait-silent"


Next, a couple of additions to the vim configuration file to make ZZ save the contents to an archive, close the buffer, and return Firefox to the foreground.

augroup VimperatorYPentadactyl
    au! BufRead vimperator-*,pentadactyl-* nnoremap <buffer> ZZ :call FormFieldArchive() \| :silent write \| :bd \| :macaction hide:<CR>
    au BufRead vimperator-*,pentadactyl-* imap <buffer> ZZ <Esc>ZZ
augroup END

Finally, here is the function that saves a copy of the form field contents to an archive file, complete with timestamp and url:

function! FormFieldArchive()
    let l:contents = getbufline("%", 1, "$")
    let l:filepath = expand("%")
    let l:filename = expand("%:t:r")
    let l:formfielddir = $HOME . "/webforms/"
    let l:currentdate = TimestampText('date')
    let l:entry = l:formfielddir . l:currentdate . ".txt"
    let l:entryexists = filereadable(l:entry)
    exec "split " . l:entry
    if l:entryexists
        normal Go
        normal o
        exec "call setline(\".\", \"" . TimestampText('time') . "\")"
        exec "call setline(\".\", \"" . TimestampText('journal') . "\")"
        exec "silent !svn add " . l:entry
    normal o
    exec "call setline(\".\", \"" . l:filename . "\")"
    normal o
    exec "call setline(\".\", " . string(l:contents) . ")"

function! TimestampText(style)
    let l:iswindows = has("win16") || has("win32") || has("win64")
    if l:iswindows
        if a:style == "long"
            let l:dateformat = strftime("%#x %H:%M:%S ")
        elseif a:style == "short"
            let l:dateformat = strftime("%Y-%m-%d %H:%M:%S ")
        let l:dateformat .= substitute(strftime("%#z"), '[a-z]\+\($\| \)', '', 'g')
        if a:style == "long"
            let l:dateformat = strftime("%Y %b %d %a %X %Z")
        elseif a:style == "journal"
            let l:dateformat = strftime("%A, %B %d, %Y %H:%M:%S %Z")
        elseif a:style == "short"
            let l:dateformat = strftime("%Y-%m-%d %H:%M:%S %Z")
        elseif a:style == "time"
            let l:dateformat = strftime("%H:%M:%S %Z")
    if a:style == "date"
        let l:dateformat = strftime("%Y-%m-%d")
    return l:dateformat

This will create a new file with the current date, e.g. "2010-03-15.txt", if it doesn't already exist. If it does exist, it will add the entry to the end of the file separated by a timestamp. TimestampText() is just a convenience function I wrote that returns a timestamp in various strftime() formats.

[2011-02-28 22:10:12 PST Update: Now using pentadactyl, so updated references appropriately. Added TimestampText() function for completeness. A couple of other minor edits and links added.]

anguish revisited

2008-07-06 02:01:00 -0700

I have returned after quite a while to the careful consideration of Buddhism. Each time in the past when I have attempted to apply Buddhist principles to my life, it has been a rewarding and beneficial experience. But one of the immense hurdles to this way of thinking is that it is not a way of thinking. If egocentricity is what is ultimately responsible for suffering, and thinking over something rationally is a manifestation of egocentricity, I'm in a poor position for eliminating suffering—and furthermore have been deliberately, methodically entrenching myself more and more deeply into this mire for most of my life. And ironically, this evaluation of my situation is simply yet another example of the very sort of distraction from awareness of the present that it is itself criticizing. Measuring, evaluating, and judging are tools I have long relied on for making decisions. I have valued a propensity for thoughtful, impartial, thorough deliberation as a most admirable, invariably worthwhile trait. It appears that this is going to be tremendously hard for me to let go of; extensive, elaborate thinking is what I have depended upon on most heavily for directing my actions. How can I simply abandon this vast investment, and on little more grounds than a peculiar variety of faith? What's more, doesn't the persuasiveness of exercising this faith derive from arguments directed at reason itself? Isn't that suspicious? Is suspicion just another of distractive contrivance of the ego? Is this entire discussion just a way to avoid further reading?

elevator anecdote

2008-05-31 23:59:59 -0700

The elevators in the building where I work have a long history of being unreliable. I work on the sixth floor. Until recently, the two floors below were home to a company that developed MMORPGs, Perpetual Entertainment. Sometime in the middle of last year, I was riding up in the south elevator with one of the Perpetual employees when the elevator suddenly lurched and then stopped. And stayed right where it was. We discovered by prying the elevator doors open that the elevator was nearly—but not quite—on the fifth floor; but the doors between the elevator and the floor would not open. However, we did notice in our survey a lever well beyond reach that we suspected would release the doors. Eventually we were able to contact the security guard at the front desk by cell phone and he arranged to have someone come out to fix the elevator and get us out, but it appeared that this would take more than a half an hour at best. Meanwhile, there was a very loud, almost unbearable alarm going off in the elevator. Annoyed at the alarm and impatient with the delay, the Perpetual employee vowed to take action. I resigned myself to being stuck indefinitely. But the Perpetual employee grinned widely and drew from his backpack a genuine, full-scale, tempered steel longsword. He gleefully brandished the weapon, then reached up and prodded the release catch on the doors that we had seen earlier. We crawled out, leaving the alarm sounding in the elevator for another couple of hours.

what was the question?

2008-04-02 01:35:00 -0700

I have been thinking a lot lately about thinking. In particular, about the way in which our predispositions of perception, cognition, and experience broadly affect the types of thoughts that we tend to have, and consequently form the unique ways we each understand the world. I should note that the uniqueness of this understanding really applies only to all of a person's ideas as an aggregate. For it seems clear that we are capable of communicating with others, that the transmission of individual ideas is indeed possible. If you think that you know what I mean, even if you disagree, then you accept this premise. All I am getting at here is that although we may never be able to understand one another comprehensively, many of us can still come awfully close to a common understanding of innumerable particulars. One of the impediments to this sort of common understanding is an inability to conceive of—or misapprehension about—how another thinks. Investigating and subsequently understanding the ways in which we differ in our conceptions of the world and its contents, and the mind and its contents, can help us correct for these very discrepancies. Systems of classification, taxonomies, are often the result of such investigations, and sometimes even provide the means for them. If we can independently agree about which category a thing or idea fits into (and why), this is often a sign in itself of a shared understanding. But the criteria of classification have to be meaningful themselves. Otherwise our agreement is meaningless.

And some taxonomies are more successful in this way than others. When it comes to reflexive classification in particular, we as a species have had questionable success. It seems at once strange and inevitable that the criteria of classification of personality types, for instance, are so contentious. Judging by the sheer proliferation of various systems of personality type classification, it seems we don't understand ourselves enough to agree on which characteristics are sufficient to cleanly delineate our similarities and differences. Admittedly, the subject under consideration is one quite vast and complex. And perhaps each system is focused on what are simply different nuances of an incredibly monumental, multifaceted nexus, such that to some degree the systems are not necessarily in contention at all. Nevertheless, as far as I can tell, there is no widely accepted, unproblematic standard for identifying unambiguous sets of interrelated personality traits. And I'm sure there are further cross-cultural complications of which I'm only dimly aware. We do employ some broad, colloquial differentiators that for the most part lack any sort of rigorous definitions (and incidentally these seem frequently to be presented as mutually exclusive dichotomies rather than sentinels on a continuum): introvert vs extrovert, intellectual vs emotional, serious vs lighthearted, considerate vs rude, strict vs liberal, confident vs shy, masculine vs feminine, etc. Even as I write these down, I feel like their meanings are shifting and subjective, and they're arguably poor examples. But what constitutes a good example here? What are some truly meaningful ways to characterize and identify what makes up each one of us in such a way as to have enough granularity to achieve precision, but without going too far? 6,658,694,324 divisions is too many for all but one statistic. Two begins to be more meaningful, but falls short of offering much understanding beyond the superficial. What enumeration of cross-sections of characteristics is worthwhile without being oppressively unwieldy? I guess the particular question one poses is critical to answering this.


2008-03-01 00:09:00 -0800

Most people I know well already know these things about me, but I realized that I haven't collected them all into one place and commented on them as a collection. And maybe I'll surprise someone who thought that they knew me. Here is a list of things that I am confident that I will absolutely never do voluntarily, however many days longer I live: drink alcohol, smoke, take drugs recreationally, get a tattoo, get a piercing, believe in God, have children, deliberately harm myself, or chew gum. And when in doubt, I will always choose left. All of these are purely personal decisions I have made for myself. I do not pass judgement on those who have decided differently for themselves; all of my life experience has convinced me of the impossibility of any sort of practical objective universal morality. Some of my choices are an indirect response to the self-righteous who might insist otherwise, some are almost completely arbitrary, some are simply promises I will never break. I find it edifying to maintain a diverse set of dictums to which I am utterly committed, but which have radically different motivations. Now if only I could apply the same stubbornness and certainty to other, more immediate, aspects of my life.

some goals and stuff

2008-02-12 00:54:00 -0800

Tonight Tadhg suggested that I stop letting my long-term personal goals float aimlessly and incoporeal through my fickle, inconstant attention. Maybe write them down or something. Maybe define them in stricter terms than, “Do some stuff and stuff before sometime later.” This seemed like a reasonably good idea. Committing to substantial, sustained goals that stretch further than tomorrow night is not something I have done much of lately. Stretching further than a couple months is a true challenge. So, setting some objectives for the calendar year seemed a good start.

Here was my first pass at these goals:

  • read some stuff
  • get into some vague sort of shape
  • write some code
  • invest some money
  • play some guitar

Woohoo! Looks great to me! But for some reason, Tadhg found these unacceptable and insisted I develop them further. Boo. So I fleshed them out like so:

  • finish reading a specific number of books (at least)
  • get into shape enough to be able to perform a specific number of repetitions of two particular exercises
  • complete the first functional versions of three particular software projects
  • invest a specific amount of money (at least)
  • play guitar for a specific number of hours (at least)

I'm going to keep the particulars and the specifics to myself for now. I also have plenty more immediate goals I'd like to accomplish and scores of other good habits I'd like to develop or reinstate. But many of those things I could potentially do in much shorter spans of time. Each of the things I've listed here will require regular attention over a long period of time. I intend to spend some time every day for the rest of the year working on at least one of them for a little while.

duck herding

2007-12-31 16:17:30 -0800

As the end of 2007 approaches, an incomplete overgeneralized summary of the year is certainly in order, right? Broadly speaking, it seems that I have finally been getting all my ducks in a row. Okay, maybe just a lot of them. And maybe not precisely in a row, per se. Hurtling through the year, I started a lot of projects and developed the means to start others, but for various reasons did not follow through. Now I feel like I'm getting much closer to having the ability to follow through. I got renter's insurance. I started backing up my computers regularly. I have been exercising regularly. I have become noticeably more proficient at my work. I appear to have found a solution to a debilitating problem that has plagued me for most of my adult life, and have overcome my stubbornness enough to embrace it. I have actually been putting to good use most of the gadgets I bought this year. I have been getting in contact with old friends and acquaintances. I have been more reliably enjoying playing guitar (when I do, at least). My overall attitude and disposition have been improving.

There are some things I have identified that would probably help me going into the next year. Do my dishes right after I use them. Netsurf less. Watch less video. Exercise greater self-discipline when it comes to gaming. Resume running regularly. Switch to posting on the first of the month rather than the last of the month. Establish designated places for storing things. Make a greater effort to keep in touch with people. Spend more time with friends. Write more often. Read more often.

ypbind problem

2007-12-02 19:31:00 -0800

After upgrading to Mac OS X 10.5 Leopard, my logs were getting spammed with the followoing error:

com.apple.nis.ypbind: Domain name not set. Aborting.

Deleting the /etc/defaultdomain file fixed the problem.

words on facebook

2007-11-30 07:05:47 -0800

I had been thinking about writing something about Facebook for a quite a while. Cory Doctorow's recent article prodded me just enough to actually get around to it. His basic premise is that Facebook, like all social networking sites, is doomed by its very nature to fail. I disagree. This is in part a response to that article, and in part an exploration of my own thoughts.

email notifications and message editing

Doctorow takes issue with Facebook's "steady-stream" of content-free email notifications. I will acknowledge up front that this is a tactic that I often find annoying with other services. Sure, they're primarily there to draw people back to the site and drive up the hit count. But I already refresh Facebook regularly in my browser or on my iPhone, and I don't think this is an atypical usage pattern. With the high frequency and typically diminutive amount of content in most Facebook updates I really don't think email is an ideal delivery mechanism anyway. Viewing the updates in context on the site is a much better experience. I've turned off email notifications for almost everything. But I do like that there are a decent amount of orthogonal email notification options. Perhaps the primary issue is that so many of them are on by default.

He also criticizes reading and writing of messages via Facebook. My god, how can this man not be aware of just how many hordes of people use a web-based email system as their primary user agent! I'm not saying it's pretty, and I'm not saying that it doesn't fill me with nausea at the very thought of it, but the masses of people that will collectively decide the fate of social networking sites like Facebook seem to be quite content with—or at lease acquiescent to—this means of composing messages.


Doctorow's dig at Eudora as a comparably poor messaging environment is flatly ridiculous. I have been trying for ages to find a better email client. The list of things that Doctorow slams Eudora for—composing, reading, filtering, archiving, and searching—are some of the very features that have made it impossible for me to give it up when I fail to find adequate implementations of one or more of them in other user agents. Sure, Eudora has it's share of bugs, quirks, and idiosyncrasies, but for being an end-of-lifed app, it still kicks the butt of everything else I've seen, on any platform. I invite anyone to please, please prove me wrong about this!


This is always a tricky one, but as far as I know there currently isn't anything approaching a feasible business model for sustaining a no-pay, large-scale, ad-free, information-based service. At least not one that would fly here in the States. So far Facebook has done its advertising tastefully and hasn't yet done anything overtly loathsome. Yes, Facebook provides a useful service, and yes ideally it would always be completely free in all ways. But developing new features, providing support, and maintaining an increasing infrastructure sure as hell ain't free for them, so there's got to be some quid pro quo. And I'd be surprised if anyone thought that making it a for-pay service would do anything but immediately undermine its popularity and thus utility.

As conflicted as I am about the motivations of the company that pays me to write code, I've got to say that if I've got to look at advertising I would much prefer well-done targeted marketing to an indiscriminate barrage of repulsive spam. (BTW, I clicked on the link he provided in his article to a Times Online article, "Facebook shrugs off privacy fears with plan for targeted advertising" and got a both a pop-up ad window and a floating css ad window in the middle of the page that I had to dismiss in order to read the article it was obscuring. Sure makes the sidebar banner ads and occasional, innocuous news feed ads on Facebook seem a lot less objectionable to me.)

laws and cluesticks

Doctorow alludes to the possibility that social networking sites may be more subject to Brook's Law than Metcalfe's Law, but he makes no further effort to explain or substantiate this. Red herring or laziness? How does adding people to your social network impede the intent behind having that social network? Hell, as I think about it, even the invocation of Metcalfe's Law is suspect. Certainly it applies to a social network as a whole, as the greater number of subscribers there are the greater the pool of people you can potentially add to your list. But once in the milieu of individual friend lists, the mechanics become radically different. You're no longer talking about point-to-point networks, you're talking about broadcast networks. Each node is not just a potential edge, it is an edge. And this situation starts to introduce problems, as Doctorow points out with with his "boyd's law" examples. But this is not the problem itself, it's a symptom of it.

People have been changing the way they interact with social networking sites. We've been adapting our habits and sites in turn have been adapting their features to accommodate the varying levels of comfort we have with sharing information about ourselves. I think Doctorow really needs to more deeply explore why people do use social networking sites. For a guy that has his own blog and seems to have a lot of cachet on the internets as being a froody tech hipster, he really just doesn't seem to grok the essence of social networking at all. Maybe he's become too celebritized to identify with net proles and comprehend their trifling amusements.

the rejection problem

How do you effectively deal with that perennial social networking problem wherein you receive a request to add someone to your network whom you know in passing but don't really want all up in your business? You don't want to be rude, but you also want to be able to hang out candidly with your tight peeps? The crux of the rejection problem is that most social networking sites do not offer sufficient granularity to reflect the various levels of intimacy we have with different people in our lives. There are things you tell your lover that you don't tell your family, things you tell your family that you don't tell to certain friends, things you tell to some friends that you don't mention to your coworkers, and things you say to your coworkers that you don't bring up in a conversation with an old acquaintance you happen to run into on the street whom you like well enough but who is not actually likely to catch up with you sometime nebulously later for drinks somewhere. And it works the other way, too. You might mention something to someone that you haven't seen in a while that would just never occur to you to verbalize to those in your more intimate circle because, for instance, by virtue of being close to you they have already effortlessly shared the very experience you must now labor to articulate.

So, currently, rejecting someone from your social network is something akin to refusing to even acknowledge that remote acquaintance if you happen to run into them on the street. Or like snubbing a coworker who invites himself to come along to a movie that you're going to see with a bunch of other folks from the office. For most people these types of responses would be indefensibly rude or at least impolite. On the other hand, it would take an unusually audacious coworker to invite himself into your hot bi-curious orgy. Or a shockingly presumptuous acquaintance to tag along while you get yourself tested for STDs. I think here most people would understand if you were not so decorous in your responses.


If a reasonably well-adjusted person in meatspace doesn't interact with you very often or very deeply, they generally do not presume to be privy to your daily agenda much less your innermost secrets. Why should it be significantly different online? I contend that it's because the social networking technology currently available for communicating those nuances is far too coarse. A person is either in or out. Binary simply doesn't work as a social model.

Now, Facebook has already made some progress on providing a little more granularity here. First, you can outright block particular people from searching for you, seeing your profile, or contacting you. The next level is that you can designate some people as having access only to a limited version of your profile. Further, you can adjust to a fairly good degree which aspects of your profile this limited group will be able to see. Nevertheless, this limited profile itself suffers from false dichotomy. You can't create multiple limited profiles each with different settings. But this does seem like the beginnings of a tactful way to start to model typical meatspace social conventions online. An observant casual acquaintance may notice they're not seeing your "currently online" status in their feed, but they're not likely to be too upset by that as they would be have to be a bit dim not to acknowledge that they are not a part of your most intimate circle—and besides maybe you have your online status indicator turned off globally. Moreover, and this is critical, this restriction is not visible to anyone else in your list. Apart from what you explicitly reveal in communication outside of details the site itself presents, each of your friends appears to the others equally, simply as being associated with you. Yet you retain full discretion about what details and updates you reveal to whom.

But this sort of fine-grained system of disclosure can't be too difficult or unwieldy to manage, or potential users will be put off by it. I'm sure there are some fastidious folks who will absolutely delight in endlessly tweaking a massive array of cool new digital knobs that correspond roughly to the social conventions we regularly improvise effortlessly in meatspace. But I suspect that for a far greater number, a more likely scenario is closer to wanting to have full confidence that the regular updates they are posting about their wild nightlife activities are not going out to that creepy ex-boss they felt compelled to add to their list.

Here's an idea. Many social networking sites are already starting to flirt with features very similar to the now-standard ecommerce feature of "other people who have bought this item have also bought these". Why not borrow patterns from other webapp archetypes as well? Apply to social networking sites the same basic principles behind the reputation systems developed for auction sites and user-moderated discussion boards. Track the number of direct interactions between each of the members in the social network, then give users the ability to use this data to moderate what is available to each person in their list. If somebody has sent you five messages, and you have sent them only one, maybe they don't see updates about your relationship status. On the other hand, let's say you've gotten 129 messages from another friend and sent them 143; maybe each of you can chose to get an alert while you're browsing your profile and the other logs in. Getting something like this working well would certainly take some work, but I can imagine it eventually being not unlike training your email spam filter, adjusting your Amazon recommendation preferences, or your Last.fm music tastes.

sometimes it's healthy to forget

Just as in meatspace, inevitably there will be ample opportunities online for gaffes, regrettable indiscretions, awkward situations, and unwelcome intrusions. Welcome to life. Social networking sites will not somehow provide exemption from basic human ineptitude. Yet stuff online does tend to linger a little too morbidly. Those idiotic comments you posted on a major technical help site in desperation way back when you didn't have any idea how the hell to quit vi now show up as one of the top hits when your prospective dot com employer googles you. That extraordinarily cheesy poem you injudiciously plastered all dewy-eyed on your homepage in college is now archived forever in that vast series of tubes for all otherwise prospective love interests to discover and use as grounds for pursuing no further contact with you.

And you know what, I think Facebook even has a start on ameliorating this problem. Whether this is by deliberate policy or by fortuitous technical (or aesthetic) limitations, I can't say for certain, but it used to greatly annoy the completist in me that older items appeared to just fall off your profile into oblivion. But I am starting to really appreciate this and now even consider it a to be a feature. If you slip up and say something off-color at a company party, that little impropriety will likely only last as long as coworkers are interested in retelling the story. Generally after a few days, maybe weeks, it will dissipate into the countless eddies formed by the perpetual precipitation of new events. Yeah, maybe at subsequent parties at the same time of year someone will recollect that you embarrassed yourself and imperfectly describe the incident more sparsely and less precisely each time, but for the most part it's not even worth a footnote in an already unwarranted biography. A digital version of this event horizon is not unwelcome.


Facebook could certainly screw up the relatively good thing that's its got going right now. They could make poor decisions that alienate their user base. They could fail to make enough money to sustain the service without irrevocably compromising its quality. So I'm not saying that Facebook is the be-all end-all of social networking sites. I just don't think much of what Doctorow is claiming as reasons for its immanent demise are fatal characteristics necessarily inherent in all social networks. The greatest danger to Facebook is that someone might build a better one.


I'd like to encourage anyone who uses Facebook to invest some time in exploring the privacy settings, especially those of you who would genuinely like to use it more frequently and more extensively to keep in touch with close friends but feel uncomfortable or unwilling to share particular aspects of yourself with the less intimate acquaintances you've reluctantly included on your list. The link is right there on the top right, next to the logout link. There's quite a lot of great functionality hidden behind that little unassuming link. And among these tools that might help you to negotiate some of the more delicate social networking minefields, there are some that fortuitously provide handy ways to keep your profile page less cluttered as well. I think a lot of people overlook this section because they assume it's a link to yet another privacy policy legal boilerplate; I did initially.

universal access zoom feature finally fixed

2007-10-31 17:53:50 -0700

Prior to Mac OS X 10.5 (Leopard), there was a bug that made using the Universal Access zoom feature (accessible by default with Option-Command-8) useless in a multiple display configuration in which the virtual heights of the arranged displays differed. As soon as you activated the zoom feature, the portal created by your displays would lock essentially to the height of the primary display, making it impossible to scroll to the portions of the virtual screen that mapped to the higher or lower displays, and in some cases you couldn't even see the menu bar. Basically, you could pan horizontally across your virtual screen, but not vertically.

This might not make any sense to you if you never tried this yourself, but they fixed this in Leopard and I'm happy about that.

mac os x instant display sleep rant

2007-10-31 17:29:51 -0700

Why is it so freaking hard to bind a keyboard shortcut to putting the displays to sleep immediately in Mac OS X? In the classic Mac OS, there was a hot key that did just this, at least on PowerBooks (I can't remember exactly what it was, and I don't think it was remappable, but it was there). Whenever I stepped away from my PowerBook or didn't anticipate needing to use it right away, I could tap those keys and the backlight would instantly shut off, saving some precious juice. Nowadays, my laptop usage patterns are a bit different and I don't tend to need to squeeze out every last minute of battery life anymore. But on the desktop machines I use regularly, which have no fewer than four displays connected to them, I want to be able to put all of those displays into power saving mode immediately. The main reason is so that my bedroom isn't lit up like a Christmas tree when I want to go to sleep, but I also prefer not to waste power needlessly and hope to maybe get a little more life out of the LCD backlights by turning them off when I'm not actually using them. Let me note here that even with a black screen, LCD backlights still generate a fair amount of light; the displays really need to be off. Another factor is that not all of the displays can be plugged into the same power strip, enabling me to turn them all off and on with a single flip of a switch (e.g. Apple Cinema Displays get their power directly from the computer they are plugged into). And anyway I prefer to have a uniform mechanism for controlling display sleep regardless of which machine I'm using and whether the energy saver settings have put the displays to sleep or I have done so explicitly. Besides, it's nice to be able to just hit a key on the keyboard to wake up the displays. I think that covers the reasons why I want this feature, and hopefully preempts some of the not so helpful suggestions I've seen other netfolk offer in response to similar pleas.

Prior to Leopard, I had a shell script that looked like this:

$PMSET force -a displaysleep $MAGIC_NUMBER
$PMSET force -a displaysleep `$PMSET -g | $GREP displaysleep | $AWK '{print $2}'`

I was able to use a QuickSilver to bind execution of this script to a function key and I was mostly happy. It executed very quickly, and did just what I wanted it to do.

But as you can see, this script relies on a magic number—one that is undocumented and is possibly even the result of a bug. Now that I've upgraded to 10.5, this magic number no longer works; the script does nothing. Without a working magic number, the best you can do with a script like this is have the display sleep after one minute (the lowest effective pmset displaysleep argument is 1; 0 disables display sleep altogether).

Leopard introduces a new feature that allows you to bind a screen corner to "Sleep Display". So now this instant display sleep feature is explicitly supported in the operating system. Sort of. As far as I can tell, there is absolutely no way other than the hot corner to access this feature. Nothing in AppleScript, nothing in pmset, nothing in keyboard shortcuts, no menu item, no hot keys documented or otherwise, nor even a system level API that I could use to write a stupid little Cocoa app. I hope I am wrong; this omission aggravates me much more than it really ought to.

UPDATE: Malcolm Hall has come to the rescue with SleepDisplay.app. Thank you, Malc!

on catfish curry and flat tires

2007-10-21 21:11:12 -0700

if you ever find yourself in the situation of having burmese catfish curry leftovers in your backpack, i strongly recommend not keeping them there overnight. playing guitar for eight hours straight is much more rewarding than an occasional five minutes of languid pentatonic noodling. if you see a car driving down the street with a cane on the top of it, the driver will most likely be grateful if you ride your ass off to catch up with them at a stoplight, tap on their window, and present said cane to them; but be prepared for a surprised or frightened look when you first tap on the window. this one has yet to fully sink in for me, but the possibility of indefinite preservation does not necessitate it; ephemera have a definite place in our lives (even if only for a little while). poor memory seems on the whole to make life less interesting. a tiny, 2mm sliver of wire smaller in diameter than a garbage tie is sufficient under the right circumstances to cause a flat tire on a mountain bike; carrying a bike pump and a $20 bill on my weekly rides has proven to have been a good practice.

in absentia

2007-09-30 13:21:19 -0700

I am sitting on a couch in the Haber home struggling to identify a thought around which to organize this entry. My ten year St. John's class reunion seems an obvious focus, but I don't feel that I have anything interesting to say. The inferences one might draw from this statement quite likely do not provide an accurate reflection of my experiences this weekend, but it is certainly consistent with how I have been feeling for the last couple of months. My interest in my own thoughts is exceptionally low right now, so it takes quite an effort for me to share them, to presume that anyone else could possibly be entertained, amused, or informed by these fleeting, ill-constructed, inadequately considered heaps of almost random words. If I am annoyed at my own voice, why speak? The commitment I made to write here at least once a month has managed to compel me to make an attempt, even if it is unsupported by my current sentiment and reason. Sadly, this does not come packaged with inspiration and substance. I'm stuck in my head, but there seems to be so little activity here.

dad and heidi visit

2007-08-30 19:42:00 -0700

Dad and Heidi came out to visit earlier this month. We had a great time. Aside from the usual regimen of just hanging out and talking, we rented bikes and rode through Golden Gate Park to Ocean Beach, went to the San Francisco Conservatory of Flowers, toured the USS Hornet, watched most of the first season of Eureka, ate at some of my favorite restaurants in the City, and Karen took Heidi boogie boarding with Jenn and Chris. But the highlight for me was our trip to Sequoia National Park. I booked a cabin at a fairly remote campground and we all spent a few days relaxing, driving through mountains on windy roads, hiking through the sequoias, and stargazing. Dad had rented a telescope, and with a tripod we borrowed from Tadhg we were able to take some decent pictures of the moon with his new digital camera. As with seeing real sequoias versus photos of them, looking at Jupiter, the moon, and other celestial objects through the telescope is quite a different experience than seeing photos. I now have a much greater appreciation for my dad's love of astronomy.

I'll try to post photos soon.


2007-07-31 11:59:59 -0700

somehow on the way over to cup-a-joe i completely forgot what i had decided to write about. i do remember that it did not have a whole lot to do with anything that i have been predominately preoccupied with lately. this happens a lot, but usually not over the course of fifteen or twenty minutes. i guess it's fair to say i am a bit distracted. i am having trouble focusing on anything right now.

i have been listening quite a bit to the track "the falcon's cry" on zero hour's most recent album, specs of pictures burnt beyond. and i just now noticed the tipton brothers are from san francisco; i had assumed they were nordic or something because most good progressive metal these days is scandinavian, right? got the new kamelot and symphony x albums as well, along with a couple more savatage albums, another nightwish, and another crimson glory. and all of this because i wanted a usb ethernet adaptor for my zaurus. damn you, amazon.com!

i have been spending a lot of time at work. the more time i spend at work, the greater need i feel for time for myself, and generally this has the ironic result of my my wasting less time overall. i have been reading a lot of technical material, mostly on the topic of software development. i have been writing a lot of code in my own time, and doing a lot of maintenance on my computers. i have not necessarily been doing the highest priority tasks first, but i'm getting a lot done. and now i remember what it was that i had been thinking about writing about.

preserving state. i currently have 29 windows open in my email program, eudora. i have 52 windows open in my web browser, camino, each with an average of about 5 tabs in them. in my text editor, vim, i have a session with buffers open in a dozen tabs. i have multiple screen sessions with about five windows each (to say nothing of the profusion of windows in screen sessions on all of the other machines i use regularly and have access to). all this, and my current uptime is only about five days. mac os x 10.4.10 has been one of the most unreliable updates i can recall, and i have had to reboot much more frequently than i would like (i would like not to have to reboot at all, but only after major system updates would be—and has been—fine). yet, with the features of the programs i use together with scripts i've written over the years, a crash or a deliberate restart no longer has as much of an impact on the state i have on the machines i work on. i rarely if ever lose data anymore, and now the configuration of my virtual environments is fairly stable as well. for most environments i use regularly even if i don't have executable scripts i have checklists that i can use to walk through getting everything set up just so. and yet i wonder if this all comes with a veiled disadvantage in that there is no longer any semi-regular event that involuntarily clears the slate for me. it used to be very easy to just let go of all of the unread pages i had open in my web browser when it crashed because there was nothing i could do about it anyway; now i don't have to let go, but i don't always get around to actually reading everything i have open. so now i'm accumulating digital clutter to rival the clutter i surround myself with physically in the form of unsorted mail, papers, books, discs, magazines, and gadgets.

on the other hand, this preservation of state has been helping me immensely at work. i have been more organized and productive at work than i have been in a while. i just need to start using the tools and techniques i have been applying on the job to my personal life, and i think i'll be better off.

i was interrupted while writing by a pleasant conversation with a couple of educators from denmark. we talked politics, weather, earthquakes, dry standpipes, camper travel, and multilingual tendencies of europeans.

i have been seeing a large number of discarded televisions in the streets lately.

there is a cat that i run across in the vicinity of the vallejo steps that must be getting awfully annoyed with me by now. i scare it away at all hours of the night. i have not yet missed a run.

earlier today i bought an apple airport extreme base station to replace my crappy linksys befw11s4v4 that flaked out on me one time too many. so far the only thing i miss is having one extra ethernet port, but i don't really need it right now anyway. and meanwhile, the airport is so much nicer to configure. i had absolutely no problems with it at all. in the way that mac os x is to windows, the ipod is to other portable music players, and the iphone is to other cell phones, the airport is to other wireless routers. it's the attention to details, and the right details at that. i even plugged in a spare 30GB drive just to see how the usb drive sharing worked. not only did it just work, it prompted me to mount the new drive on my laptop. i would have preferred firewire, but oh well.

macports has definitely become my preferred port system for mac os x. it is just so much cleaner and more intuitive than fink ever was for me. i just trust it more. now that it has all the ports that i used fink for, i think i'm going to get rid of fink altogether.

i like vim. a lot.

a touch of madness

2007-06-29 06:11:54 -0700

i have been working some late nights this month finishing a project important to my employer. although the deadlines can be stressful at times, i feel like i am finally starting to improve my craft noticeably. i am getting into a rhythm with writing code and establishing good habits. i still have some difficulties focusing as well as i would like to some days, but once i get in the zone i really enjoy it and want more. and anyway some of my best hours are between 22:00 and 03:00. so tonight i got home around 04:30. i put my things away, got ready for bed, and then put on my gear and went for a run.

a what? huh? when? you? sure, it's been oh say about ten years since i did this regularly, but what's a decade between exercising good habits? or good exercising habits. or whatever. so this was the sixth premeditated run i've completed in a row. i run two times a week for about twenty minutes around my neighborhood. if you've been to my neighborhood, that probably means a little more to you. suffice it to say, there are a lot of hills. i like to listen to music as i am running. this morning i was listening to the rodrigo y gabriela album tadhg gave to me earlier this week. their cover of metallica's orion is pretty incredible. and that got me up the steps at vallejo and taylor. earlier this week as i approached the top of those stairs i was listening to dream theater's the dark eternal night and labrie had just sung the lyric "...climbing endless stairs...". haha. at the top of those stairs, i usually turn right and head down towards green street. halfway down the hill, the view previously obstructed by trees clears and you can see (well, during the day) an amazing view of alcatraz. so i think i might just be able to keep this up. even if my zeal to keep my schedule may be a little crazy.

i need to post more photos. the brunch karen and i hosted recently was a great success, and there were some fun pics from that. i have another series of hawk hill photos. i promised to scan the photos chris took ages ago. i told rana i'd put some on my sjc alum page. and who knows what other miscellaneous randomness lurks in the bitrotting digital jungle of my desktop.

i am looking forward to a visit from dad later this year and hopefully heidi as well. the only sibling to visit me in california so far has been jorgen, and that was about nine years ago. note to family: i can help with expenses and provide a place to stay. sometime in the next five years, i'd like to have everyone out here at least once.

i had some other things to say, but i've been up for almost twenty-four hours now, and i'm beginning to trough again.