Subject: Re: A string of a list
From: rpw3@rigden.engr.sgi.com (Rob Warnock)
Date: 1999/12/09
Newsgroups: comp.lang.scheme
Message-ID: <82n8cp$anbj4@fido.engr.sgi.com>
Dorai Sitaram <ds26@bunny.gte.com> wrote:
+---------------
| >(let ((result (car list-of-strings)))
| >  (map (lambda (s) (set! result (string-append result " " s)))
| >       (cdr list-of-strings))
| >  result)
| 
| s/map/for-each/, because map does not guarantee that its second argument
| will be processed left-to-right.
+---------------

True, but "map" *would* be the right thing to use if you wanted to avoid
"set!" for some reason (e.g., trying to avoid the write-barrier in a gen-GC).
The following works well enough, if you don't mind a little extra consing
due to the "append":

	> (define (string-append/spaces . list-of-strings)	; [Note#1]
	    (cond
	      ((null? list-of-strings)
	       "")
	      ((null? (cdr list-of-strings))
	       (car list-of-strings))
	      (else
		(apply string-append
		       (car list-of-strings)			; [Note#2]
		       (apply append
			      (map (lambda (x) (list " " x))
			           (cdr list-of-strings)))))))
	> (string-append/spaces)
	""
	> (string-append/spaces "hello")
	"hello"
	> (string-append/spaces "hello" "there" "Joe")
	"hello there Joe"
	> 

Note#1: I took the liberty of adjusting the calling sequence to match
the null- and single-arg behavior of "string-append" (but also [Note#3]).

Note#2: Using the extended form of "apply" causes *another* implicit
"append", so a recursive helper procedure that did its own consing
*might* be a more efficient solution [depending on the relative speeds
of the builtin library & implicit "appends"]:

	(define (string-append/spaces . list-of-strings)
	  (define (aux ls)
	    (if (null? ls)
	      ls
	      (cons " " (cons (car ls) (aux (cdr ls))))))
	  (cond
	    ((null? list-of-strings) "")
	    ((null? (cdr list-of-strings)) (car list-of-strings))
	    (else
	      (apply string-append
		     (cons (car list-of-strings)
			   (aux (cdr list-of-strings)))))))

Note#3: Bonus question for newbies & students. Write a higher-order
procedure "make-string-append-with-separator" such that the above function
could have been instantiated with:

   (define string-append/spaces (make-string-append-with-separator " "))


-Rob

-----
Rob Warnock, 8L-846		rpw3@sgi.com
Applied Networking		http://reality.sgi.com/rpw3/
Silicon Graphics, Inc.		Phone: 650-933-1673
1600 Amphitheatre Pkwy.		FAX: 650-933-0511
Mountain View, CA  94043	PP-ASEL-IA