The Nuclear Squid Musings on stuff and other things.

Rust Presentation at Vienna.rb

A presentation I gave at the Vienna.rb Meetup in February:

How to become a Better Developer

You probably know the feeling. You’re writing a piece of code, and just by looking at it, you know it could be better – but you don’t know how. You have that feeling that the right solution is just around the corner, if only you could reach it… but you don’t, and you have to live with whatever you’ve got. You have to live with the knowledge you were not good enough to write better code.

This happens especially if you’ve just left the beginner stage behind, and are slowly advancing through the intermediate stage. Many plateaus await you, frustrating you in your quest for progress. Some days, it seems like you’ve hit your limits, the very best you can do, and that you cannot go any further.

But there are things you can do to help yourself. I’d like to tell you about a few.

Challenge yourself

Similar to training a muscle, your skills won’t grow when you keep repeating the same things over and over. So it is important that you expose yourself to new concepts and ideas. Often, you’ll feel out of your element, and like the biggest n00b on the planet. And that’s ok. If it’s not hard, if it doesn’t suck, you probably won’t learn much from it. Become comfortable with your Discomfort Zone.

Expose yourself to new ideas. Read about something you do not yet quite understand. Listen to podcasts about topics you do not know much about. Watch screencasts about things you’ve only dreamed of.

Ask other people about books, blogs, screencasts, or podcasts they recommend. But also always ask them why they recommend them. What is right for them may not be right for you.

I like Ruby Rogues, Avdi Grimm’s Ruby Tapas, Real Talk, Vimcasts, Build an App with Cory Haines and Gary Bernhardt’s Destroy All Software. Each one of these has exposed me to new ideas, or a new way of doing things that I hadn’t know of or considered before.

But even more important, do new stuff. Just collecting information in your head is not enough, you also have to implement it. Want to learn functional programming? Go learn Haskell. Want to work in a statically typed language? Learn Scala. Always wanted to know more about the actor model? Learn Erlang.

Here’s the thing: After that initial explosion of cognitive growth, they noticed a decline in both cortical thickness, as well as the amount of glucose used during that task. However, they remained just as good at Tetris; their skill did not decrease. The brain scans showed less brain activity during the game-playing, instead of more, as in the previous days. Why the drop? Their brains got more efficient. Once their brain figured out how to play Tetris, and got really good at it, it got lazy. It didn’t need to work as hard in order to play the game well, so the cognitive energy and the glucose went somewhere else instead.

Andrea Kuszewski, “You can increase your intelligence: 5 ways to maximize your cognitive potential”

And then write programs in those languages. They don’t have to be things that will actually be put in production, but you should write non-trivial programs that do something useful (ie., anything but printing "Hello World").

You are functionally blind when you only have book knowledge.

~ Chong Kim

Study the masters – and mastering

Amy Hoy’s post “Why Blacksmiths are Better at Startups than You”1 contains many great lessons about mastery, apprenticeship, and how we often sabotage ourselves on our path to getting better.

PeepCode’s Play by Play series shows how masters work on a given exercise, telling you about their thought process and explaining their decisions as they go along.

And, if you can, find a mentor, someone who can guide you, show you the way, and provide you with useful criticism that will let you grow.

Learn the classics

Languages and frameworks come and go, but the classics are forever.

You might call some of these things “computer science”, but many of the best programmers I know have no formal training in such. These things can be learned by anybody, many of them are learned best in a hands-on environment.

Investing your time learning things like networking, concurrency, regexes, or system programming will not go out of style in your lifetime.

Jesse Storimer, in his “Working With #{code}” newsletter

Languages and frameworks are only tools, a means to an end. Understand why those tools exist, and why they work the way they do, and you will gain a deeper understanding of how things work.

And they will set you apart from others who define themselves as Ruby/Python/PHP/JavaScript developers. Restricting yourself to one language or framework means limiting your horizon to many other things out there.

Practice mindfully

Sites like Exercism.io or Code Wars present you with programming challenges in various languages that allow you to “exercise” in a very defined way. Exercism.io is especially great because its emphasis is on getting and giving feedback, forcing you to think and argue about your design decisions. This can be very enlightening even with apparently very simple exercises.

Using Katas to Improve Yourself is another possibility to train your programming abilities, while at the same time picking up a new language or framework.

The Ruby Rogues episode on coding exercises, quizzes and katas also contains useful information on that topic.

Mind your body

Go outside and get fresh air. Sleep more (about 7 hours seems to be the right amount for most people). Work out, even if it’s only 15 minutes every other day. And start meditating for 2 minutes each day. Doing these things will improve every area of your life, not just your programming.

