Although it’s not yet the last month of the year, I was in a reflective mood, and jotted down programming lessons I learned this year:

  1. Spend time first on what you’re going to do, iterate several times on the “plan”, and when you get to the computer, it should just be about typing out what you have already decided.

    Of course, I do my own planning within OrgMode itself, it’s hard for me to do my planning on paper, but the idea is to do the iteration of the steps first, take feedback from stakeholders, etc. The actual part of typing should come last and should be boring.

    There are places where this should probably not be applicable such as explorations of technology and finding out what is possible, but for majority of things, I constantly have to remind myself that we are in the problem-solving business first, and in the programming business second.

    Part of the problem-solving is in figuring out the repercussions of making code changes and how to restrict the limitations and expand the possibilities of the code that we write, especially keeping the code as slim as possible. In simpler words, part of the time spent up front should be as much about the accidental complexity as well as the incidental complexity.

    Some call this hammock-driven development. Some call this killing busywork.

  2. “Working in strange environments is a CS life skill” is what Dan Grossman mentioned at the start of the Programming Languages Coursera course and it was a profound statement for me.

    The times when I have resisted learning new tools or getting used to new programming languages are the times I have atrophied.

    The times when I threw away familiarity and explored new tools was when I learned and enjoyed.

    Time and again, I have to make a commitment to throw familiarity away. That is what pushes me to learn to customize Emacs despite already having spent years mastering Vim and spent so much time using PyCharm, etc.

    The flip side is that learning how to create a mobile app has always been a point of procrastination for me because it is all about learning new tools, new APIs, new IDE, etc.

  3. Always keep raw original data around.

    You never know when you’ll need to reprocess it. It is always possible to reprocess but losing raw original data is a bad place to be. For example, if you’re auto-parsing some user input and it is not a selection that the user is choosing, then you’re probably better off storing the user input as-is and having a separate field where you store the result of your parsing the user input.

    This habit is especially important to scale to a Lambda Architecture.

  4. Always use camel-case for data.

    This is something I have learned the hard way when trying to use data passed between Postgresql database, MongoDB database, a Java server, a Django website server with JavaScript / Ajax-based workflows, a Django-based admin, and so on.

    Especially when JavaScript and Java & GSON enter into the picture, life will be much easier if the keys of your JSON data are camel-cased.

  5. Do logging-first development.

    No matter how well-written or well-indented or well-formatted the code is, ultimately, the run-time behavior of the code is what determines the value of the compile-time code.

    Always think about how to log the importants parts of the code which work based on time-sensitive data, so that your post-mortem on why something happened will be far easier.

    For example, storing every API request and response to payment gateways was one of the best things I ever did when writing the ecommerce platform for Automatic. That clarified so many behaviors when investigating things after-the-fact, and it reiterates point 3 where it was easy to reprocess some statuses based on unexpected API responses, etc.

  6. First make it possible. Then make it beautiful. Then make it fast.

    I’ve worked on tasks more efficiently and effectively whenever I have taken the time to get a quick “let’s get it working” version out there first, and then tweaking it constantly to get the software that the stakeholder wants.

    Some call this as how Apple rolls. Some call this as software is grown, not built.

  7. Queues are what makes things scalable.

    Well, queues and asynchronicity are what makes things scalable.

    Use queues wherever you can.

  8. Immutability is paramount.

    It is what will keep your system sane. As @ghoseb says: “One day, we incurred a loss of a million Rupees at my company because of a bug that got triggered by my (apparently pure) code due to our usage of mutable datastructures in Common Lisp.”

    Writing pure functions makes code far more predictable and easier to understand, and at the same time, keeps the prone-to-errors-because-of-data surface area of the code smaller.

    A side-effect (sic) of considering immutability is that you learn to data all the things.

Twitter Comments

@anuragwho says:

@swaroopch 1,2, 6 are probably the most important things in programming ever. And I can’t stress enough on how amazing Grossmans course was.

<!– "Do logging-first development." and other programming lessons @swaroopch learned in '13: http://t.co/ZpjzFXSRlI

+1 for logging-first. –>

NH7 Weekender 2013 Pune was fun. Well, I thought it was better music last year, but the festival is definitely worth visiting every year. Nucleya, Madboy/Mink, Ankur Tewari & The Vinyl Records are the new discoveries for me this year. Started downloading some of their albums and playing their songs on Youtube – this is the best part of NH7 for me, discovering great new bands.

As expected, Blackstratblues, Midival Punditz, Dualist Inquiry, Raghu Dixit Project performed stellar sets and made the festival memorable for me. Vir Das’ Alien Chutney had a so-so performance but their “This is my NH7 song” was a fun standout song. And I really wished Raghu Dixit Project played more from their second album, loved “Parashiva” song.

I think I can’t have enough of listening to Dualist Inquiry and Midival Punditz, kudos to such Indian talent.

The one crib that I have with NH7 event is that smoking kills the music. If there’s one reason, I won’t go to NH7 next year is because the place is filled with 99.9% smokers and the other 0.01%, which includes me, suffer for it. It’s a hard choice between great music and the ability to breathe.

All in all, the weekend is best summarized by a random tweet I came across in the #NH7Weekender hashtag:

@nikhileshmurthy says:

Returning home to blore. Slightly depressed at the prospect of the day job tomorrow after the terrific high of the #NH7Weekender in pune

And it must be said – the OML folks do a remarkably good job of organizing every aspect of the event, it’s a pleasure to attend such events.

