Skip to content
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

exnrefs are nominal #85

Closed
RossTate opened this issue Mar 26, 2020 · 8 comments
Closed

exnrefs are nominal #85

RossTate opened this issue Mar 26, 2020 · 8 comments

Comments

@RossTate
Copy link
Contributor

exnrefs are garbage-collected references that you cast to specific cases, so why aren't they using the same structural design as all other garbage-collected references? They're just structs with a tag field (with a hidden trace field?), so it seems inconsistent to design them differently than all the other structs with a tag field out there.

@rossberg
Copy link
Member

The type exnref is one built-in type. Exceptions define values in this type, so don't relate to structural vs nominal typing.

It is true that exception tags are generative, however, as in any standard semantics, AFAICT. That's mainly for disambiguation, not encapsulation: unlike regular values, raised exceptions can bypass module/abstraction boundaries implicitly, and mix with others in the same type, so that you cannot generally tell what code they originate from when caught. It is essential for correctness that you can tell apart your exceptions from somebody else's exceptions.

@RossTate
Copy link
Contributor Author

So what you're saying is that, in any place where anyref is actually (dynamically) representing references from many languages, then (like with exnref) it is essential for correctness that you can tell your values apart from somebody else's references (in order to avoid unintended coincidences). Thus in such uses of anyref we should expect all references to be generatively tagged values of the form mytag myref. For the sake of discussion, let's call references following this convention mixedref (without actually making that a new static type).

We've also said that any coordinated interlanguage communication should be expected to be done using Interface Types. So with those two expectations, is there any situation where anyref is currently expected to be used that wouldn't be better served by mixedref or myref (where myref is whatever type is guaranteed by a module's own mytag)?

@rossberg
Copy link
Member

So what you're saying is that, in any place where anyref is actually (dynamically) representing references from many languages, then (like with exnref) it is essential for correctness that you can tell your values apart from somebody else's references (in order to avoid unintended coincidences).

That's explicitly not what I am saying. I am saying that this applies to the exception type specifically, because throwing shortcuts explicit data flow through abstraction boundaries. In all regular cases, programs have a choice to not mix values in a single type, but with exceptions they haven't, because all exceptions share the same data flow path.

Moreover, a local exception may propagate through code that does not know about it, e.g., when library A invokes a higher-order function from library B, and passes one of its own function that throws an exception local to A. Interface types cannot help with such tunnelling.

IOW, exceptions need to be extensible sums or something equivalent, and that necessitates generative tags. That's different from subtyping. It does not even necessarily have to do with multiple languages, but just multiple modules defining exceptions independently (though a single language runtime could use secondary tagging to distinguish its own exceptions internally, like LLVM/C++ does).

@RossTate
Copy link
Contributor Author

The point is that any situation where you have uncoordinated mixing of references from different modules, one example of which is exceptions, modules will want to be able to distinguish their references from other reference, just like with exceptions. And for any situation where you have coordinated communication of data across distinct modules, the plan is to use Integrated Types. If that's not the case, then you should be able to give me an example of where anyref that is not better served by mixedref or myref. Having such an example would be very useful.

@rossberg
Copy link
Member

rossberg commented Mar 26, 2020

I don't think anyref is ever meant for uncoordinated mixing of references. It's primary purpose is avoiding assumptions about what a specific (single) reference type is in places where you can't or don't need to know. E.g., as the bound on a type import or export.

@RossTate
Copy link
Contributor Author

RossTate commented Mar 26, 2020

That example purpose of bounds is much more easily achieved by allowing type imports and exports to not have subtyping upper bounds (just like you allow them to not have lower bounds). The purpose of conveying uninterpreted references has no need for anyref to be a supertype of anything; it's better achieved by an unconstrainted type import or (as a placeholder in the absence of type imports) by extref. Note that, in both cases, removing subtyping better achieves the intended purpose.

@rossberg
Copy link
Member

We are getting off-topic for this issue and this proposal. I suggest discussing the merits of bounded abstraction on the type imports proposal.

@tlively
Copy link
Member

tlively commented Feb 12, 2022

exnref no longer exist and we've settled on #243 as the MVP type system, so closing this.

@tlively tlively closed this as completed Feb 12, 2022
rossberg added a commit that referenced this issue May 9, 2023
Use plain type substitution instead of type addresses and static/dynamic types
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants