;;; The format string in Common Lisp is almost a
;;; language on its own. Here's a Lisp version
;;; that shows its power. Hope you find it
;;; entertaining.
(in-package "CL-USER")
(defun bottle-song (&optional (in-stock 99) (stream *standard-output*))
;; Original idea and primary coding by Geoff Summerhayes
;; <sumrnot@hotmail.com>
;; Formatting idea by Fred Gilham <gilham@snapdragon.csl.sri.com>
;; Actual formatting & minor recoding by Kent M Pitman
;; <pitman@world.std.com>
(format
stream
"-----~2%~
~{~&~1&~
~[~^~:;~
~1:*~@(~
~R~) bo~
ttle~:P o~
f beer on t~
he wall~01:*~[.~
~:;,~%~1:*~@(~R~
~) bottle~:*~P ~
of beer.~%You t~
ake one down, p~
ass it around, ~
~01%~[*No* more~
~:;~:01*~@(~R~)~
~] bottle~:*~P ~
of beer on the ~
wall.~2&-----~%~
~1%~:*~]~]~}~0%"
(loop for bottle from in-stock downto 0 collect bottle)))
(bottle-song)
Ozs7IFRoZSBmb3JtYXQgc3RyaW5nIGluIENvbW1vbiBMaXNwIGlzIGFsbW9zdCBhCjs7OyBsYW5ndWFnZSBvbiBpdHMgb3duLiBIZXJlJ3MgYSBMaXNwIHZlcnNpb24KOzs7IHRoYXQgc2hvd3MgaXRzIHBvd2VyLiBIb3BlIHlvdSBmaW5kIGl0IAo7OzsgZW50ZXJ0YWluaW5nLgoKKGluLXBhY2thZ2UgIkNMLVVTRVIiKQoKKGRlZnVuIGJvdHRsZS1zb25nICgmb3B0aW9uYWwgKGluLXN0b2NrIDk5KSAoc3RyZWFtICpzdGFuZGFyZC1vdXRwdXQqKSkKCiAgOzsgT3JpZ2luYWwgaWRlYSBhbmQgcHJpbWFyeSBjb2RpbmcgYnkgR2VvZmYgU3VtbWVyaGF5ZXMKICA7OyAgIDxzdW1ybm90QGhvdG1haWwuY29tPgogIDs7IEZvcm1hdHRpbmcgaWRlYSBieSBGcmVkIEdpbGhhbSA8Z2lsaGFtQHNuYXBkcmFnb24uY3NsLnNyaS5jb20+CiAgOzsgQWN0dWFsIGZvcm1hdHRpbmcgJiBtaW5vciByZWNvZGluZyBieSBLZW50IE0gUGl0bWFuCiAgOzsgICA8cGl0bWFuQHdvcmxkLnN0ZC5jb20+CgogIChmb3JtYXQKCiAgICAgICAgICAgc3RyZWFtIAogICAgICAgICAiLS0tLS1+MiV+CiAgICAgICAgICB+e34mfjEmfgogICAgICAgICAgflt+Xn46O34KICAgICAgICAgIH4xOip+QCh+CiAgICAgICAgICB+Un4pIGJvfgogICAgICAgICB0dGxlfjpQIG9+CiAgICAgICAgZiBiZWVyIG9uIHR+CiAgICAgIGhlIHdhbGx+MDE6Kn5bLn4KICAgICAgfjo7LH4lfjE6Kn5AKH5SfgogICAgICB+KSBib3R0bGV+Oip+UCB+CiAgICAgIG9mIGJlZXIufiVZb3UgdH4KICAgICAgYWtlIG9uZSBkb3duLCBwfgogICAgICBhc3MgaXQgYXJvdW5kLCB+CiAgICAgIH4wMSV+WypObyogbW9yZX4KICAgICAgfjo7fjowMSp+QCh+Un4pfgogICAgICB+XSBib3R0bGV+Oip+UCB+CiAgICAgIG9mIGJlZXIgb24gdGhlIH4KICAgICAgd2FsbC5+MiYtLS0tLX4lfgogICAgICB+MSV+Oip+XX5dfn1+MCUiCgogICAobG9vcCBmb3IgYm90dGxlIGZyb20gaW4tc3RvY2sgZG93bnRvIDAgY29sbGVjdCBib3R0bGUpKSkKCgooYm90dGxlLXNvbmcp
; compiling file "/home/N6mIUx/prog.lisp" (written 02 MAR 2019 10:29:22 AM):
; compiling (IN-PACKAGE "CL-USER")
; compiling (DEFUN BOTTLE-SONG ...)
; file: /home/N6mIUx/prog.lisp
; in: DEFUN BOTTLE-SONG
; (FORMAT STREAM "-----~2%~
; ~{~&~1&~
; ~[~^~:;~
; ~1:*~@(~
; ~R~) bo~
; ttle~:P o~
; f beer on t~
; he wall~01:*~[.~
; ~:;,~%~1:*~@(~R~
; ~) bottle~:*~P ~
; of beer.~%You t~
; ake one down, p~
; ass it around, ~
; ~01%~[*No* more~
; ~:;~:01*~@(~R~)~
; ~] bottle~:*~P ~
; of beer on the ~
; wall.~2&-----~%~
; ~1%~:*~]~]~}~0%"
; (LOOP FOR BOTTLE FROM IN-STOCK DOWNTO 0
; COLLECT BOTTLE))
;
; caught WARNING:
; error in FORMAT: Parameters found after #\: or #\@ modifier
; -----~2%~
; ~{~&~1&~
; ~[~^~:;~
; ~1:*~@(~
; ~R~) bo~
; ttle~:P o~
; f beer on t~
; he wall~01:*~[.~
; ~:;,~%~1:*~@(~R~
; ~) bottle~:*~P ~
; of beer.~%You t~
; ake one down, p~
; ass it around, ~
; ~01%~[*No* more~
; ~:;~:01*~@(~R~)~
; ~] bottle~:*~P ~
; of beer on the ~
; wall.~2&-----~%~
; ~1%~:*~]~]~}~0%
; ^
; See also:
; The ANSI Standard, Section 22.3
;
; caught ERROR:
; during macroexpansion of
; (FORMATTER "-----~2%~
; ~{~&~1&~
; ~[~^~:;~
; ~1:*~@(~
; ~R~) bo~
; ttle~:P o~
; f beer on t~
; he wall~01:*~[.~
; ~:;,~%~1:*~@(~R~
; ~) bottle~:*~P ~
; of beer.~%You t~
; ake one down, p~
; ass it around, ~
; ~01%~[*No* more~
; ~:;~:01*~@(~R~)~
; ~] bottle~:*~P ~
; of beer on the ~
; wall.~2&-----~%~
; ~1%~:*~]~]~}~0%").
; Use *BREAK-ON-SIGNALS* to intercept.
;
; error in FORMAT: Parameters found after #\: or #\@ modifier
; -----~2%~
; ~{~&~1&~
; ~[~^~:;~
; ~1:*~@(~
; ~R~) bo~
; ttle~:P o~
; f beer on t~
; he wall~01:*~[.~
; ~:;,~%~1:*~@(~R~
; ~) bottle~:*~P ~
; of beer.~%You t~
; ake one down, p~
; ass it around, ~
; ~01%~[*No* more~
; ~:;~:01*~@(~R~)~
; ~] bottle~:*~P ~
; of beer on the ~
; wall.~2&-----~%~
; ~1%~:*~]~]~}~0%
; ^
; See also:
; The ANSI Standard, Section 22.3
; ==>
; (FORMAT SB-C::DEST
; (FORMATTER "-----~2%~
; ~{~&~1&~
; ~[~^~:;~
; ~1:*~@(~
; ~R~) bo~
; ttle~:P o~
; f beer on t~
; he wall~01:*~[.~
; ~:;,~%~1:*~@(~R~
; ~) bottle~:*~P ~
; of beer.~%You t~
; ake one down, p~
; ass it around, ~
; ~01%~[*No* more~
; ~:;~:01*~@(~R~)~
; ~] bottle~:*~P ~
; of beer on the ~
; wall.~2&-----~%~
; ~1%~:*~]~]~}~0%")
; #:G7)
;
; note: The second argument never returns a value.
; compiling (BOTTLE-SONG);
; compilation unit finished
; caught 1 ERROR condition
; caught 1 WARNING condition
; printed 1 note
; /home/N6mIUx/prog.fasl written
; compilation finished in 0:00:00.128
Unhandled SIMPLE-ERROR in thread #<SB-THREAD:THREAD "main thread" RUNNING
{1001E07133}>:
compilation failed
Backtrace for: #<SB-THREAD:THREAD "main thread" RUNNING {1001E07133}>
0: (SB-DEBUG::DEBUGGER-DISABLED-HOOK #<SIMPLE-ERROR "compilation failed" {1001FA6E03}> #<unavailable argument>)
1: (SB-DEBUG::RUN-HOOK *INVOKE-DEBUGGER-HOOK* #<SIMPLE-ERROR "compilation failed" {1001FA6E03}>)
2: (INVOKE-DEBUGGER #<SIMPLE-ERROR "compilation failed" {1001FA6E03}>)
3: (ERROR "compilation failed")
4: (SB-INT:SIMPLE-EVAL-IN-LEXENV (ERROR "compilation failed") #<NULL-LEXENV>)
5: (SB-INT:SIMPLE-EVAL-IN-LEXENV (WHEN (NTH-VALUE 2 (COMPILE-FILE "prog.lisp")) (ERROR "compilation failed")) #<NULL-LEXENV>)
6: (EVAL (WHEN (NTH-VALUE 2 (COMPILE-FILE "prog.lisp")) (ERROR "compilation failed")))
7: (SB-IMPL::PROCESS-EVAL/LOAD-OPTIONS ((:EVAL . "(when(nth-value 2(compile-file \"prog.lisp\"))(error \"compilation failed\"))") (:EVAL . "(quit)")))
8: (SB-IMPL::TOPLEVEL-INIT)
9: ((FLET #:WITHOUT-INTERRUPTS-BODY-77 :IN SAVE-LISP-AND-DIE))
10: ((LABELS SB-IMPL::RESTART-LISP :IN SAVE-LISP-AND-DIE))
unhandled condition in --disable-debugger mode, quitting