99 Bottles of Beer/Lisp: Difference between revisions

From Rosetta Code
Content added Content deleted
(moving code from main task-page to sub-page)
(moving code from main task-page to sub-page)
Line 9: Line 9:
See [[99 Bottles of Beer/Lisp]]
See [[99 Bottles of Beer/Lisp]]
-->
-->

=={{header|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 [http://www.lispworks.com/documentation/HyperSpec/Body/22_c.htm 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 <tt>~D</tt> with <tt>~R</tt>, and then with <tt>~@R</tt>. Yes, this is all standard and dependable (dys?)functionality.

Explanation of the format string for the uninitiated:
* <tt>~{<i>fmt</i>~}</tt> expects the next argument to be a list (which is of the integers from 99 down to 0), and executes the format string <i>fmt</i> on each element. It is essentially a map or foreach.
* <tt>~[...~]</tt> is a case/switch. It executes the <i>n</i>th clause, where <i>n</i> is taken from the next argument. Since there is only one clause here, it will be executed only when the argument is 0.
* <tt>~^</tt> will terminate formatting.
* <tt>~:*</tt> will back-up to the most-recently used argument.
* <tt>~D</tt> prints the next argument as a decimal number.
* <tt>~:P</tt> is for English plurals: it prints <tt>s</tt> if the last argument wasn't 1; it prints nothing otherwise. There's also <tt>~@P</tt> for <tt>y</tt>/<tt>ies</tt>, in case you were worried about that.
Note, by the way, how the emoticons <tt>:*~D</tt> and <tt>:P</tt> have shown up in the format string. FORMAT is so powerful, it's even self-aware about how silly it is.



=={{header|PicoLisp}}==
=={{header|PicoLisp}}==

Revision as of 05:35, 21 November 2014

99 Bottles of Beer/Lisp is part of 99 Bottles of Beer. You may find other members of 99 Bottles of Beer at Category:99 Bottles of Beer.

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>