Last night, I went to a coding meet-up where a few of the others were playing a game. There's a website called Exercism.IO, where you can download code exercises and submit your answers to a global community of like-minded players. The others had been at it for a few minutes; I had to take time to install the exercises and begin. The basic problem, coded in JavaScript, was "Here are seventeen sentences, each marked as being one of four kinds of conversation: statement, question, argument, or silence. Write a function that successfully matches the expectations of the test case."
While the others struggled with both regular expressions and multiple if / then / else if ...
trees, I went straight for a different solution:
this.hey = function(input) {
var tests = [[function(i) { return /^\s*$/.test(i); }, "Fine. Be that way!"],
[function(i) { return /[A-Z][A-Z]+.*!$/.test(i) || /^[A-Z\s]+\??$/.test(i); }, "Woah, chill out!"],
[function(i) { return /\?$/.test(i);}, "Sure."]];
for(var i = 0, l = tests.length; i < l; i++) {
if (tests[i][0](input)) return tests[i][1]; };
return "Whatever."; };
Seven lines. (Yes, my Javascript coding conventions look like Python and Coffee. Whitespace is one of my secret weapons.) Where everyone else had 20-plus lines of comparisons, I went with the brute-force solution. It took four iterations to shake out all the bugs, all 17 tests passed, and it was done.
There are plenty of places where this is silly code; it's basically arbitrary string reduction, and is completely dependent upon the order of the tests, but as the last result says, "Whatever." To me, however, this reduces a lot of if / then
statements down to a single if expression in a hand-written map/reduce: map all possible regexes with a single string, returning [String | Nothing], then reduce down to a single memo of the String. But really, this comes down to a basic rule: wherever you have a list of things to do, see if your language has a proper List with which to contain them.