Thursday, October 4, 2007

What I Learned From X That Made Me A Better Programmer In Y

Picking up Raganwald's gauntlet.

X = Acting classes; Y = Any programming language

Trust your instincts. Act on the first idea that comes into your head, just to see what will happen.

X = DJing in clubs; Y = Presenting at conferences

Show off. The worst that could happen is that somebody will put you down. The only way they can put you down, if you're showing off, is by teaching you something better. So you win either way.

X = Common Lisp; Y = Java

Objects do not need to have any substance at all. They can consist entirely of behavior.

Compartmentalize everything. Use simple names.

X = The dot-com boom; Y = Rails

If you hand-code CGI, then graduate to Perl's, you're in the position of using a framework which automates stuff you used to do by hand. In this position, you can program rings around people who only know how to use the framework. The best way to use a framework is to know on a very practical level what it's doing every step of the way.

X = smashing boulders with a skidster; Y = JavaScript

My parents are building this high-tech hippie house that is part miniature ecosystem. I helped them by clearing rubble and turning big sandstone boulders into rubble to be cleared. One time I was up at their property all on my lonesome for hours in the skidster, and it was assumed I'd only be able to clear existing rubble, rather than smash up any new boulders, because it takes two people to take the scoop off the front and put the piledriver on instead.

(This is my parents' skidster. The aging hippie's my dad. The scoop is pictured attached.)

I cleared all the rubble, and because I was having fun, went ahead and smashed some boulders anyway. Being sandstone, they were soft enough that you could smash them up just by deliberately colliding with them at the skidster's maximum speed (about 3mph) if you hit them with the scoop at just the right angle. Later my folks were surprised by how much I'd done on my own. Not only was it possible to smash rocks without going to the trouble of attaching a special hydraulic piledriver, it was also a lot more fun.

Nine times out of ten, when you want to do something with JavaScript, you don't really need Prototype or Scriptaculous. Using external libraries is awesome when it makes your work easier, but it's much less impressive when it just circumvents ignorance. Not only is it possible to get interesting interactivity with just JavaScript and the DOM, it's also a lot more satisfying.

X = Ancient Greek; Y = Any new language I'm learning

No syntax any serious computer language has ever used will ever be as tricky or bewildering as attempting to translate Sophocles or Plato. I have not ever seen and never will see programming syntax that scares me. Even including languages designed for the sole purpose of being difficult to program in. Such syntax does not exist. If you can tackle Ancient Greek, you can take on any language. (And that goes double if you can actually read Homer.)

Also, no matter how hard it is, it gets easy if you do it often enough.

X = Python; Y = Perl

Emphasize readability.

X = releasing DJ records nobody bought; Y = open source projects

Buy-in is everything.

X = Perl; Y = Ruby

Dynamically designed data structures rock.

Never write code if you can convince your language to do it for you.

X = playing with Legos; Y = any language

Idioms are resources, not rules.

