“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 , , , , | 2 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

blip.June 10, 2010 12:16 pm

Progammers Must All Learn Statistics or I Will Kill Them All… still GREAT after all these years http://ping.fm/rp1Cd

Posted in blips | Tagged | Leave a comment