Recursive function writing to buffer

Notices and updates
Locked
cormullion
Posts: 2038
Joined: Tue Nov 29, 2005 8:28 pm
Location: latiitude 50N longitude 3W
Contact:

Recursive function writing to buffer

Post by cormullion »

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

Code: Select all

(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
Posts: 388
Joined: Thu May 08, 2008 1:24 am
Location: Croatia
Contact:

Re: Recursive function writing to buffer

Post by Kazimir Majorinc »

What's wrong with simple version?

Code: Select all

(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>

Lutz
Posts: 5289
Joined: Thu Sep 26, 2002 4:45 pm
Location: Pasadena, California
Contact:

Post by Lutz »

Code: Select all

(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
Posts: 5289
Joined: Thu Sep 26, 2002 4:45 pm
Location: Pasadena, California
Contact:

Post by Lutz »

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

cormullion
Posts: 2038
Joined: Tue Nov 29, 2005 8:28 pm
Location: latiitude 50N longitude 3W
Contact:

Post by cormullion »

Thanks guys - will try your ideas...

My function is really this:

Code: Select all

(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
Posts: 388
Joined: Thu May 08, 2008 1:24 am
Location: Croatia
Contact:

Post by Kazimir Majorinc »

In such case, maybe following idiom is appropriate - using
apply, append and map instead of explicit branching of the list on first & rest.

Code: Select all

(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)))))

Locked