Newsgroups: comp.lang.scheme
Path: cantaloupe.srv.cs.cmu.edu!bb3.andrew.cmu.edu!newsfeed.pitt.edu!scramble.lm.com!news.math.psu.edu!news.cac.psu.edu!howland.reston.ans.net!vixen.cso.uiuc.edu!sdd.hp.com!hplabs!hplntx!hplntx.hpl.hp.com!gjr
From: gjr@hplgr2.hpl.hp.com (Guillermo (Bill) J. Rozas)
Subject: Re: MIT Scheme map function evaluates back to front?
Sender: news@hpl.hp.com (HPLabs Usenet Login)
Message-ID: <GJR.96May14114241@hplgr2.hpl.hp.com>
In-Reply-To: cdjeris@midway.uchicago.edu's message of Tue, 14 May 1996 04:44:30 GMT
Date: Tue, 14 May 1996 18:42:41 GMT
Reply-To: gjr@hpl.hp.com
References: <DrDp66.5Fy@midway.uchicago.edu>
Nntp-Posting-Host: hplgr2.hpl.hp.com
Organization: Hewlett-Packard Laboratories, Palo Alto, CA
Lines: 67

In article <DrDp66.5Fy@midway.uchicago.edu> cdjeris@midway.uchicago.edu (Christopher Jeris) writes:

|   From: cdjeris@midway.uchicago.edu (Christopher Jeris)
|   Date: Tue, 14 May 1996 04:44:30 GMT
|
|   I discovered recently (while working on some code from Essentials of
|   Programming Languages, which I think is a *wonderful* book, if any of
|   its authors are lurking) that the `map' function in MIT Scheme 7.4
|   appears to evaluate its arguments back to front.  To wit:
|
|   (map (lambda (x) (display x)) '(a b c d e))
|
|   results in `edcba' being printed (followed by a list of five unspecified
|   return values, of course) rather than the expected `abcde'.  SCM 4e3
|   prints `abcde'.  Now I'm not objecting to this behavior---I know that the
|   order of evaluation of the arguments to `map' is unspecified, and that
|   `for-each' is provided for people who want side-effects and an evaluation
|   order they can rely on.  I'm just curious:  Why is it done this way?

Consider that map is defined essentially (ignoring variable arity) as

(define (map f l)
  (if (null? l)
      '()
      (cons (f (car l))
	    (map f (cdr l)))))

Now assume that an interpreter (or compiler) uses left-to-right order
of argument evaluation.

Then, the left argument to CONS will be evaluated before the right
argument to CONS.  Therefore the call to F will be evaluated before
the recursive call to MAP.  Hence the function will be invoked first
on the first element of the list, then on the second, and so on.

However, if an interpreter uses right-to-left order of argument
evaluation, then the recursive call to MAP will be evaluated before
the call to F.  Hence F will be invoked first on the last element of
the list, then on the next-to-last element of the list, and so on,
until "on the way back up from the recursion" it is invoked on the
first argument of the list.

Hence the order of argument evaluation imposes the order of invocation
on the element of a list.

MIT Scheme's interpreter evaluates arguments right-to-left.  Thus if
your system is interpreted, you will get guaranteed right-to-left
behavior.  The compiler, however, chooses the order of argument
evaluation individually for each call, thus you have no guarantee
that it will always be one way or another.

BTW, the consequences of the order of argument evaluation are quite
far ranging.  One of my pet examples is memoizing tree-recursive
Fibonacci.  If you use a list to remember the values already computed,
depending on the order in which the recursive calls are made, you can
get linear or quadratic behavior.

|
|   (Incidentally, under scheme font-lock-mode in Emacs 19.30, `map' gets
|   printed in the special-form color even though it's a procedure, while
|   `set!' is printed in the procedure (i.e. ordinary) color even though
|   it's a special form.  Is this a deliberate decision, and is it related
|   to the implementation of map in MIT Scheme?)

I doubt that it is related to the implementation of MAP in MIT Scheme.
I have no idea why MAP appears one way and SET! the other.  I
effectively disable colors in my init file, so I hadn't noticed.