The Key

Always remember that the biggest factor that determines your success is not intelligence, or talent. Grit, the perseverance and passion for long-term goals, and your attitude towards getting better are what determines your path ahead.

And finally

Something to meditate on:

One day a monk visited Master Wq, and inquired, “Master, how will my code be different when I have mastered Vim?”

Master Wq answered, “Before Vim: declare, define, process, print. After Vim: declare, define, process, print.”

~ Vim Koans

Acknowledgements

Thanks to eclubb, Tekhne, augiedb, michael, newton10471, and markijbema of the RubyRouges Parley forum for suggestions and feedback.

  1. Even though the post discusses mastery in the context of a business and startup founders, its lessons are easily applicable to mastery in general.

A Very Short Overview of Vagrant

A presentation I gave at the Vienna.rb Meetup in July:

n Things You Probably Didn't Know About PostgreSQL

A presentation I gave at the Vienna.rb Meetup in June:

Rails Security Primer presentation

A small presentation I gave at the Vienna.rb Meetup in March:

Mercurial fails with import error on Mac OS X

If you installed Mercurial, but it fails with the following error message when you try to use it:

Traceback (most recent call last):
  File "/usr/local/bin/hg", line 38, in <module>
    mercurial.dispatch.run()
  File "/Library/Python/2.7/site-packages/mercurial/dispatch.py", line 28, in run
    sys.exit((dispatch(request(sys.argv[1:])) or 0) & 255)
  File "/Library/Python/2.7/site-packages/mercurial/dispatch.py", line 41, in dispatch
    req.ui = uimod.ui()
  File "/Library/Python/2.7/site-packages/mercurial/ui.py", line 45, in __init__
    for f in scmutil.rcpath():
  File "/Library/Python/2.7/site-packages/mercurial/scmutil.py", line 464, in rcpath
    _rcpath = osrcpath()
  File "/Library/Python/2.7/site-packages/mercurial/scmutil.py", line 436, in osrcpath
    path = systemrcpath()
  File "/Library/Python/2.7/site-packages/mercurial/scmutil.py", line 489, in systemrcpath
    path.extend(rcfiles(os.path.join(p, root)))
  File "/Library/Python/2.7/site-packages/mercurial/scmutil.py", line 474, in rcfiles
    for f, kind in osutil.listdir(rcdir)
  File "/Library/Python/2.7/site-packages/mercurial/demandimport.py", line 86, in __getattribute__
    self._load()
  File "/Library/Python/2.7/site-packages/mercurial/demandimport.py", line 58, in _load
    mod = _origimport(head, globals, locals)
ImportError: dlopen(/Library/Python/2.7/site-packages/mercurial/osutil.so, 2): no suitable image found.  Did find:
    /Library/Python/2.7/site-packages/mercurial/osutil.so: mach-o, but wrong architecture

Then your Python most likely runs in 32-bit mode. To force Python to run in 64-bit mode, run this command:

defaults write com.apple.versioner.python Prefer-32-Bit -bool no

Sharing history in zsh

One feature of any shell that is immensly useful is the history. Any command you made gets recorded, and you can then retrieve it later on with various commands (my favorite: Ctrl-R, which allows you to search through your history).

At any given time, I usually have anywhere between 10 and 20 terminals open somewhere (not counting remote sessions). Thanks to zsh I can share every command I enter between all those terminal after I enter it and make it accessible via the history.

This means I no longer have to remember which terminal I entered my command in, all I have to do is search the history.

How to enable this

In your .zshrc:

# Appends every command to the history file once it is executed
setopt inc_append_history
# Reloads the history whenever you use it
setopt share_history

REPORTTIME in zsh

REPORTTIME is a nifty feature of zsh. If you set it to a non-negative value, then every time, any command you run that takes longer than the value you set it to in seconds, zsh will print usage statistics afterwards as if you had run the command prefixed with time.

So, for example, if we run rake to rebuild any out of date files in Rubinius, we get this:

~/Development/Rubinius ☺ » rake 
[ … Lots of output …]

Finished in 136.926808 seconds

3866 files, 21497 examples, 59187 expectations, 0 failures, 0 errors
rake  160.78s user 26.49s system 81% cpu 3:50.20 total

(Yes, my prompt has a smiley in it. It turns sad and red when the exit status is non-zero)

How to enable this

Since this only makes sense in interative shells, I set this value in my .zshrc:

# Report CPU usage for commands running longer than 10 seconds
REPORTTIME=10

(See this on GitHub)