Sunday, February 21, 2010

Thanks, Sean!

Thanks to my friend, Sean, I noticed yesterday that my last blog entry was posted exactly one year ago today. Well, I'm nothing if not punctual, and I'm committed to blogging at least once a year, whether I have anything to say or not.

So on the off-chance you're wondering what I've been doing this past year...

Well... I learned to juggle... a little... a few tricks, only 3 balls.

It's a little depressing when I think about it.

Thanks again, Sean. ;-)

Saturday, February 21, 2009

A little lithp

After almost 20 years of fairly hardcore Emacs love, I finally wrote my first Lisp macro. And now I want to smear my good fortune all over you, dear reader, by recounting my experience in more depth.

How lucky for you!

About Lisp...

Created in 1958, Lisp is the 2nd oldest (not to mention sexiest) programming language in widespread use today. Its syntax is simple: lists of tokens contained within parentheses. In Lisp, code and data are represented the same way: as lists of tokens, duh. This deceptively powerful quality is what allows "Lispers" to create new syntax, i.e. Domain Specific Languages, within Lisp itself.

Lisp is basically what the "executable XML geniuses" -- yes, I'm looking at you Ant, Spring, J2EE, VoiceXML, and countless others -- should have used! XML is what you use when your chosen language for manipulating data can't adequately represent it.

My Macro

Ok, enough with the history. Here's the macro:

(require 'sqlplus)
(defmacro def-oracle (name connect-string)
(let* ((buf-name (concat "oracle-" (symbol-name name)))
(fun-name (intern buf-name)))
`(defun ,fun-name ()
(interactive)
(sqlplus ,connect-string ,buf-name))))
Lisp macros are like functions, except that instead of computing a value, they compute another Lisp expression that will compute the value. In this case, my macro creates a defun expression, which defines a function. Simple, huh?

The trick to macros is the backquote character: `. Combined with the comma character, they allow you to selectively evaluate elements of a quoted list. In my macro, the list whose first token is defun is quoted (by a backquote) and my "selectively evaluated elements" are fun-name, connect-string, and buf-name.

Here's how I invoke my macro:
(def-oracle dev   "user/password@dev.host:port/sid")
(def-oracle qa "user/password@qa.host:port/sid")
(def-oracle prod "user/password@prod.host:port/sid")
After those lines execute, three new functions are created:
  • oracle-dev
  • oracle-qa
  • oracle-prod
Ta-da!

Um, hello?

Your stolid reaction belies the awesomeness of my macro!

Maybe I should've started with my reasons for creating the macro in the first place.
  • Create a handy function that "wraps" the Emacs sqlplus function for each of the databases to which I must often connect
  • Don't prompt me for the dang connection credentials every time I invoke the handy wrapper function
  • Enforce a consistent naming convention for the various sqlplus buffers I have open so that I may, for example, easily switch between qa and dev
  • Make it easy to add more of these handy wrapper functions
There. Is that better? I certainly think so. :-)

But perhaps it would be enlightening to see what I would've had to code to achieve the same result without using a macro:

(defun oracle-dev ()
(interactive)
(sqlplus "user/password@dev.host:port/sid" "oracle-dev"))
(defun oracle-qa ()
(interactive)
(sqlplus "user/password@qa.host:port/sid" "oracle-qa"))
(defun oracle-prod ()
(interactive)
(sqlplus "user/password@prod.host:port/sid" "oracle-prod"))

See how verbose and redundant that is? It's positively VERBOSIDUNDANT!!! And my naming/calling conventions are sprinkled all over the place. To change any one would require multiple redundant changes. And that's not DRY, and that's not good.

Friday, August 15, 2008

PoopTag = Social Defecation

(It's not as gross as it sounds!)

Everybody poops. Every U.S. president. Every Jonas Brother. Every Olympic athlete. Even Michael Phelps. Actually, at 12,000 calories a day, he poops a LOT!

And so while you're pooping, have you ever wondered who else is pooping at exactly the same time? Really? Me, too!

So with the help of some friends, I created PoopTag, a sort of game that strives to be both encouraging and enlightening. It's easy to play: you simply notify PoopTag whenever you poop. You do this by sending a direct message to the pooptag account on Twitter using your mobile device. PoopTag will then determine whether anyone else is pooping at that time. If they are, you will have successfully "tagged" them, and PoopTag will notify its followers of this happy event.

And in response to your direct message, whether you successfully tag anyone or not, you will receive a random pithy reply. That's the "encouraging and enlightening" part.

There are two modes of play: public and covert. You decide which way to play each time you poop.
  • Public (send more than one character):
    d pooptag This text will be broadcast to all PoopTaggers

  • Covert (send any single character):
    d pooptag !

Obviously, the public notification makes it easy for someone to tag you, though they must be pooping in order to do so.

Eventually, we'll publish statistics at pooptag.com, enabling services like Poop Cycle Compatibility Matching, prospective home-buyer bathroom sizing tools, and life-saving medical history to present to your doctor, among other things.

Come join the fun!

UPDATE 9/20/08: Changed covert pooping method from an empty message to one containing only punctuation due to Twitter no longer delivering blank direct messages.
UPDATE 10/13/08: Covert pooping now triggered by a message containing only a single character (letter, number, punctuation, whatever)

Saturday, August 09, 2008

Create

I'm big on creativity. You know, building stuff. Putting things where nothing was before. I think it's both the secret to happiness and the meaning of life. I think it's what humans are SUPPOSED TO DO.

Create. Re-create. Recreation. Play, especially at work.

I follow why the lucky stiff on Twitter. His tweets are usually funny and clever. And once in a while, he'll write something like this:

when you don't create things, you become defined by your tastes rather than ability. your tastes only narrow & exclude people. so create.

Very cool.

Thursday, June 12, 2008

Sunday, May 18, 2008

Trying to Save the Crum & Forster

My grandfather, Lewis "Buck" Crook, was a prominent architect. He and his partner, Ernest "Ed" Ivey, comprised the firm of Ivey & Crook, responsible for almost 600 commissions over the course of 43 years, most of which were built in and around the city of Atlanta, Georgia.

One of them, the Crum & Forster building, a midtown landmark at 771 Spring Street since 1927, is in imminent danger of being torn down. Ironically, the demolition is being proposed by Georgia Tech, who purchased the property in December of 2007, apparently with the intent to demolish it and expand the development of their Technology Square.

Georgia Tech is the alma mater of both my grandfather and his partner, Ed Ivey, who helped found the school of architecture there one hundred years ago this year. Through their works, they made a substantial contribution to the esteemed academic reputation Georgia Tech enjoys today.

Rather than destroy it, Georgia Tech has an opportunity to celebrate the work of Ivey & Crook, just as world-renowned architect John Portman, another Tech graduate, did when he expanded Emory University's student center in the 1980's. Ivey & Crook designed and built the original dining hall at Emory. Portman could've torn it down, but instead he chose to incorporate it into his own vision for the Dobbs University Center.

Georgia Tech has every reason to do the same for Technology Square!

An online petition to save the Crum & Forster has been created. Please add your name.

The building has an official blog. More pictures and info can be found here, here, and here.

Tuesday, May 06, 2008