It's not about technology for its own sake. It's about being able to implement your ideas.
The typical Hollywood hacking scene is an amalgamation of familiar elements: screens full of rapidly changing hex digits, database searches that show each fingerprint or image as it's encountered, password prompts in a 72 point font, dozens of windows containing graphs and random data...oh, and 3D flights through what presumably are the innards of a computer. Somehow the protagonist uses these ridiculous tools to solve a difficult problem in a matter of minutes, all while narrating his exploits with nonsensical techno jargon.
Admittedly, it's a lot more entertaining than the reality of staring at code for hours, sitting through ten minute compile and link cycles, and crying over two page error messages from a C++ template gone bad.
But the part about solving a problem in a matter of minutes? There's some strong appeal in that. Who wouldn't want to explore and come to grips with a tricky issue in real-time?
It's not as outlandish as it sounds. Traditional software development methodologies are based more around encapsulation and architecture than immediate results. To mimic the spirit--not the aesthetics or technical details--of a scene from a bad hacker movie, you need different priorities:
Visualization tools. At the one end of the spectrum are Bret Victor-esque methods for interactively exploring a problem space. On a more basic level, it's tremendously useful to have graphing facilities available at all times. How often are zeros occurring in this data? What are the typical lengths of strings going through this function? Does displaying a matrix as a grid of rectangles, with each unique element mapped to a separate color, show any hidden patterns?
Terseness. It's easier to just say print or cos than remembering output display functions are in system.output.text and cosine is in math.transcendentals. It's easier to have built-in support for lists than remembering what constructors are available for the list class. It may initially seem obtuse that Forth's memory fetch and store operations are named "@" and "!", but that reaction quickly fades and the agility of single-character words sticks with you.
A set of flexible, combinable operations. The humble "+" in array languages does more than a plus operator in C. It not only adds to two numbers, but it can add a value to each element of an arbitrarily long array and add two arrays together. Follow it with a slash ("+/") and the addition operator gets "inserted" between the elements of an array, returning the sum.
It gets interesting when you've got a collection of operations like this that can be combined with each other. Here's a simple example: How do you transform a list of numbers into a list of pairs, where the first element of each pair is the index and the second the original number? Create a list of increasing values as long as the original, then zip the two together. That's impossibly terse in a language like J, but maybe more readily understandable in Haskell or Erlang:
lists:zip(lists:seq(1,length(L)),L).
The trick here is to forget about loops and think entirely in terms of stringing together whole array or list transformations. That lets you try a series single-line experiments while avoiding opening up a text editor and switching your mindset to "formal coding" mode.
(If you liked this, you might enjoy This Isn't Another Quick Dismissal of Visual Programming.)
permalink September 11, 2012
I'm James Hague, a recovering programmer who has been designing video games since the 1980s. Programming Without Being Obsessed With Programming and Organizational Skills Beat Algorithmic Wizardry are good starting points. For the older stuff, try the 2012 Retrospective.
Where are the comments?