typed-racket
typed-racket copied to clipboard
Refine the return type of `hash-copy` and `for/hash`s.
hash-set, hash-set*, hash-update, hash-remove, and hash-clear should receive an immutable hash table and return an immutable hash table;
hash-set!, hash-set*!, hash-update! , hash-remove!, and hash-clear! should receive a mutable hash table and modify its state;
hash-copy should return a mutable hash table;
for/hash[eq/eqv]: should return an immutable hash table. In the older definition, if a.ty is false, for/hash can't make sure the returned hash table is immutable.
This seems like it breaks existing code, as evidenced by the PRs for other repositories. That doesn't seem like something we want to do, at least not when the breakage seems substantial as it is here.
We might want to try to warn people when they do this, which perhaps might eventually let us make these changes. Unfortunately there isn't currently a good way to surface warnings to users in Racket, so there are some design considerations to be addressed first.
I can see this difficulty. In fact, I thought about creating the PR when I discovered that there was a hidden bug in my code which should be thrown by type system. Unfortunately it seems to break too many repositories so maybe it's not a good idea to merge it now.
I think it's safe to refine operators' return types. And the default return type of for[*]/hash[eq/eqv]: should be #'(Immutable-HashTable Any Any). In this way, we can combine the definitions of define-for/hash:-variant and define-for*/hash:-variant.
Hi @samth, currently this PR only optimizes the return type, I think this change is safe. Will TR consider merging it?
This has some conflicts, and also the changes to the type annotations in the tests worry me.
the changes to the type annotations in the tests worry me.
I thought (Immutable-HashTable A B) is the subtype of (HashTable A B) and these changes should be safe, so I didn't undo the changes to the tests.
This has some conflicts
I thought (Immutable-HashTable Any Any) is the supertype of all immutable hash tables, so it could be used as the default return type when there is no type annotation. I'm not sure where the conflict is, is there any example?
The conflict is a merge conflict, with changes to the files that have happened in the mean time.
I would like to not change the tests, except perhaps for more precise types for the results.