“What’s Fred Using?,” the “back from the ashes” edition.

 

Yesterday my Mac’s filesystem had a bad day.  Not just an, “I don’t want to get up this morning day,” kind of day but the kind of day that ends screaming on the roof, hostage in hand, while the police try to talk you down on a megaphone and the SWAT team creeps around from behind to administer the final solution.

This is the first time I’ve seen Disk Utility give up and say, “Sorry bro, I can’t fix this.  Back up what you can and run for your life.”  No matter, I make backups and most of my data is sync’d with remote services and systems.  Two hours later, I’ve got a freshly formatted Lion system and a small handful of irreplaceable backup files.

And I’m standing at a crossroads: restore from Time Machine, or start from scratch and copy what I need?  I decide to go the road less traveled and start with a blank slate.

It was actually liberating to realize how little I need outside of my ~/.vim and ~/.vimrc, and how easy it was to grab those pieces using GitHub & Mac Homebrew.  I accidentally lost my SSH config but, no matter, I took ye olde backup (that thing was dusty) and stripped out everything but the dozen-odd hosts that I care about connecting to.

 

Here’s what I installed, in approximate order:

• Factor (http://factorcode.org).  I can’t live without a Factor environment on hand.  I love Factor and have a few indispensible personal tools I’ve written with it.

• Dropbox — no explanation needed.

• 1Password — the keys to the kingdom.

• XCode Command-Line tools.  A few hundred megs vs. the full install, and I don’t do Mac or iOS app development.

• Mac Homebrew — cure for the bad old days of Fink/DarwinPorts.

• GitHub for Mac.  At first I thought it was gimmicky, but being able to click “Clone in Mac” from the web browser any project and have the repo on my hard drive seconds later is too awesome.

• Tapped the homebrew duplicate repository and compiled the latest Vim.  Why didn’t I use the vim that comes with Mac OS X?  No clipboard register, that’s why, and I like my vim with all the fixin’s.

• fish (via brew) — my favorite shell for home.  Universal variables, friendly colors, and intuitive command line completions make me happy.  Setting PATH to prefer the brew versions of utilities over the built in ones is as simple as `set -gx PATH /usr/local/bin $PATH; set -U PATH $PATH` — no config files to fuss with.

• Spotify — Gotta have music.

• NetNewsWire — Feed me.

• Cloud.app — instant screenshot uploads that put the link on my clipboard.  What’s not to like?

• Alfred (alfredapp.com) — Won my heart after LaunchBar.  Hotkeys for all of my most used apps.

• Propane (propaneapp.com) — such an awesome app.  Completely worth $20, I keep it open to chat with my team whenever we’re working.

• Chrome — which, with the profile associated with my work account, downloaded

• Sparrow — This was an interesting decision.  I’ve used Mail.app for a long time but have gotten sick of its bloat and slowness.  I decided not to restore my multi-gig mailboxes (it’s all on Gmail/Google Apps anyhow) and use a lightweight client.

 

The main feature keeping Mail.app in my toolbelt was S/MIME (encrypted) email support, but I found an acceptable replacement in the S/MIME support in iOS 5, for the few times I need to read and reply to a sensitive email.

 

Things that I love about Sparrow:

• Gmail keyboard shortcuts (hjkl!)

• Wicked responsive.

• Growl notifications

• Easy to quickly reply to email from friends or team members who need a timely response.

 

• TextExpander — I have some cool abbreviations that are now hard-wired to my fingers, so I gotta have it.  My useful abbreviations were in Dropbox so it took no time to get it going again.

• NValt — a version of Notational Velocity that has some cool tricks like Markdown formatting.  Discovered by accident when I went to reinstall NV.  So far, I love it.

• iTerm2 — it seems a little faster than Terminal, and it makes pretty colors with Solarized (link).

 

Things I got rid of:

• MacVim — nice, but since I’m always swapping between a terminal window and vim, why not just run vim in the terminal?  With the “all the fixin’s” version I built and iTerm I have mouse and clipboard support, so there’s reason to use it anymore.

• XCode / Developer stuff.  I need a gcc/clang toolchain, not a full iOS development environment WITH documentation AND examples.

• A lot of cruft that’s accumulated in the form of checked out projects, dotfiles, prefences, apps and brew packages that I don’t, preference panes that do various unauthorized things to the underlying parts of OS X.  I don’t even miss them.

• All told, 25G of crap that I wasn’t using.

I guess that it’s not such a minimal list after all, but the environment feels and lightweight and fast.  Maybe not awesome (awesome.naquadah.org) on Arch Linux fast, but fast.  With the SSD I upgraded this MacBook with last year Lion is as quick as ever.  But is it quick enough?  Of course not!

Out of curiosity I disabled swapping according to this tip (http://hints.macworld.com/article.php?story=201106020948369).  Since I’m not running Mail.app and have traded down in terms of memory-hungry apps, I figure my 3GB of RAM should be enough.

Reboot, and it’s like magical gnomes climbed inside my computer and made every chip 10x faster.  Holy wow.  All of the frustrating slowdowns from the past few months? GONE.  Any hint of slowness?  Banished by a passing breeze, a breeze that smells like awesome win.

You know, it’s all about responsiveness.  A 2GHz CPU and 3G of RAM doesn’t mean anything if the machine randomly hangs when I’m doing a task.  When I press keys and move the mouse the computer needs to DO something, NOW.  This is something that Apple has always cared about and it’s still one of the best things about my Mac.  It’s in Jef Raskin’s seminal work on user interface design, and it’s considered a primary feature of an interface.  If a tool doesn’t respond right away when I use it, then I hate the tool.

Right now?  No hate baby, nothin’ but love for my new/old rig. :-)

 

Posted in blag, Uncategorized | Tagged , | Leave a comment

“Remembering Steve,” or “20 years of the Happy Mac”

It started with something called an “Apple II” in a darkened room at my elementary school. Oregon Trail, Odell Lake, turtle graphics, writing our first stories and printing them out.

HyperCard, hours making flipbooks and puzzling through scripting on my salvaged Mac SE 30 (30 for 30 meg hard drive). Happy times spent with my friend who is also gone building new worlds, bending the machine to our will, fueling our imagination.

It’s what I used to write my first newsletter, print and distribute it to my 4th grade class. The first time I’d ever see a CD drive or play a multimedia game.

The first computer I seriously wanted: a Color Mac Classic. The first time I started saving my money to buy some new hardware. (Only $600!)

Continue reading

Posted in blag, thoughts, words | Tagged , , , | Comments Off

Copy and Copy JSON: essential Listener hacks.

Something I’ve really wanted in the Listener for a while is the ability to right-click and copy a string to the clipboard. I’ve been working around that by having my own “>clipboard” word that places a single string argument on the clipboard — extremely handy for debugging long HTTP responses which get truncated at the right-side of the window.

: >clipboard ( str  )
    clipboard get set-clipboard-contents ;

This is from Factor’s useful ui.clipboards vocab, which is the most concise and least ugly way I’ve seen to handle clipboards in a cross-platform GUI. clipboard is a global reference to the current clipboard object whose methods are overridden to handle the dirty details of the current platform’s clipboard.

Along came this useful post about adding an ‘open url’ command for URLs in the listener, and I saw a path to my goal: ui.operations and the define-operation word.

Combined with unparse to get a string representation of an object, this adds a “Copy” command to the Listener’s context menu for all objects:

: copy ( obj  )
  unparse >clipboard ;

[ drop t ] \ copy H{ } define-operation

In this brave new Web 2.0 world, it’s dangerous to go alone! Take this JSON with you*:

: copy-json ( obj  )
  >json >clipboard ;

[ string? not ] \ copy-json H{ } define-operation

Load up the vocab (or paste those definitions in the Listener), and voilá — the GUI is instantly extended with new context menu options:

As usual, this is all available on GitHub

*(Sorry for the Zelda reference, just spent a happy weekend playing a big chunk of the awesome LD20 48-hour game compo entries)

Posted in code, factor | 3 Comments

Factoring the Luhn algorithm

I work a lot in the field of e-commerce, and have written at least two shopping carts. Anyone who has implemented any kind of payment processing probably knows about the Luhn algorithm, which is a simple test that one can apply to a credit card number to make sure that the customer entered it correctly.

Factor and, I believe, concatenative languages as a whole can be very expressive when it comes to describing and implementing an algorithm. Let’s explore this.

Meet the Luhn

First, let’s look at an informal explanation of the algorithm

The formula verifies a number against its included check digit, which is usually appended to a partial account number to generate the full account number. This account number must pass the following test:

  1. Counting from the check digit, which is the rightmost, and moving left, double the value of every second digit.
  2. Sum the digits of the products (eg, 10 => (1 + 0) => 1, 14 => (1 + 4) => 5) together with the undoubled digits from the original number.
  3. If the total modulo 10 is equal to 0 (if the total ends in zero) then the number is valid according to the Luhn formula; else it is not valid.

The first whack

: luhn-check ( number-seq  passes? )
    reverse                #! Moving from right to left,
    double-every-other     #! double every other digit.
    sum-digits             #! Add the digits of the sequence, then
    multiple-of-ten? ;     #! test that the result is evenly divisible by 10.

The Factor description of the algorithm looks like a close approximation to the English description of the same. Interestingly, if you enter that word definition into Factor’s listener (i.e. REPL), Factor will note that double-every-other, sum-digits, and multiple-of-ten? are unknown words, however, you can “defer” the definition of those words and Factor will accept the definition. Pause for a moment here: Factor accepts without question words that it can’t actually evaluate or run which lets me start with this simple top-level definition and “fill in the blanks” as I go.

Craft the parts.

First, we need a word to double every other value in a sequence. That is, given the sequence { 1 2 3 4 5 6 }, we should get the result { 1 4 3 8 5 12 }.

Well, Factor supports a number of Lisp-like sequence combinators so this should be simple:

: double-every-other ( seq  seq-doubled )
    [ odd? [ 2 * ] when ] map-index ;

For those new to Factor, [ … ] or “quotation” is the equivalent of (lambda … …) or function (…) {…} in your language of choice; that is, it defines an anonymous function. (For those who care about such linguistic details, “scope” or lexical bindings are an optional feature in Factor, in the locals vocab). Since Factor is concatenative, parameter passing is implicit and we don’t have to name or count the quotation’s arguments — Factor will infer them at compile time and warn if the program doesn’t add up.

Whereas map calls the quotation with each element of a sequence, map-index passes both the element and its index into the quotation: perfect for modifying every other index with the odd? predicate.

It’s almost readable as English: “Given a sequence, produce a new sequence, as so: if an element is at an odd index in the original sequence then double that element in the new sequence.” Yes, it sounds a bit stilted when read aloud, but it concisely and accurately confers the idea to the listener.

A few quick tests in the listener shows that this word works as expected.

Next we need a word that sums the digits of a sequence. That is, for the sequence { 1, 11, 5 }, this word should produce the sum (1 + (1 + 1) + 5) = 8.

Well, the sum word in Factor adds the numbers in a sequence together, but we need to treat two-digit numbers specially. Using integer arithmetic, the way to sum the digits of a two-digit number is to divide the number by 10 (num / 10) and add the remainder (num mod 10). Handily, Factor provides a /mod (read “divmod”) word which does both in one step. Let’s have a go at sum-digits:

: sum-digits ( seq  sum )
   [ 10 /mod + ] map sum ;

Nothing surprising there. “Produce a new sequence as so: for each element of the sequence, apply /mod word to get the quotient and remainder, then add them together, placing the result in the new sequence. Sum the numbers in the new sequence.” Again, stilted, but readable.

On to the last word: multiple-of-ten?. This is simple, test if a number is evenly divisible by 10 — that is, the remainder of dividing the number by 10 is 0, or more simply: num mod 10 == 0.

: multiple-of-ten? ( n  ? )
    10 mod 0 = ;

Very small, and easy to visually inspect and test.

Now we’re cooking with Luhn!

Well, that’s actually all there is to write; we’ve implemented all the parts the Luhn algorithm. The astounding thing is that we started with a simple definition and implemented the entire algorithm without changing the original definition!

A thought experiment

Imagine, as a Python or C++ programmer, if someone handed you a definition of a function and said “this definition can’t be changed, now implement all of the functions it calls.” In order to meet their original syntactic definition, I’d be hard-pressed and restricted in the features that I could use to implement the solution. If they used classes and OO-style code, I’d be stuck with the hierarchy they implied or I’d need to start hacking around them with templating, macros, monkey patching, or other such self abuse. Even if they didn’t use those features of the language, I’d be bound by the function calls and parameter passing in the original definition, which might make my life very difficult as I wrangle the data flow to produce their intended result.

Whereas, in Factor or Forth, handing a well-crafted but fixed definition of a word to someone can lead to an elegant solution that not only looks correct but runs correctly.

Don’t let me be misunderstood

Truthfully, I re-factored the words in this example several times (see the my commit history) before coming to this tidy little definition. I think it has to be experienced to be understood — rearranging words and testing them in an interactive environment feels natural and simply right. To paraphrase Chuck Moore, author of the Forth language, (speaking of implementing a Bluetooth stack), “first you have to figure out what they’re actually doing [in the algorithm], then you simplify the definition and fill in the parts.”

There is some ineffable “ah hah!” moment that comes when writing a well-factored program which makes me smile inside, some intangible correctness of having a readable definition that not only looks right but is right.

Look at the examples and tell me that a single one of those is more clear than this:

: luhn-check ( number-seq  passes? )
    reverse                #! Moving from right to left,
    double-every-other     #! double every other digit.
    sum-digits             #! Add the digits of the sequence, then
    multiple-of-ten? ;     #! test that the result is evenly divisible by 10.

Granted, those aren’t the most shining examples of implementations (hell, I’ve written stuff equally confusing), that this is a trivial algorithm, and maybe I’m getting old, but nowadays all of those just look like esoteric nonsense. (Really, look at the Java and Python implementations; way too clever for their own good).

Now if only I could grow a decent beard to go with these suspenders…

The source to this post is available on GitHub

Posted in blag, code, factor | Tagged , , , | 3 Comments

This is your weblog on Dexy!

Well, this last weekend, instead of writing code or blog posts, I fiddled with Dexy. And I’ve come to one simple conclusion:

Dexy is freakin’ awesome!

Dexy is a documentation writer’s dream tool: it takes words about code, pictures, and original unchanged source code and generates absolutely gorgeous documentation. In fact, Dexy generated the markup for this entire post from just a few small files and automatically posted it to my WordPress blog. Now that is utility!

Here is a Factor script:

! Copyright © 2011 Your name.
! See http://factorcode.org/license.txt for BSD license.
USING: http.client json.reader kernel prettyprint strings multiline ;
IN: weblog.dexyfied

#! @export section-1
: test1. (  )
    "http://oohembed.com/oohembed/?url=http%3A//www.flickr.com/photos/fuffer2005/2435339994/"
    http-get nip >string json> . ;

See that funky @export comment in there? That lets Dexy pull out just a small section of that script:

: test1. (  )
    "http://oohembed.com/oohembed/?url=http%3A//www.flickr.com/photos/fuffer2005/2435339994/"
    http-get nip >string json> . ;

I even got simple interactive Factor sessions going:

( scratchpad ) USE: weblog.dexyfied
( scratchpad ) test1.
H{
    { "version" "1.0" }
    { "provider_name" "Flickr" }
    { "width" "300" }
    { "height" "300" }
    { "author_name" "fuffer" }
    { "title" "echo 2" }
    { "cache_age" 3600 }
    { "type" "photo" }
    {
        "url"
        "http://farm4.static.flickr.com/3092/2435339994_4ab42c3c20.jpg"
    }
    { "provider_url" "http://www.flickr.com/" }
    { "author_url" "http://www.flickr.com/photos/fuffer2005/" }
}
( scratchpad ) 

That’s the result of running this Factor program:

USE: weblog.dexyfied
test1.

It’s re-generated each time that the file changes: no bitrot, just exactly what happens when you type that code into the Factor listener, always in sync with the code on disk. This is sort of like Literate Programming but without doing weird things to the source code while retaining the ability to structure the documentation like, well, a document.

Still a bunch of bugs with the interactive handler, and the splitting of Factor “sections” is a hack, but I hope to improve these things as I go. Already, this beats the old “copy-and-paste” approach by a factor of approximately 10 jillion. Take a look at the source to this post.

Posted in code, factor | Tagged , , , , , , , | Leave a comment

Sorting in Factor

So, mrjbq7′s post with words to find the maximum and minimum of a sequence of tuples got me thinking, and playing, and reading the Factor docs: all good things! I started with his test data:

    TUPLE: person name age ;
    CONSTANT: PEOPLE {
        T{ person f "Jim" 30 }
        T{ person f "Sally" 27 }
        T{ person f "Rebecca" 32 }
        T{ person f "James" 28 }
        T{ person f "Benjamin" 22 }
    }

So, the words from his vocab let me say:

( scratchpad ) PEOPLE [ age>> ] maximum .
T{ person f "Rebecca" 32 }

( scratchpad ) PEOPLE [ name>> length ] minimum .
T{ person f "Jim" 30 }

My first idea was, “hey, couldn’t I represent this operation as a sequence?” since, if it was a kind of sequence then I could use sequence operations like sum and map on the result. Looking back, that really wasn’t a good idea, for reasons I’ll discuss below, but I made it work anyway:

    ( scratchpad ) PEOPLE [ name>> length ] seq-by
    T{ seq-by f ~array~ ~quotation~ }
    ( scratchpad ) infimum
    { 3 T{ person { name "Jim" } { age 30 } } }

This uses an underlying assumption about comparisons between sequences: they are compared by their first non-matching elements or, if all elements up to the length of the shortest sequence were equal, then they are compared by their lengths. How do I know? By looking at the help for generic word <=> as implemented by the sequence class:

    USING: kernel math.order sequences sequences.private ;
    M: sequence <=>
        [ mismatch ] 2keep pick
        [ 2nth-unsafe <=> ] [ [ length ] compare nip ] if ;

mismatch does the first part, comparing the elements of the sequences, outputting the first non-matching index or f if the end of either sequence is reached. The if is a little bit tricky, but if mismatch outputs a non-false value, then 2nth-unsafe grabs the nth element from each sequence (without bounds checking, hence -unsafe) and then calls <=> on those elements.

This is the power of the Factor’s online help system and a glance at the underlying power of the language: the definitions of all words are not only known by the system, but available in a human-readable format, and the definitions are all hyperlinked to other definitions. Nothing I’ve yet used can touch this.

Back to the topic at hand: we just made up a virtual sequence called seq-by that applies a quotation to each element of the underlying sequence when asked. Here’s seq-by‘s implementation of the nth generic word:

TUPLE: seq-by seq quot ;
INSTANCE: seq-by sequence

M: seq-by nth ( n seq -- elt )
    [ seq>> nth ]
    [ seq>> nth ]
    [ nip quot>> ] 2tri
    call( elt -- elt' ) swap 2array ;

seq-by wraps around another sequence, stored in the seq slot. It also stores a quotation that should be applied to each element in the quot slot. The nth word for seq-by says: grab the nth element of the underlying sequence, put it on the stack twice, then call quot on the top value of the stack, then store the whole result into a two-element array.

This is kind of cool, as the values in the sequence get re-calculated each time nth is called. But really, what have I done here? I’ve re-implemented map as an object that follows the sequence protocol which, while interesting for me, is probably not all that useful or clear. When am I going to want to sum up the ages of everyone in the group? Or when am I going to want to go person-by-person in order of age? I conceivably might want to do one of those things, but then if I do, I think the next approach is a lot clearer.

In fact, there’s some built-in fun in Factor’s sorting.slots vocabulary that handles just what we’re trying to accomplish here: sorting our person objects by the values of their slots.

    ( scratchpad ) PEOPLE { { age>> <=> } } sort-by
    --- Data stack:
    { ~person~ ~person~ ~person~ ~person~ ~person~ }
    ( scratchpad ) .
    {
        T{ person { name "Benjamin" } { age 22 } }
        T{ person { name "Sally" } { age 27 } }
        T{ person { name "James" } { age 28 } }
        T{ person { name "Jim" } { age 30 } }
        T{ person { name "Rebecca" } { age 32 } }
    }

sort-by is cool in that it takes a sequence of { slot-name comparator } pairs, so you can have a cascading sort across multiple columns of the objects. In the case above, I just want to sort by age, in natural order (1, 2, 3…). After sorting, the first element is guaranteed to be the one with the lowest age and the last value is guaranteed to be the one with the highest.

Now, back to another example, how about finding person with the shortest or longest name? First, we’re going to need a name comparator.

    :: length<=> ( obj1 obj2 -- <=> ) obj1 length obj2 length <=> ;

I used the locals vocab just to make this a little more clear, and because I’m feeling lazy at the moment: get the length of the first thing, then the second thing, then call <=>. If passed two strings, or two sequences, this will compare them based on their length alone instead the usual behavior of <=> for sequences mentioned above.

Now, to call sort-by:

    ( scratchpad ) PEOPLE { { name>> length<=> } } sort-by
    --- Data stack:
    { ~person~ ~person~ ~person~ ~person~ ~person~ }
    ( scratchpad ) .
    {
        T{ person { name "Jim" } { age 30 } }
        T{ person { name "Sally" } { age 27 } }
        T{ person { name "James" } { age 28 } }
        T{ person { name "Rebecca" } { age 32 } }
        T{ person { name "Benjamin" } { age 22 } }
    }

Not bad! Only one new word. A brief discussion of efficiency: sort is a merge sort, meaning it’s O(N log N) at worst. Finding the minimum or maximum of an unsorted sequence is O(N). In practice, though, I don’t give a fig about order of complexity, nor about any performance penalties incurred by the underlying language or machine model.

What matters to me, then? Well, in this case, a couple of things: using the tools that I already have in the standard library, and writing code that’s readable and meaningful — both now and when I have to maintain this sucker in a few weeks, months, or years. Let’s say, extending the above example, that our program talks about the ‘oldest’ of a group of people often, in that case it makes sense to make a new word:

: oldest ( seq -- elt )
    #! ....

Then we can say things like, “get me the name of the oldest person:”

PEOPLE oldest name>>

Or, in idiomatic English, “Of those people, who is the oldest one, and can you tell me their name?”

The beauty of Factor and other concatenative languages is that it doesn’t matter if oldest is implemented in terms of maximum, minimum, sort-by, or some other method. Instead, we have a single word that clearly expresses the intent of what we want to do: find the oldest person in a group.

This kind of thing is usually written as an expression or series of statements in imperative languages:

    var oldest_persons_name = people.sort().pop().name; // Find the oldest person, get their name

    // OK, we wrote a helper method, this is a little better:
    var oldest_persons_name = this.oldest_person().name;

Already, the code is getting messy, and the intent is getting buried in so much useless noise and repetition. This kind of thinking also leads to rampant copy-and-pasting of common idioms, or elaborate preprocessor macros, or template programming and other bastard OOP paradigms replete with heinous dependency graphs.

What happens if I need to replace PEOPLE with a result cursor from a database? Or if I now want to sort lists of pets? In Factor, it’s all the same, oldest will work on either of those things, presuming they are sequences of objects. In the languages of the day, any of those changes will require changing a lot of code, or maybe adjusting my class hierarchy, all things that are gonna derail me from the task at hand. Not only that, but the code will likely get harder to read, and even end up less flexible than before.

Philosophical question for the night: why does this happen so much in programs? Is it something about the programmers or something about the languages or something about the nature of programming itself?

I can’t produce a qualified answer to those questions, but I know this: once you go concatenative, you never go back. :-)

Posted in blag, code, factor | Tagged , , | 2 Comments

QR codes in Factor

Wow, so Factor is one of the most amazing programming languages that I’ve ever used. And I’ve used a bucketful of them in my checkered past, that’s for sure. But there’s something about using this odd little stack-based “concatenative” language that’s really got me going on a creative high.

Perhaps it’s the interactivity, perhaps it’s how cleanly and concisely concepts can be expressed; I can’t quite define what it is that makes me so happy with this. Not only that, the people in the community are amazing, helpful, friendly, and really freaking smart!

Anyway, I was playing around and brainstorming, and somehow got on the topic of barcodes, and ran across the Zebra Crossing or zxing demo page which uses the Google Charts API to create all manner of useful QR (“Quick Response”) Codes. They look like this:

That’s a 2-dimensional barcode representing the URL http://factorcode.org. If you have a mobile phone that groks these, you can take a picture with the phone’s camera and be automatically taken to that URL. I use RedLaser on my iPhone, because it’s not built into the platform like with Android phones. (In fact the ZXing library is used in the Android software to parse these codes; pretty nifty, eh?)

Anyhow as you can see if you hit the zxing demo page, you can stick a URL, a calendar event, a contact, plain text, a “send sms to” command, and more on one of these codes.

I had just gotten a scrap of paper with my friend’s phone number on it and, programmer that I am, I decided that the best way to enter this into my phone was to write some software to generate a QR code that I could scan on my phone and then add to my contact book. (Yep, all that instead of just taking 20 seconds to type it in. I am broken.)

So, first stop was making a qr-image word that, given a string, would fetch the image of the QR code from the GCharts API. After all, these little symbols are just computer vision-friendly encodings of unicode characters. Yep, just tested that, “Good morning” in Japanese scans perfectly.

To get the phone to recognize contact info, it’s got to be encoded using the MECARD format, which is an abbreviated vCard. (As noted here, vCard is way too chatty for a tiny barcode).

The end result? A mecard vocabulary to talk about contact information and generate the MECARD-formatted string to pass to qr-image and generate the QR image.

T{ mecard { name "Fred Alger" } { email "fred@fredalger.net" } { nickname "@_phred" } } >mecard
--> "MECARD:N:Fred Alger;EMAIL:fred@fredalger.net;NICKNAME:@_phred;;"
qr-image image.

I’d be lying if I said that it worked the first time, but it took me less than an hour to implement. Such is the power of Factor.

Remember that I said that the Factor community are all really smart? While I was implementing my little amusement, mrjbq7 just happened to write a vocabulary for the Google Charts API. This is gonna be epic when it’s done, and it’s going to let me replace my qr-image word with just <qr-code> chart, as well as generate all manner of graphs from my Factor primitives. So awesome.

OK, enough said. Check it all out on GitHub.

Posted in blag, code, factor | Tagged , , , , | 3 Comments

Pedal-powered machines

Check this out:

http://www.processedworld.com/carlsson/nowtopian/technology/bike-stencils-bicimakinas-pedal-powered-tools-in-guadalajara

Sketches and prototypes for bicycle powered machines — a blender, a food processor, a grain grinder, a lathe, even a washing machine!  As high-tech as my world is, there would be something deliciously satisfying about pedaling a bike to wash my clothes, then hanging them to dry.

Posted in thoughts | 1 Comment

bzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzrt

Ahem.

This has been a test of the emergency broadcasting system.  If this were a real emergency, you wouldn’t be checking this blog.  Thank you.  bzzzzzzzzzzzzzrrrrrrrrrrrrrrrrrrrrrrrt

Posted in blips | Leave a comment

Reflections on one week out of the home office

It’s been almost two years that I’ve worked out of my house, and I’ve just recently moved back out into an office.  ”Why?”, you may well ask.  Sites like Zen Habits and Lifehacker extol the virtues of telecommuting.  And, indeed, I am one of the rare and privileged few who can do my job entirely from home.

Why then, would I want to move out?  I have a few reasons, but the main thing is that it’s been a positive change to my daily routine.  I am not, by nature, an extremely disciplined person (still learning) and, with the main office on the West Coast and me three hours ahead on the East, it became far too easy to slip into a pattern of sleeping in until 10, working through the afternoon, taking a little time for dinner with the family, and then staying up late to finish the day’s work.  Kinda sloppy, in my opinion — I ignored the sage advice to set a schedule for my work, set definite office hours and stick to them.  For one thing, I have a hard thing getting up early if all I have to do is go across the hall and sit down at my computer to get to work.

I have been, and am growing out of, a habit of intense procrastination.  Procrastination served me well in high school, because I knew that no matter how much I slacked off, I could always get everything done at the last minute.  In college, this didn’t work so well, and in real life, it works not at all.  In fact, when working from home, the ease of going to work became another way to procrastinate: well, I can take a few more minutes for breakfast, do a couple more chores, then I’ll be really ready to sit down and work.  At least, that’s what I told myself.

Also, I have three small children and a wife at home, so there’s a whole cabin fever aspect going on when I  work at home every single day.

In any case, simply placing the tools that I need for my work 6 miles away has been a huge relief to my mind.  Last week, after setting up my computer at the office and going home, I felt a burden lift from my shoulders.  ”Aha,” I said, “I’m off work!”  I can’t overstate the psychological benefits of this, especially as a system administrator who is frequently on call  and, as of late, frequently called by a miscreant server.

The second unexpected benefit I experienced was that I could suddenly get up early again.  Something about the way I’m wired makes it so that if I have to get up and travel somewhere, I can inevitably get up with plenty of time to get prepared and get there.  I’ve gotten up at 5 almost every day this week and been into work by 6.  The added hours to each day have done untold good for my mental health.  Five in the morning is quite early, I realize, but, as my primary mode of transportation is a sporty old road bike and the local heat hits 90 degrees and 90 percent humidity by about 10 AM this time of year, it’s best that I get my rear end out the door before too late in the morning.

I noticed, also, that I have a better sense of how much time that I spend working.  Having no set hours when I worked from home, I always had a sense of, “I could go work on that right now,” which, for some reason was enough for my brain to feel like it had accomplished something, when it really hadn’t.  I track my time on a timesheet, which gives me a numeric/analytical sense of the time I spent each week but, being out of the house, I really get a sense of how long I’ve been gone, and I’m eager to get home and spend time with my wife and kids.  I’m starting to re-realize the value of time with them, not just time when we’re physically proximal, but time where my mind is disengaged from work and I’m free to pay attention and express my love for them.

It struck me, at one point last week, where one of my co-workers said, during a server emergency, “sucks that you have to go into an office,” the real professional value of an office.  Not that professional people don’t work from home, and do an excellent job.  For me, there’s something intangible that gives my work more legitimacy.  Working in an office, away from the pressures of home life, says to me, “I’m serious about what I do for a living,” in a very stupid and physical way.  Staying up all night to finish the critical project that evening, and then driving home in the morning, I felt a supreme sense of accomplishment and, something I’ve missed for too long — a sense of coming home for which there is no substitute.

Meanwhile, having completed my work in four days, instead of five or six as has been my habit, I can sit at home on the couch and write an early morning blog post while my daughter sits next to me and plays with my iPhone.  In a minute I’ll be making us all waffles and bacon, then kicking back to enjoy them with a frosty glass of OJ and to bask in my new-found love of home.

Posted in blag, thoughts | Tagged , , , | Leave a comment