Grepability 101

Programming in dynamically typed languages such as JavaScript or Python gives you a lot of freedom over how you structure your code. However, you lose a lot of powerful static analysis and refactoring tools that are available in languages like Java. For example, in Eclipse, you can easily perform tasks such as:

  • Find all the occurrence of a given class or method.
  • Rename or change signature of a given method, and replace all the references to the previous method.

The fundamental nature of dynamic languages make it very challenging to reliably perform those tasks. Thus, instead of relying on sophisticated tools and IDEs, I end up using traditional unix tools such as grep and find to aid me.

However, it is important to give your code more structure to use those tools more efficiently. Here are few things I've learned:

Avoid short and common names - If you have a variable with short names such as x, y, or i, it would be almost impossible to efficiently find all the occurrence of them. Generic names such as min, max, and index are bad for the same reason. Names such as CategoricalFiltertwitter_api_handler are good examples.

Prevent names from being a substring of another - This one is less detrimental than the above one, but it can be annoying if you encounter it frequently. If you have a identifier of both form X and YX (Say, View and PanelView), grep for X would also result in YX. This can be avoided by say, renaming View to BaseView.

Try to use fully qualified names as much as possible - By fully qualified name, I'm referring to the names that includes the module name or namespace identifier. The reason for this is simple - fully qualified names are easier to grep for. In Python, it means that you should prefer "import x.y.z" over "from x.y import z", because the first construct forces you to refer to z via its fully qualified name. In Coffeescript, syntax {identifiers...} = module serves a similar purpose in this context, so it should be avoided.

Avoid referencing names over multiple lines - This can occur if the fully qualified name is too long. if the name is x.y.z, keep it one line.

(Javascript) - Modularize / namespace your code - By default, JS doesn't provide any abstraction for module, and it's very tempting to place all the function declarations, global variables, and prototypes in the single global scope, but this is bad and unscalable, because it's not trivial to trace back where a given function or variable is declared from. To prevent this, do something to give the code more structure. You don't have to do something very fancy:

  • Make sure that every variable in a JavaScript has a specific prefix. For example, all the functions declared in foo.js may start with prefix foo_.
  • Each JavaScript file defines an object that is the same name as the file, and all the variables are defined in that object.
  • Use module management libraries such such as require.js.

I might be missing a lot of stuff, but those are few things I'm thinking about whenever I'm coding in JavaScript and Python.

This entry was posted in Programming, Uncategorized. Bookmark the permalink.