Recursive function writing to buffer

Started by cormullion, October 13, 2008, 11:23:12 AM

Previous topic - Next topic

cormullion

Say I'm using a recursive function. (This is an example, I'm not actually trying to print a list of numbers... :))


(define (r n)
  (println "n is " n)
  (if (> n 0)
      (r (- n 1))))

(r 10)

n is 10
n is 9
n is 8
n is 7
n is 6
n is 5
n is 4
n is 3
n is 2
n is 1
n is 0


But I want that output to go into a buffer, rather than being printed to the output device. Is there a way of using something like "write-buffer" or "push" inside that function that doesn't require me to set a global variable outside the recursive function beforehand? I just want the function to return a string...

Kazimir Majorinc

#1
What's wrong with simple version?


(define (r n)
  (if (>= n 0)
      (append "n is " (string n) "n" (r (- n 1)))
      ""      ))

(println (r 10))
(exit)


n is 10

n is 9

n is 8

n is 7

n is 6

n is 5

n is 4

n is 3

n is 2

n is 1

n is 0





C:NEWLISP>
http://kazimirmajorinc.com/\">WWW site; http://kazimirmajorinc.blogspot.com\">blog.

Lutz

#2
(define (r:r n)
  (if (not r:buff)
(set 'r:buff "")
(write-line (string "n is " n) r:buff))
  (if (> n 0)
      (r (- n 1))
r:buff))

(r 10)

; or

(print (r 10))

Lutz

#3
Probably the parameters in 'write-line' should be swapped for 10.0. Then multiple arguments to write are possible too.

cormullion

#4
Thanks guys - will try your ideas...



My function is really this:


(define (nl-expr-to-string l)
 (dolist (i l)
    (if (atom? (first i))
          (cond
           ((= (first i) 'symbol)
                (write-buffer buf (string (last i))))
           ((= (first i) 'open-paren)
                (write-buffer buf {(}))
           ((= (first i) 'close-paren)
                (write-buffer buf {)}))
           ((= (first i) 'whitespace)
                (dostring (s (base64-dec (last i)))
                  (write-buffer buf (char s))))
           ((= (first i) 'braced-string)
                (write-buffer buf (string "{" (last i) "}")))
           ((= (first i) 'quoted-string)
                (write-buffer buf (string {"} (last i) {"})))                
           ((= (first i) 'bracketed-string)
                (write-buffer buf (string {[text]} (last i) {[/text]})))
           ((= (first i) 'quote)
                (write-buffer buf "'"))
           ((= (first i) 'comment)
                (write-buffer buf (string (last i) "n")))
           ((= (first i) 'integer)
                (write-buffer buf (string (int (last i)))))
           ((= (first i) 'float)
                (write-buffer buf (string (float (last i)))))
           ((= (first i) 'hex)
                (write-buffer buf (string (last i)))))
       ; not an atom
       (nl-expr-to-string  i)))
       buf)


- as you see, I want to avoid having to create 'buf first as a global symbol...

Kazimir Majorinc

#5
In such case, maybe following idiom is appropriate - using

apply, append and map instead of explicit branching of the list on first & rest.


(set 'nl-expr-to-string
      (lambda(l)
         (if (atom? l)

             (cond ((= (first i) 'symbol)
                    (string (last i)))
                    ... )                     ; end of cond

             (apply append (map nl-expr-to-string l)))))
http://kazimirmajorinc.com/\">WWW site; http://kazimirmajorinc.blogspot.com\">blog.