Egoless Software Development

No comments:
"Ego" is a complex phenomena that, in Buddhist theory, represents a great risk to happiness. The ego is responsible for a great deal of misery: whenever someone hurts our feelings, disrespects us, abuses us, the pain and anger we feel is due entirely to the specter of ego.

Attachment is dangerous because attachment can be severed. The ego attaches itself strongly, especially to the images of ourselves in other people's heads. We all want to be perceived positively, however we define that, some combination of: strong, competent, authoritative, reliable, smart, attractive, friendly, likable, etc. To achieve this aim, we must not make mistakes, not show fear, weakness or doubt.

It is tempting to say that to be egoless requires that one go in the opposite direction, to revel in our mistakes, to celebrate our weaknesses and failures. This is a more subtle mistake, but it is a mistake nonetheless.

To avoid both the trap of self-aggrandizement and self-loathing is the key attribute of egolessness. This is the essential ability to be able to look at oneself in the mirror, and see yourself as you really are, without bias, positive or negative.

The technology world is filled with people, people with all kinds of strengths and weaknesses, people with egos and (remarkably) people seemingly without. It is to those humble, good programmers that have created so much for so many that I respect and admire. Two that come to mind immediately are Larry Wall (inventor of Perl) and John Resig (inventor of jQuery). They are amazing people.

I also have a great deal of respect for Rich Hickey (inventor of Clojure), Mike Bostock (inventor of D3), Oliver Steele (inventor of OpenLaszlo) and Edward Tufte (author of a wonderful book on data visualization).

In comparison to these giants, my own contribution to the software world has been exceedingly minimal. Much of my early career was spent on enterprise software, at first in MS Access and VBA, and then later on variants on the Java stack, particularly the [Tomcat, Spring, and Hibernate] stack. Over the last several years, my interest has turned sharply toward the open web platform, both front- and back-end (although last year I took an interesting detour into consumer internet startup land at Z4 using Groovy and Vert.x). The open web platform world is dominated by JavaScript, open-source, cooperative multitasking (asynchronous programming), and the use of non-RDMS datastores and caches. Distributed applications are in the web platform's core DNA.

This transition hasn't been fast or easy for me. For one, it represents a sea-change in tooling: the web platform has an entirely different taxonomy, different tooling, different libraries (indeed, different patterns), different debugging techniques, different build tools, different runtime structures, and different communities. Moreover, there exists a dizzying array of products and services available at every level of abstraction you care to name, in every combination you can imagine, and a few more besides.

It's fantastic.

The way in which web applications are built is still very much in the air, although it would seem that the community at large has settled on a few common points:

  1. node is good.
  2. npm is good.
  3. git is good.
    1. github is good
  4. single page applications are good.
  5. modern browsers are good.
  6. mobile is good
  7. css frameworks are good.
    1. css languages are good
  8. javascript in the front-end is required
    1. front-end component frameworks are good
  9. realtime is good
    1. websockets are good
  10. APIs are good
  11. JSON is good
  12. markdown is good
Slightly more controversial (although I feel this way):
  1. Functional is good
  2. Pure functions are good
  3. Immutable data is good
Definitely controversial (which I believe):
  1. Javascript is good
  2. Promises are good
Notice what is missing: there is no mention of datastores, or even datastore styles. That is because data-stores remain surprisingly controversial. MySQL and PostgreSQL are both very popular; NoSQL alternatives like Mongo, Couch, Cassandra, Riak, and so forth all have their proponents. Even proprietary datastore have proponents: you will find significant loyalty to Oracle and Microsoft, although not so much on the open web platform. Partly this is because there's another statement missing from the above:
  1. Statelessness is good
This is not there because of underlying hardware changes. It is no longer out of the question to have 64G of main memory, making it possible to vertically scale applications like never before. Keeping all application data in memory is entirely possible, especially if large data structures (like images) are factored out into "resources". Removing memory constraints enables radically simplified application architectures that are far faster to write, and far easier to understand and extend.

It is against this background that I hope to contribute something to the world, one application at a time.

The Homebrew bug that looked like a zsh bug... but turned out to be an iTerm bug.

No comments:
This bug was difficult for me to diagnose.

The first sign of trouble was that the `npm` command wasn't found. I use homebrew to manage my local node installation, and so ran brew doctor. Much to my surprise, it reported:

Warning: Homebrew's bin was not found in your PATH.
Consider setting the PATH for example like so
    echo export PATH='/usr/local/bin:$PATH' >> ~/.bash_profile

This despite the fact that `echo $PATH` clearly reported that it was set. I double-checked ~/.zshrc to make sure the path export looked right, and it did.

I eventually hopped on IRC#machomebrew channel, and a friendly person suggested I write a simple script to verify that sub-processes were receiving the PATH variable correctly. I did that, and this was my first indication that it was not a homebrew bug! I suspected that it was zsh, or oh-my-zsh, and radically simplified my login files, but the problem was still there.

About to post onto IRC#zsh when it hit me: what if my terminal is doing something funny? So I started up plain vanilla Terminal and executed the same script. It worked! This meant that it was, in fact, iTerm2's fault.

And indeed, that is the determination from this rather lengthy bug discussion.

There was both a brilliant work-around in that thread by a user github/pilif:

/usr/bin/login -f 
but the iTerm maintainers were on it, and fixed it. For some reason I did not get that update of iTerm (probably because I cancelled out of an update in my haste). The best solution was to simply update iTerm2 to the latest version, which fixes this problem.

Why write about this bug? Because it highlights the surprising ways that tools interact, and how sometimes appearances can be deceiving. It's also a reminder of how delicate software systems are, and how easily they can interact with each other in unexpected, and unwanted ways. Patience and perseverance, though, can usually result in a resolution.

I also want to say that, without exception, these are all wonderful tools, including iTerm2, who's consistent strengths definitely outweigh it's (momentarily frustrating) weakness.