Question

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

Was it helpful?

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.

OTHER TIPS

Treating procedures as values works in languages like ML where they are truly immutable. But in Scheme, procedures can actually be mutated, because their local variables can be. In effect, procedures are poor man's objects (though the case can also be made that OO-style objects are just poor man's procedures!) The location tag serves the same purpose as the object identity that distinguishes two pairs with identical cars and cdrs.

In particular, giving global procedures identity means that it's possible to ask directly whether a predicate we have been passed is specifically eq? or eqv? or equal?, which is not portably possible in R6RS (though possible in R6RS implementations in practice).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top