Hi Al,

On a practical level, I would be sad if vector-ref, for example, was "impure", and thus compiling a vector-ref invalidated all previously- checked globals for the current scope. Likewise, I would prefer to declare a procedure using vector-ref as pure, to let csc know that it does not modify globals (or the filesystem etc).

The function vector-ref doesn't stop being pure (i.e. referentially transparent) depending how you use it. The function is always referentially transparent -- the expression (vector-ref some-global-vec) isn't. Quoting from "Functional Programming in C++" by Ivan Čukić:

> We’re going to define purity more precisely now, through a concept called referential transparency. Referential transparency is a characteristic of expressions, not just functions. Let’s say an expression is anything that specifies a computation and returns a result. We’ll say an expression is referentially transparent if the program wouldn’t behave any differently if we replaced the entire expression with just its return value. If an expression is referentially transparent, it has no observable side effects, and therefore all functions used in that expression are pure.

(p.104)

I think that part just decides whether the procedure is "pure", for whatever purity means. That doesn't say anything about what compiling a call to such a "pure" procedure means (can memoize the value or not, need to re-check globals or closures afterwards or not etc).

Both the Declarations and Types manual pages say clearly it means "referencial transparency."

And RE local state, that you asked in another email: my understanding is that that refers to variables belonging to the closure, that survive across calls. E.g.:

(define foo
  (let ((x 0))
    (lambda (y)
      (set! x (add1 x))
      (* 2 y))))

siiky



Reply via email to