Subject: Re: string-append with evaluation order
From: rpw3@rigden.engr.sgi.com (Rob Warnock)
Date: 1997/08/19
Newsgroups: comp.lang.scheme
Message-ID: <5tb25i$9bj@fido.asd.sgi.com>

David Fox  <fox@graphics.cat.nyu.edu> wrote:
+---------------
| > I'm looking for a function that mimicks the behavior of string-append, with
| > one extension: the order of evaluation of the expressions passed to the
| > function is defined. They should be evaluated from left to right. Any
| > suggestions?
| 
| The order of evaluation of for-each is guaranteed.  Perhaps this works:
| 
| (define-macro (my-string-append . args)
|   `(let ((strings '()))
|      (for-each (lambda (string) (set! strings (cons string strings)))
| 	       (list ,@args))
|      (apply string-append (reverse strings))))
+---------------

As written, that doesn't help, unfortunately. The args will be evaluated --
in undetermined ordered -- before the call to "list", which occurs before
the call to "for-each". You need to do the sequencing at macro-expand time,
something like this quick&dirty version:

(define-macro (my-string-append . args)
  (if (null? args)
    ""
    (let ((tmp (gensym)))
      `(let ((,tmp ,(car args)))
	 (string-append ,tmp (my-string-append ,@(cdr args)))))))


[And with a little more work in the macro, you can reduce this to only
one call to "string-append", and get rid of the final "" as well...]


-Rob

-----
Rob Warnock, 7L-551		rpw3@sgi.com   http://reality.sgi.com/rpw3/
Silicon Graphics, Inc.		Phone: 650-933-1673 [New area code!]
2011 N. Shoreline Blvd.		FAX: 650-933-4392
Mountain View, CA  94043	PP-ASEL-IA