Re: Attribute String...

Subject: Re: Attribute String...
From: Dave Love <d.love@xxxxxxxx>
Date: 06 Oct 1997 18:05:42 +0100
>>>>> "Lassi" == Lassi A Tuura <Lassi.Tuura@xxxxxxx> writes:

 Lassi> Ouch.  Maybe I should spend more time reading the specs and
 Lassi> less time guessing what the interface should be.

Or look at existing implementations.  There are several Scheme in
Scheme runtime systems around.

 Lassi> Here is another candidate that avoids computing the full
 Lassi> `transpose' of the argument lists.  Any idea whether it is
 Lassi> better or worse in terms of memory usage if `map' is used
 Lassi> heavily?

It's several times slower than the following, which is about 20%
faster and less consing than jjc's version for the 3-argument case
measured in the Gambit Scheme interpreter on x86 GNU/Linux using:

  (begin (##gc) (time (mapx + l l)) (##gc) (time (mapx + l)) #t)

Here (length l) is 10000 and ##gc invokes the collector.  [Yes,
apropos a previous comment, this is integrated with my mailer and
SGML/DSSSL editor :-).]

This map seems relatively a little faster in Jade, which, creditably,
runs at a comparable speed to Gambit in this case -- albeit Gambit
isn't the fastest interpreter around.

Note that the straightforward recursive version is faster over short
lists in Gambit (and would be fast anyway under a compiler optimizing
tail recursion-modulo-cons).  For short strings, I guess Norm's code
(modulo list-ref) would be tolerably good.

It would be nice to add `map' as a Jade primitive, but I don't grok
its evaluator.

HTH.

(define (map f #!rest l)
  (letrec
      ;; Aux functions for the simple case: single list arg to map
      ((map1 (lambda (f l)		; probably good for short arg list
	       (if (null? l)
		   '()
		   (cons (f (car l))
			 (map1 f (cdr l))))))
       (map2 (lambda (f l)		; tail-recursive for long arg list
	       (reverse
		(let loop ((acc '()) (l l))
		  (if (null? l)
		      acc
		      (loop (cons (f (car l)) acc)
			    (cdr l))))))))
    (cond ((null? l)
	   '())
	  ((null? (cdr l))
	   (map2 f (car l)))		; tail-recursive variant
	  (else
	   (reverse
	    (let loop ((acc '()) (l l))
	      (if (null? (car l))
		  acc
		  (loop (cons (apply f (map1 car l))
			      acc)
			;; simple recursive map, assuming l is short
			(map1 cdr l)))))))))

 DSSSList info and archive:  http://www.mulberrytech.com/dsssl/dssslist


Current Thread