Sascha Ziemann <[email protected]> writes: > On page 31 of R7RS draft 9 it is written: > > "On symbols, booleans, the empty list, pairs, non-empty > strings, vectors, bytevectors, and records, eq? and eqv? are > guaranteed to have the same behavior." > > And later on the same page: > > "On empty strings, vectors, bytevectors, and records, eq? may > also behave differently from eqv?." > > Have eq? and eqv? the same behaviour for records or do they behave > differently? > > The first sentence could also mean that eq? does the same for strings > and records. But what is the record equivalent for an empty string? > Does it exist?
I believe an empty record would be one without any fields: (define-record-type <token> (make-token) token?) Hrm, at first thought I would expect this to work for creating unique objects that can be compared with `eq?' to test identity, the same way `cons' (or `gensym' if available) is often used. I suppose it is not guaranteed to work that way, per R7RS-small. However, that in turn makes sense when I remind myself of the viewpoint that `eq?' is an efficiency hack over `eqv?', and `eqv?' is a test for operational equivalence; after all two immutable objects with identical contents (including empty contents) are operationally equivalent and could be made to be the same object in memory (as an optimization) even when created through different calls to a constructor. To be pedantically conformant to that viewpoint (though I know it doesn't necessarily try to), R7RS-small should also allow immutable records with identical contents to be `eq?' (and `eqv?'), and not prescribe a #false return-value when testing their equivalence. (All other "container" data types have no way to be immutable other than being literals, or empty, if I'm not mistaken, so this issue only applies to record-types, since they can be defined to be immutable by omitting mutators.) ... Actually, reading sections 6.1 (`eqv?'), 3.4 (storage model), and 5.5 (record-type definitions), I cannot find the precise semantics for record equivalence at all. The `eqv?' definition says that if its arguments are records, it returns #true iff they "denote the same location in the store (section 3.4)", reading section 3.4 I see no mention of records specifically, reading the part of section 5.5 that explains the constructor (<constructor name>), the only thing I see that might relate to section 3.4 is that it specifies the constructor to return "a new record", but there is no mention of the store, locations, or allocation. Section 6 (standard procedures) says that "when a procedure is said to return a /newly allocated/ object, it means that the locations in the object are fresh." The phrase "a new record" doesn't seem clear enough. I might be missing something but this seems like a nontrivial oversight; in short, there seems to be no explicit specification that *any* two different records must return #false when compared with `eqv?' (though it might be obvious). I would propose to add wording to the part of section 5.5 that explains the constructor, specifying either that it must return a newly allocated record for every call (the simple solution, going along well with other wording in the document), or that it must do so only for mutable records and immutable ones with distinct contents to all other records (not all fields are `eqv?') and that immutable ones with identical contents need not denote distinct locations. (In the former option, I believe it is clear enough that the special-casing of empty records "overrides" this wording; the same thing goes for `make-vector', `make-string', etc., which also just say "newly allocated" and don't mention the empty special-case.) Or rather, I would propose that for the errata, since the draft is final and it really is intuitively obvious that at the very least distinct records (mutable and created with different calls to the constructor, or immutable but having non-eqv? fields) must not be `eqv?'. (By the way it comes to my attention that the phrase "newly allocated" is used a few times prior to section 6 where it is described. Section 3.4 speaks of situations where the report speaks of "storage being newly allocated for a variable or object", perhaps that should be clarified to make it obvious that the sole phrase "newly allocated" means the same thing, and the redundant explanation in section 6 removed.) Sorry for the long-winded e-mail, I discovered many things on-the-go and didn't have the time to rewrite it to be shorter. Taylan _______________________________________________ Scheme-reports mailing list [email protected] http://lists.scheme-reports.org/cgi-bin/mailman/listinfo/scheme-reports
