-
Notifications
You must be signed in to change notification settings - Fork 81
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
New dictionary contract semantics breaks record.map with recursive dependencies #1161
Comments
Reporting here our ideas/findings during the weekly meeting: the bulk of the issue is that there are somehow two different - and natural, at least each one in some situations - interpretations of what could First interpretation: "outer" mappingThe first interpretation is a natural extension of the semantics of record mapping on non-recursive records. We mostly ignore that fields might be dependent over other fields, and just slap a function on top of each value of the record, giving:
This is the current semantics. One question is what happens if we override
We could imagine that the result would be:
But this second question is quite orthogonal to this issue, as we'll see. The important characteristic of this first variant is that the mapping operation is applied after the fixpoint computation has taken place. It can't update the recursive occurrence of Second interpretation: "inner" mappingIf we go back to the semantics of recursive records as being functions, where we compute the fixpoint at each record operation, then
This is semantics is different from the previous one, because
This second way of mapping can sound natural (when defined syntactically, or as commuting with the fixpoint function), but it has a strange behavior: it's not obviously possible to type it correctly. For example, That being said, this mapping seems to make sense in the case of contracts. For example, if we apply a contract on top of this record:
We expect this example to work (this kind of case showed up in e.g. the tf-ncl repo) and DiscrepancyThe above issue comes from the discrepancy between the two: polymorphic sealing is done through a dictionary contract, which since recently, just acts like a lazy record contract. This applies the inner semantics, and in particular seals recursive occurrences of fields inside the record, like Unsealing is done by applying the mapped function, but this use the outer semantics, leaving sealed terms inside the record, and causing the error. The solution isn't totally obvious right now. Either making the contract mapping outer, or the record mapping inner, has unpleasant consequences (in each case, the current mapping semantics seem to be the one we want in practice). We what are exploring right now, and have continued this morning, is to consider This is work in progress, and will be surely extensively documented in a note, as the matter isn't trivial. |
@yannham Just to confirm, should:
actually have |
Indeed. Fixed. Thanks! |
* First draft on polymorphic contracts and records * Try to handle polarity flipping in arrow types correctly * Update the note with a description of the issue and our process of resolving it * Describe the problem in #1161 in more detail --------- Co-authored-by: Viktor Kleen <viktor.kleen@tweag.io>
The new dictionary contract semantics from #1141 seem to break
record.map
on records with recursive dependencies. Specifically, #1141 is the first commit to produce the following:Interestingly, all other ways I've tried to narrow down the issue evaluate without a hitch:
The text was updated successfully, but these errors were encountered: