Bottles of beer

Here is a fun little programming exercise, printing out the lyrics to the bottles of beer song. Indeed, we were motivated by this large collection of bottles of beer programs. Our code starts by specifying the max number of bottles to sing about, in this case 4. Then we have 3 learn rules that handle applying the bottles operator to different integer types. Yeah, English can be a little annoying in that regard. The first-line and second-line operators then map integers to their respective lines in the song. Then the row operator combines them into a sequence. Finally the sing operator maps a sequence of integers to a sequence of lines of the song, and then prints it all out. The "sdrop tidy" combination is just there to pretty the return value of the sing operator and return the empty ket |>.

Here is the code:

-- Implement, and run, the bottles of beer song:

max |bottles> => |4>

bottles |0> => |no more bottles>
bottles |1> => |1 bottle>
bottles |*> #=> |_self> __ |bottles>

first-line |*> #=> to-upper[1] bottles |_self> __ |of beer on the wall,> __ bottles |_self> __ |of beer.>

second-line |*> #=> |Take one down and pass it around,> __ bottles minus[1] |_self> __ |of beer on the wall.>
second-line |0> #=> |Go to the store and buy some more,> __ bottles max |bottles> __ |of beer on the wall.>

row |*> #=> first-line |_self> . second-line |_self> . |>

sing |*> #=> sdrop tidy print row sreverse srange(|0>, max |bottles>) |>


sing

Here is the output from the code:

4 bottles of beer on the wall, 4 bottles of beer.
Take one down and pass it around, 3 bottles of beer on the wall.

3 bottles of beer on the wall, 3 bottles of beer.
Take one down and pass it around, 2 bottles of beer on the wall.

2 bottles of beer on the wall, 2 bottles of beer.
Take one down and pass it around, 1 bottle of beer on the wall.

1 bottle of beer on the wall, 1 bottle of beer.
Take one down and pass it around, no more bottles of beer on the wall.

No more bottles of beer on the wall, no more bottles of beer.
Go to the store and buy some more, 4 bottles of beer on the wall.

|>

Raw file here.