99 Bottles of Beer/Lisp
99 Bottles of Beer done in Lisp-languages
Common Lisp
Sensible solution
<lang lisp>(defun bottles (x)
(loop for bottles from x downto 1 do (format t "~a bottle~:p of beer on the wall
~:*~a bottle~:p of beer Take one down, pass it around ~a bottle~:p of beer on the wall~2%" bottles (1- bottles))))</lang> and then just call <lang lisp>(bottles 99)</lang>
Ridiculous
<lang lisp>(format t "~{~[~^~]~:*~D bottle~:P of beer on the wall~%~:*~D bottle~:P of beer~%Take one down, pass it around~%~D bottle~:P~:* of beer on the wall~2%~}"
(loop :for n :from 99 :downto 0 :collect n))</lang>
The FORMAT function is probably the most baroque (i.e. featureful almost to a fault) function in Common Lisp. To really drive this point home, try replacing each instance of ~D with ~R, and then with ~@R. Yes, this is all standard and dependable (dys?)functionality.
Explanation of the format string for the uninitiated:
- ~{fmt~} expects the next argument to be a list (which is of the integers from 99 down to 0), and executes the format string fmt on each element. It is essentially a map or foreach.
- ~[...~] is a case/switch. It executes the nth clause, where n is taken from the next argument. Since there is only one clause here, it will be executed only when the argument is 0.
- ~^ will terminate formatting.
- ~:* will back-up to the most-recently used argument.
- ~D prints the next argument as a decimal number.
- ~:P is for English plurals: it prints s if the last argument wasn't 1; it prints nothing otherwise. There's also ~@P for y/ies, in case you were worried about that.
Note, by the way, how the emoticons :*~D and :P have shown up in the format string. FORMAT is so powerful, it's even self-aware about how silly it is.
PicoLisp
<lang PicoLisp>(de bottles (N)
(case N (0 "No more beer") (1 "One bottle of beer") (T (cons N " bottles of beer")) ) )
(for (N 99 (gt0 N))
(prinl (bottles N) " on the wall,") (prinl (bottles N) ".") (prinl "Take one down, pass it around,") (prinl (bottles (dec 'N)) " on the wall.") (prinl) )</lang>