On Mon, Nov 7, 2016 at 4:05 PM, Chris Hanson <c...@chris-hanson.org> wrote:

> OK, after a close reading I agree that you're right. It's also pretty
> clear that eqv? is only allowed to return #t for two empty vectors if they
> have the same address.
>
> In other words, what we are doing isn't permitted, but it would be if we
> took pains to guarantee that there was only one instance of an empty
> vector. Practically speaking, that's not possible to do since we have an
> operation that allows a vector's length to be truncated in place.
>
> For a future standard, it might be reasonable to allow empty vectors to be
> eqv? independent of the address, since a reasonable person could argue that
> they are "normally regarded as the same object". The same could be said for
> empty strings, since they behave like vectors of characters.
>

We had checked specifically for eq?, assuming eqv?
would be the same here.  There are very few impls which
return #t for (eq? (vector) (vector)):

  http://trac.sacrideo.us/wg/wiki/EmptyStringsVectors

I hadn't thought about the case of truncating vectors
in place.  I suppose there is no inverse operation?

The spirit of eqv? is generally operational equivalence.
Anything with a mutable location should therefore not be
equivalent.  Non-empty vectors are clearly not eqv?.
If you put (vector 1) and (vector 1) in an eqv? hash-table,
they should be two different entries.  If you then truncate
both to zero length, what happens?  Have you simply
invalidated the hash table by mutating the keys?  Usually
mutating keys in an eqv? hash table is allowed.

-- 
Alex

On Sun, Nov 6, 2016 at 3:40 PM, Alex Shinn <alexsh...@gmail.com> wrote:
>
>> On Mon, Nov 7, 2016 at 5:51 AM, Chris Hanson <c...@chris-hanson.org>
>> wrote:
>>
>>> The problem here is that the example of empty-vector equivalence isn't
>>> clear about why the equivalence is unspecified. Is it because they are
>>> literals? Or because they're empty? I'm pretty sure the intention is the
>>> former, but there's still an ambivalence.
>>>
>>
>> In R5RS and R6RS it's because of the former.  In R7RS,
>> both reasons apply, as clarified in section 3.4 - because
>> empty vectors "may not be newly allocated", the runtime is
>> free to return the same value.  Where's the ambiguity?
>>
>> --
>> Alex
>>
>> Everything else is consistent in saying that empty vectors are not eqv?
>>> unless they happen to have the same memory address. Which is not the case
>>> here: we're deliberately equating empty vectors because they are
>>> functionally equivalent, and apparently this is not permitted by R7RS
>>> (modulo the ambivalence).
>>>
>>> I think that the interpretation of empty vectors as eqv? is a valid
>>> point of view, despite the standards. That said, our implementation should
>>> adhere to the standards.
>>>
>>> On Sun, Nov 6, 2016 at 5:11 AM, Alex Shinn <alexsh...@gmail.com> wrote:
>>>
>>>> On Sat, Nov 5, 2016 at 6:29 PM, Chris Hanson <c...@chris-hanson.org>
>>>> wrote:
>>>>
>>>>> I can understand why it acts that way, since two empty vectors are
>>>>> equivalent for all intents and purposes.
>>>>>
>>>>> Either way, eqv? and eqv-hash must agree, so one of them has to be
>>>>> changed.
>>>>>
>>>>> The eqv? of empty vectors seems to be false according to R7RS. Except
>>>>> that the section on eqv? is a little ambiguous around exactly this point,
>>>>> so maybe not.
>>>>>
>>>>
>>>> The spec of eqv? is identical to the R5RS, except for the
>>>> equivalence of numbers which is based on the R6RS
>>>> (but fixing the broken wording of R6RS), to be a sort of
>>>> "operational equivalence" which distinguishes, e.g. +0.0
>>>> and -0.0.
>>>>
>>>> For empty vectors, all three specs give the example:
>>>>
>>>>   (eqv? '#() '#()) => <unspecified>
>>>>
>>>> The specs all give special license for constants to make
>>>> it clear this is unspecified.  The definition of `vector' and
>>>> `make-vector' otherwise say they return "newly allocated"
>>>> vectors, suggesting false would be required, but the
>>>> discussion of storage model in section 3.4 of the R7RS
>>>> goes further to allow optimizing this case:
>>>>
>>>>   [...] It is also understood that empty strings, empty vectors,
>>>>   and empty bytevectors, which contain no locations,
>>>>   may or may not be newly allocated.
>>>>
>>>> --
>>>> Alex
>>>>
>>>> On Fri, Nov 4, 2016 at 5:35 PM, Taylor R Campbell <campb...@mumble.net>
>>>>> wrote:
>>>>>
>>>>>> (let ((u (vector))
>>>>>>       (v (vector)))
>>>>>>   (list (list 'eq (eq? u v) (eq-hash u) (eq-hash v)
>>>>>>               (= (eq-hash u) (eq-hash v)))
>>>>>>         (list 'eqv (eqv? u v) (eqv-hash u) (eqv-hash v)
>>>>>>               (= (eqv-hash u) (eqv-hash v)))))
>>>>>> ;Value 15: ((eq #f 107689176 107689168 #f) (eqv #t 107689176
>>>>>> 107689168 #f))
>>>>>>
>>>>>> Oops.
>>>>>>
>>>>>> Why do we treat empty vectors as eqv?  If we do, eqv-hash needs to be
>>>>>> made to agree.
>>>>>>
>>>>>> _______________________________________________
>>>>>> MIT-Scheme-devel mailing list
>>>>>> MIT-Scheme-devel@gnu.org
>>>>>> https://lists.gnu.org/mailman/listinfo/mit-scheme-devel
>>>>>>
>>>>>
>>>>>
>>>>> _______________________________________________
>>>>> MIT-Scheme-devel mailing list
>>>>> MIT-Scheme-devel@gnu.org
>>>>> https://lists.gnu.org/mailman/listinfo/mit-scheme-devel
>>>>>
>>>>>
>>>>
>>>
>>
>
_______________________________________________
MIT-Scheme-devel mailing list
MIT-Scheme-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/mit-scheme-devel

Reply via email to