Created
September 16, 2014 08:42
-
-
Save sbaldwin24/48f71b085040fa54125f to your computer and use it in GitHub Desktop.
99 Bottles of Beer with Underscore
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This imperative version, while somewhat contrived, is emblematic of an imperative | |
programming style. That is, the implementation describes a “99 Bottles of Beer” pro‐ | |
gram and exactly a “99 Bottles of Beer” program. Because imperative code operates at | |
such a precise level of detail, they are often one-shot implementations or at best, difficult | |
to reuse. Further, imperative languages are often restricted to a level of detail that is good | |
for their compilers rather than for their programmers (Sokolowski 1991). | |
By comparison, a more functional approach to this same problem might look as follows: | |
function lyricSegment(n) { | |
return _.chain([]) | |
.push(n + " bottles of beer on the wall") | |
.push(n + " bottles of beer") | |
.push("Take one down, pass it around") | |
.tap(function(lyrics) { | |
if (n > 1) | |
lyrics.push((n - 1) + " bottles of beer on the wall."); | |
else | |
lyrics.push("No more bottles of beer on the wall!"); | |
}) | |
.value(); | |
} | |
The lyricSegment function does very little on its own—in fact, it only generates the | |
lyrics for a single verse of the song for a given number: | |
lyricSegment(9); | |
//=> ["9 bottles of beer on the wall", | |
// "9 bottles of beer", | |
// "Take one down, pass it around", | |
// "8 bottles of beer on the wall."] | |
Functional programming is about pulling programs apart and reassembling them from | |
the same parts, abstracted behind function boundaries. Thinking in this way, you can | |
imagine that the lyricSegment function is the part of the “99 Bottles” program that | |
abstracts lyric generation. Therefore, the part of the program that abstracts the assembly | |
of the verse segments into a song is as follows: | |
// === 99 Bottle Program === // | |
function song(start, end, lyricGen) { | |
return _.reduce(_.range(start,end,-1), | |
function(acc,n) { | |
return acc.concat(lyricGen(n)); | |
}, []); | |
// And using it is as simple as: | |
song(99, 0, lyricSegment); | |
//=> ["99 bottles of beer on the wall", | |
// ... | |
// "No more bottles of beer on the wall!"] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment