Page 1 of 1

Evaluation order in map

Posted: Sun Jun 25, 2006 3:29 am
by William James
Is it guaranteed that map will apply the function to the list elements in left-to-right order? Will

Code: Select all

(map print (sequence 5 8))
always produce

Code: Select all

5678
?

In Scheme, the order is unspecified. SRFI 1 proposes map-in-order, which works from left to right.

Posted: Mon Jun 26, 2006 11:47 am
by Lutz
Yes, 'map' will always work the argument lists from left to right for the number of args in the first parameter list and assume 'nil' fo a missing argument, which may cause an error message depending on the function applied.

Code: Select all

(map list '(1 2 3 4 5) '(a b c)) 

=> ((1 a) (2 b) (3 c) (4 nil) (5 nil))

(map list '(1 2 3) '(a b c d e)) 

=> ((1 a) (2 b) (3 c))
Lutz

Posted: Tue Jun 27, 2006 5:58 am
by William James
Good. An advantage over Scheme.
A newbie asked the Scheme gurus:
I just want to use a print statement with multiple things inside of it.
This doesn't seem possible. Is there a work-a-round?

(print "the value of variable foo is " foo)
One solution was

Code: Select all

(define (myprint . args)
   (for-each (lambda (x) (display x)) args))
When I suggested

Code: Select all

(define (myprint . args)
  (map display args)) 
I was told that map-in-order (which isn't even in the standard language) would have to be used.

Posted: Tue Jun 27, 2006 1:30 pm
by rickyboy
No, the first solution is "The Right Way" for Scheme, according to R5RS (emphasis mine):
The arguments to for-each are like the arguments to map, but for-each calls proc for its side effects rather than for its values. Unlike map, for-each is guaranteed to call proc on the elements of the lists in order from the first element(s) to the last, and the value returned by for-each is unspecified.
Also, you can drop the lambda too in that person's for-each solution; so that it becomes something like:

Code: Select all

(define (display+ . args) (for-each display args))
Of course, like you, I don't have any objection to applying the left-to-right argument evaluation order constraint on calls to 'map'. Any advantage gained by unconstraining 'map' calls (as R5RS does) will be lost in short order by the effects of Moore's Law anyway. So, Lutz has made a good decision, as you surmised.