Search code examples
recursionprintingiolispcommon-lisp

LISP Printing to Same Line


Another LISP question, I am currently trying to write a function that will return a triangle, whose size will depend on the input of the user

ex: 7

aaaaaaa 
aaaaaa 
aaaaa 
aaaa 
aaa 
aa 
a 

ex: -3

aaa 
 aa 
  a

I have the code for the positive integer part written, the logic at least, but I've run into a hurdle. I can't seem to have the loop print the letter on the same line. Every time the loop iterates, it goes to the next line. Is there any way to fix this? Also any comments/suggestions on my implementation would be greatly appreciated, I am very new at Lisp. Thanks a bunch everyone! You will find my code below

(defun triangle (k) 
    (if (or (= k 1) (= k -1))
        (print 'a)) 
        (if (> k 0) 
           (loop for n from 0 to k
                 do (print 'a)) 
                (triangle (- k 1))))

        
(print (triangle 2))

Solution

  • Indeed, print prints a newline. princ does not.

    To further control how you print stuff, there is format. It works with directives that start with ~. Thus, ~a (or ~A) prints the object given as argument æsthetically. ~& prints a newline.

    (format t "~a~&" 'a)
    

    t is for *standard-output*.

    See https://lispcookbook.github.io/cl-cookbook/strings.html#structure-of-format

    This link also explains how to align strings to the right or to the left, which you might need (if you go the format route).

    You can make your code shorter. There is make-string count :initial-element character that can replace the loop. A character is written #\a.

    Also you could call triangle recursively only if k is > 0 (zerop). With this and (format t "~a~&" (make-string k :initial-element #\a)), my version has only one call to the print function and less "if" machinery:

    (defun my-triangle (k)
       (format t "~a~&" (make-string k :initial-element #\a))
       (unless (zerop k)
         (my-triangle (decf k))))