schemer5rsr7rs

Why does Scheme need the special notion of procedure's location tag?


Why does Scheme need the special notion of procedure's location tag?
The standard says:

Each procedure created as the result of evaluating a lambda expression is (conceptually) tagged with a storage location, in order to make eqv? and eq? work on procedures

The eqv? procedure returns #t if:

  • obj1 and obj2 are procedures whose location tags are equal

Eq? and eqv? are guaranteed to have the same behavior on ... procedures ...

But at the same time:

Variables and objects such as pairs, vectors, and strings implicitly denote locations or sequences of locations

The eqv? procedure returns #t if:

  • obj1 and obj2 are pairs, vectors, or strings that denote the same locations in the store

Eq? and eqv? are guaranteed to have the same behavior on ... pairs ... and non-empty strings and vectors

Why not just apply "implicitly denote locations or sequences of locations" to procedures too?
I thought this concerned them as well
I don't see anything special about procedures in that matter


Solution

  • Pairs, vectors, and strings are mutable. Hence, the identity (or location) of such objects matter.

    Procedures are immutable, so they can be copied or coalesced arbitrarily with no apparent difference in behaviour. In practice, that means that some optimising compilers can inline them, effectively making them "multiple copies". R6RS, in particular, says that for an expression like

    (let ((p (lambda (x) x)))
      (eqv? p p))
    

    the result is not guaranteed to be true, since it could have been inlined as (eqv? (lambda (x) x) (lambda (x) x)).

    R7RS's notion of location tags is to give assurance that that expression does indeed result in true, even if an implementation does inlining.