99 Bottles

Display the text for the 99 Bottles of Beer song.

For this, I'm using s:evaluate to construct words which display a string when called. This lets the majority of the code read nicely.

~~~{ 'bottle 'bottles 'of 'beer 'on 'the 'wall 'no 'more   'Take 'one 'down, 'pass 'it 'around } [ dup ':%s_'%s_s:put_sp_; s:format s:evaluate ] a:for-each ~~~

Handling of the exact text related to the number of bottles is done with a simple array of functions that get selected based on the number of bottles left. This is done with a very simple filter, where the number of bottles for the purpose of the text is in a set of 2 or more, 1, or none.

~~~{ [ no more bottles      ]   [ #1 n:put sp bottle   ]   [ dup n:put sp bottles ] } 'BOTTLES const   :number-bottles   dup #2 n:min BOTTLES swap a:fetch call ; ~~~

Thanks to the programatically generated words for the verse text, the main code is nicely readable.

~~~:display-verse   number-bottles of beer on the wall  nl   number-bottles of beer              nl   n:dec Take one down, pass it around nl   number-bottles of beer on the wall  nl ;   :verses (n-)   repeat 0; nl display-verse again ;   #99 verses   ~~~