Last active
August 29, 2015 14:06
-
-
Save takikawa/e2adef8dfd409fe88d52 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
optimizable to a single wrapper with B+, B- | |
(box/c int?) | |
|----------------| A+ B- |---------------| | |
| >-| ---------> | b' | | |
| | | | | | |
| A | | | B | | |
| | | | | | |
| | | | | | |
| ^-| <--------- | b = (box 3) | | |
|----------------| A- B+ |---------------| | |
(box/c int?) | |
References to the box in A will always use the version wrapped with the | |
original contract. That is, (mon (box/c int?) b B A). | |
Therefore writes to b in A will check int? and blame A on failure. Reads | |
from b in A will check int? and blame B on failure. | |
This is still ok even if the contract is (box/c (-> int? int?)) because | |
a write will wrap the function with (-> B A) checking (blame A on failure | |
of domain contract, blame B on failure of range). Reads will check | |
(-> A B) as expected. | |
Now b' would normally be (mon (box/c int?) (mon (box/c int?) b B A) A B). | |
But this is equivalent to (mon (box/c int?) b B B). | |
That's because writes to (mon (box/c int?) (mon (box/c int?) b B A) A B) will | |
first check int? and blame B on failure and then check int? and blame A on failure | |
if the first check succeeded. Obviously it is impossible for the contract to | |
blame A though because the int? check is identical. | |
Similarly, a read will check int? and blame B on failure and then check again | |
blaming A on failure. By the same argument as above, A can't be blamed. | |
;;; | |
Now, finally (mon (box/c int?) b B B) is the same as not attaching a contract | |
at all in Typed Racket because we know that TR can never fail to meet either the | |
positive or negative obligations of the type/contract anyway. | |
Or in other words, A can't possibly distinguish whether TR is using the original | |
reference or the new contract-wrapped one anyway, so it doesn't matter if we make them | |
exactly the same. | |
TR only: optimizable to no contract | |
(box/c int?) | |
|----------------| A+ B- |---------------| | |
| >-| ---------> | b' | | |
| | | | | | |
| untyped A | | | typed B | | |
| | | | | | |
| | | | | | |
| ^-| <--------- | b = (box 3) | | |
|----------------| A- B+ |---------------| | |
(box/c int?) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
If you only wrap once, what happens with the following code? Who gets blamed for the call with
"foo"
?