c++functional-programmingschemehigher-order-functionssicp

Is environment model necessary for higher-order procedures?


When learning SICP, 6.001 lec15 has:

A good understanding of the environment model tells me why (IMHO) C++ will never have a fully-functional map, filter, and fold-right/fold-left procedures that are as convenient as Scheme’s

SICP implements map, filter, fold-left (IMHO they are all based on recursion or iteration):

(define (map proc items)
  (if (null? items)
      nil
      (cons (proc (car items))
            (map proc (cdr items)))))

(define (filter predicate sequence)
  (cond ((null? sequence) nil)
        ((predicate (car sequence))
         (cons (car sequence)
               (filter predicate (cdr sequence))))
        (else (filter predicate (cdr sequence)))))

(define (fold-left op initial sequence)
  (define (iter result rest)
    (if (null? rest)
        result
        (iter (op result (car rest))
              (cdr rest))))
  (iter initial sequence))

Here each recursive calls map will create one new env for each argument list (proc items), so they can be independent (similar for proc and cons etc).

But in my opinion, in C++ the above code can be done with the same ideas based on stack. So independence is still held.

Why does the lec say "C++ will never have a fully-functional map" due to "environment model"?


Based on this comment, in C++ map and filter can be implemented with for loop. proc etc func can be passed with one func pointer. For fold-left, we can use namespace to create one local iter although maybe not elegant. Then how to answer "the relationship between environment model and lackness of map in pre-C++11" (this is one more clear rephrase of the above question based on the comments below)?


Solution

  • I don't know what the author meant there, but my understanding is that the most pertinent issue here is having map use an anonymous function which has access and modifies some variables external to it which are internal to the function which makes the map call:

    (define (foo x y)
      (define (bar z)
        (set! x z)
        y)
      (map bar (list 1 2 3)))