(That goes for design patterns too. Design patterns essentially are idioms, but just so it's clear.)

X = playing Werewolf; Y = any group context

Give people the trust they earn. No more, no less. Likewise accept from people exactly the trust you earn.

Be warm and open to people, but be very clear-headed when you encounter known warning signs. Any time I've gotten screwed politically in some corporation, or lost in some way playing Werewolf, the signs were there all along.

X = TDD; Y = situations where using TDD frameworks was impossible

Test like you're a robot. Do the exact same thing, over and over again.

X = LSD; Y = Ruby metaprogramming

Sometimes things which seem to make you smarter really do.

X = marijuana; Y = Ruby metaprogramming

Sometimes things which seem to make you deep really make you silly.

X = astrology; Y = debugging legacy systems

Just because it works predictably doesn't mean it makes any sense.

X = pencil drawing; Y = Haskell

If you're only doing things that come easily to you, you're totally underperforming. Anyone smart enough to program well is smart enough to do something strange and unusual, outside their comfort zone. Take something that seems weird, put time, effort, and brains into it, and the payoff will be worth it.

X = driving; Y = corporate politics

At a certain point in my life, from studying hypnosis, I got really attuned to body language, and realized that body language is expressed through driving. I started to pay attention to it and came to the absolutely firm conclusion that almost everything people do when they're driving is subconscious social behavior. People don't drive fast because they're in a hurry; they drive fast because they want other people to notice them.

In the same way, many, many decisions made in corporations have nothing to do at all with the subject of the decision. It's almost entirely social behavior. We go with Bob's plan because Bob successfully asserted his dominance over Fred. If we're lucky, Bob is good at making plans as well as asserting dominance, but if he's bad at making plans but good at asserting dominance, his plan is still the plan we use. Sometimes entire corporations go out of business because some idiot had the shiniest hair.

Ever since I noticed this thing about driving being mostly social behavior, I've been a different driver. I spend a lot less time passing people and a lot more time letting people cut into my lane if they want to. In reality, all that subconscious social behavior's expressed through potentially lethal gigantic metal objects moving at high speed. I'd rather take the hit in terms of social status than be hit with tons of fast steel. (And you have to remember, a lot of those people are idiots.)

Likewise, if you recognize that a lot of the decision-making process in corporations is about asserting social dominance, you can accept that fact and deal with it. Countless brilliant geeks have driven themselves nuts trying to get corporations or groups to turn away from idiotic decisions, never realizing that the way to get the corporation to stop being stupid is not to prove your point but to wash your hair. (Alternatively, align yourself with a skilled corporate politician and let them deal with it.)

X = my ex-girlfriend; Y = irb, the Unix shell, and OS X

My gf at the time criticized me during the dot-com boom, because I was making a lot of money but living the same way I had when I was making a quarter as much. It was a gentle criticism, but it was accurate: "You don't know how to live rich, man." She'd had an extremely rich friend in college. Basically she meant I had the ability to set myself up in comfort, but I wasn't using it.

Living rich on your computer means owning your operating system. Don't use Unix commands; write them. When I'm in irb or bash, I'm not using the irb or bash other people use; I'm using special dialects of each shell which I've built up around my own common use patterns. My bash has grammatical conventions - for instance, when a command ends in ?, it signifies a question. Likewise, I've got a Unix command I call from the OS X GUI (and Evan Light showed me how to add many more).

It's not really your computer until you own it. A programmer whose computer works like anybody else's doesn't know how to live rich (and should learn).

X = Java; Y = Ruby

Obie Fernandez's hyperbole was pretty much dead-on - Java reeks like muskrat butt. However, I can say this because people have given me money to write Java. I think it's actually a competitive advantage. A lot of Rubyists seem prejudiced against Java, and by prejudiced I mean they're making judgements based on ignorance, which is how prejudice works. Those Rubyists shouldn't dis Java until they learn it, and they should learn it. Criticizing something you don't understand is bullshit.

A lot of the freebies you get with "scripting languages" gloss over complexities that you're better off knowing about. You're not usually better off working with those complexities by hand, but being totally unaware of them screws you in the long term. It's actually a very good thing to be aware of the difference between a string and a string buffer. Likewise, having to remember all the idiotic flaws in Java's numeric implementations has a great side effect - you think about what your program is doing in more detail. It's a pain in the ass, but it's healthy to jump through those hoops once in a while.

I came to Java from Perl, and went from Java to Ruby. Coming back to a higher-level language, I'm a lot more comfortable in my new environment, but I always have those lower-level concerns floating somewhere in the back of my head. That's really valuable. The most obvious example is with Rails #find statements, which almost invariably generate wasteful duplication of SQL connections and statements. This causes unnecessary slowdowns in your site - but if you've seen it coming, you can avoid that lag factor. Working at a high level with awareness of the lower level is much more powerful than working at a high level with no awareness beyond that.


  1. Wow! Great article. Loved it. Agreed, to live rich, you need to own the computer that you use. I know of several people who don't switch away from Qwerty because "Oh! What if X wants to use my computer". That to me, is merely an excuse not to try something new. Its easy to get stuck in a rut where conventions become a part of you, and questioning them seems to be useless...

  2. Quite nice

    can you explain about the bash usage more though?

    How does the
    notation work?

  3. It's crazy to me that Java is considered a low-level language these days, and I'm only 29!

  4. It's really pretty straight forward. You can use ? in alias names in bash, just like you can use ? in method names in Ruby.

    So g? is grep, g+? is an enhanced grep, ps? is an alias to a sequence of commands which does a ps and then greps it for the arg -- e.g.

    ps? mongrel

    will give you all the mongrel processes -- and so on and so forth. Likewise h? greps history.

    Anything that begins with m8 sends a file to TextMate. So m8p sends my bash profile to TextMate, m8irb opens .irbrc, m8ar opens ActiveRecord, m8pack opens ActionPack, etc. Client names take me to the directories their projects live in.

    It's nothing more than convention over configuration, but it's very handy. It becomes necessary to have some consistency if you build a large profile. It's pretty to easy remember that h is show history and h? is grep history, while ps is show processes and ps? is grep processes.

  5. "It's crazy to me that Java is considered a low-level language these days, and I'm only 29!"
    To me, as well. And I'm just 21. ;p

    I can remember when people would talk about how their assembly experiences have helped them understand C++.

  6. >> People don't drive fast because they're in a hurry; they drive fast because they want other people to notice them.

    That makes completely sense. I feel like an idiot now. Thanks for opening my eyes.

  7. You had me until the part about Java being a low-level language. Sorry, but Java hides and glosses over way too much to be considered low-level. I don't think Java is any lower-level than Perl or Python, it's just more verbose.

    As for people driving fast to be noticed, I'm sure that accounts for some people's driving, but some people are just in a hurry. When I go fast it's often to distance myself from the other drivers -- that's a habit you get from motorcycle riding.

  8. Sooooooooooooooooo good.

    Glad to see you back in the blogging saddle full force.

    Makes visiting the rss reader worth it again.

  9. "You can use ? in alias names in bash, just like you can use ? in method names in Ruby."

    Thanks for explaining, this is very insightful. I believe it makes sense to use the '?' as part of a query (to your system or shell, in this case with h? for asking history). Really nice idea IMHO.

    Also, I believe Ruby kinda had a footprint on your thinking too since using "def foobar?" methods is quite common. I especially like something like "def include? argument"

    The beauty of a good Ruby way had a footprint for me too. I am especially in total love of human readable, clear DSLs :)

    Hope to see you give us more food-thought later, cheers for the good blog!

  10. "... I believe Ruby kinda had a footprint on your thinking too since using "def foobar?" methods is quite common. ..."

    You may also expect that this was influenced by Lisp (particularly Scheme), where this has been common place for what seems like forever... though less so in Common Lisp.

    Lisp was a big influence on Ruby, so it stands to reason :).

    Take care,


  11. Common Lisp tends to use -p as a suffix to indicate that the function is a predicate. Scheme uses ?.

    E.g., in Scheme you'd have "fast-driver?", while in Common Lisp you'd have "fast-driver-p".

    The difference is historical; although I'm a Common Lisper, I actually prefer the Scheme style, though searching for [!?] and friends with some Unix tools isn't so easy.

  12. Giles, this is a great post. And Tiago: I completely agree with you and feel the same!

  13. Giles, this is a great post. I have translated it into Russian, you can find it here:

    Please let me know if there are any issues concerning my translation.



Note: Only a member of this blog may post a comment.