Language Scheme
(uses the hygenic macro system)
| Date: | 08/11/05 |
| Author: | Evan Farrer |
| URL: | http://www.cs.utah.edu/~farrer/ |
| Comments: | 2 |
| Info: | http://www.schemers.org/ |
| Score: |
;; 99 bottles implemented using a hygenic macro in Scheme (R5RS)
;; Evan Farrer Evan.Farrer@gmail.com
;;
;; At compile time the (beer 99) expression expands into a call to display with a string of the
song lyrics passed as the argument
;; (beer 99) -> (display "99 Bottles of beer on the wall, 99...")
(define-syntax beer
(lambda (stx)
(let* ((plural (lambda (count)
(case count
((1) (format "~a ~a" count "bottle"))
((0) "no more bottles")
(else (format "~a ~a" count "bottles")))))
(gen-line (lambda (pre count)
(let ((pre (syntax-object->datum pre))
(count (syntax-object->datum count)))
(string-append
pre
(if (= 99 count)
""
(format "~a~a~a\n" "Take one down and pass it around, " (plural
count) " of beer on the wall."))
(format "\n~a~a~a~a\n" (string-titlecase (plural count)) " of beer on the
wall, " (plural count) " of beer.")
(if (= 0 count)
"Go to the store and buy some more, 99 bottles of beer on the
wall.\n"
""))))))
(syntax-case stx ()
((_ pre count)
(let ((last (= 0 (syntax-object->datum #'count))))
(with-syntax ((new-pre (gen-line #'pre #'count))
(new-count (sub1 (syntax-object->datum #'count))))
(if last
#'new-pre
#'(beer new-pre new-count)))))
((_ count)
#'(display (beer "" count)))))))
(beer 99)
Download Source | Write Comment
Alternative Versions
| Version | Author | Date | Comments | Rate |
|---|---|---|---|---|
| original version | Tim Goodwin | 04/20/05 | 2 | |
| define-less version | lambda the ultimate | 10/14/10 | 0 | |
| Cleanly factored MAP-based version | Gnomon | 04/18/08 | 2 | |
| slightly shorter, efficient, featureful | Ricardo Malafaia | 08/29/05 | 1 |
Download Source | Write Comment
Add Comment
Please provide a value for the fields Name,
Comment and Security Code.
This is a gravatar-friendly website.
E-mail addresses will never be shown.
Enter your e-mail address to use your gravatar.
Please don't post large portions of code here! Use the form to submit new examples or updates instead!
Comments