NH7 Weekender 2013 NH7 Weekender 2013 NH7 Weekender 2013 NH7 Weekender 2013 NH7 Weekender 2013 NH7 Weekender 2013 NH7 Weekender 2013 NH7 Weekender 2013 NH7 Weekender 2013 NH7 Weekender 2013 NH7 Weekender 2013 NH7 Weekender 2013 NH7 Weekender 2013 NH7 Weekender 2013 NH7 Weekender 2013 NH7 Weekender 2013 NH7 Weekender 2013 NH7 Weekender 2013

Ever since I got back into using OrgMode full-time, I’ve been using Emacs every single minute of using a computer. In fact, these days, I can’t even function without Emacs and OrgMode.

Naturally, it follows, that just like the days when I dived deep into Vim, I’m diving into Emacs these days.

I got interested in Emacs again because of BG’s dotemacs, but to truly become familiar, I had to create my own configuration files. It was a great way to learn Emacs Lisp. I have breezed through the initial chapters of the Emacs Lisp Manual and after getting introduced to Clojure recently, Lisp and functional programming doesn’t seem that alien any more.

I bumped into Cask and Pallet last week (probably via Emacs-Reddit) and that gave me impetus to kickstart my own .emacs.d over the weekend.

$HOME
 |
 \-> .emacs.d
      |
      \-> install.sh
      \-> Cask
      \-> init.el

Contents of the file install.sh :

#!/bin/bash

if [[ ! -e ~/.cask ]]
then
    echo "Cloning Cask repo"
    git clone git@github.com:cask/cask.git ~/.cask
fi

if [[ $(grep "cask/bin" ~/.bash_profile) == "" ]]
then
    echo "Adding \$HOME/.cask/bin to \$PATH in ~/.bash_profile"
    echo '' >> ~/.bash_profile
    echo "# Added by ~/.emacs.d/install.sh" >> ~/.bash_profile
    echo "export PATH=\$HOME/.cask/bin:\$PATH" >> ~/.bash_profile
fi

export PATH=$HOME/.cask/bin:$PATH

cd ~/.emacs.d
cask install

# For Python / ELPY
# Prerequisite: Install Python as per:
# http://docs.python-guide.org/en/latest/#getting-started
pip install --upgrade elpy flake8 rope jedi ipython

Contents of the file Cask initially was (I’ve added more packages now, but this is the minimal list of packages that I would use, although ELPY is optional if you don’t use Python):

(source "gnu" "http://elpa.gnu.org/packages/")
(source "melpa" "http://melpa.milkbox.net/packages/")
(source "marmalade" "http://marmalade-repo.org/packages/")
(source "org" "http://orgmode.org/elpa/")

(depends-on "ack-and-a-half")
(depends-on "cask")
(depends-on "elpy")
(depends-on "exec-path-from-shell")
(depends-on "flx-ido")
(depends-on "magit")
(depends-on "pallet")
(depends-on "projectile")
(depends-on "yasnippet")
(depends-on "zenburn-theme")

A minimal init.el looks like:

;; /This/ file (~init.el~) that you are reading
;; should be in this folder
(add-to-list 'load-path "~/.emacs.d/")

;; Package Manager
;; See ~Cask~ file for its configuration
;; https://github.com/cask/cask
(require 'cask "~/.cask/cask.el")
(cask-initialize)

;; Keeps ~Cask~ file in sync with the packages
;; that you install/uninstall via ~M-x list-packages~
;; https://github.com/rdallasgray/pallet
(require 'pallet)

;; Root directory
(setq root-dir (file-name-directory
                (or (buffer-file-name) load-file-name)))

;; Theme
;; https://github.com/bbatsov/zenburn-emacs
(load-theme 'zenburn t)
(set-cursor-color "firebrick")

;; Font
;; https://www.mozilla.org/en-US/styleguide/products/firefox-os/typeface/#download-primary
(set-frame-font "Fira Mono OT-14" nil t)

;; Don't show startup screen
(setq inhibit-startup-screen t)

;; Show keystrokes
(setq echo-keystrokes 0.02)

;; Path
(require 'exec-path-from-shell)
(when (memq window-system '(mac ns))
  (exec-path-from-shell-initialize))

;; Git
(require 'magit)
(eval-after-load 'magit
  (progn '(global-set-key (kbd "C-x g") 'magit-status)))

;; flx-ido completion system, recommended by Projectile
(require 'flx-ido)
(flx-ido-mode 1)
;; change it if you have a fast processor.
(setq flx-ido-threshhold 1000)

;; Project management
(require 'ack-and-a-half)
(require 'projectile)
(projectile-global-mode)

;; Snippets
;; https://github.com/capitaomorte/yasnippet
(require 'yasnippet)
(yas-load-directory (concat root-dir "snippets"))
(yas-global-mode 1)

;; Python editing
(require 'elpy)
(elpy-enable)
(elpy-use-ipython)

And that’s it, a full-fledged Emacs setup is ready.

The best part is to play around with M-x list-packages and browse around and decide which packages you want to try out and use, when you install a package, it automatically gets added to your Cask file (that’s what Pallet does), so you can convert this .emacs.d folder into a Git repository and sync anywhere and have the same configuration available on multiple machines.

So far, I have resisted many things like evil-mode and started really enjoying using packages such as org-pomodoro and ace-jump-mode.

Getting back to Emacs after a decade has been so much fun.