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

mapping any type #357

Closed
oovm opened this issue May 12, 2024 · 4 comments
Closed

mapping any type #357

oovm opened this issue May 12, 2024 · 4 comments

Comments

@oovm
Copy link

oovm commented May 12, 2024

Is it possible to add any type to the component model, corresponding to anyref (non-nullable) in wasm.

Motivation

I wrote a language and I want to import a generic library from rust. There are two implementations of generics, namely monomorphism and boxing.

My current choice is manual monomorphism and exporting multiple generic versions, which does not have good scalability.

If the any type can be supported, then all generic parameters can be boxed to any, so that rust generics can be imported through ffi.

@lukewagner
Copy link
Member

In both the handle and non-handle contexts, I think any runs into some troubles that make me wary to add it, at least not without a bunch of consideration:

  • Being able to pass a handle to an unknown resource type makes it easy to create subtle reference cycles that leak. Currently, the generativity and lack of dynamic typing keep ownership acyclic.
  • There's some pretty tricky questions for how downcast works in the presence of resource type imports: does the cast get to "see through" the abstract type to the concrete type or does it conservatively treat each type import as distinct? There are pros and cons to each one with subtle implications for security/sandboxing.
  • For values, it's tricky to think of how one unboxes the value: unboxing to a specific type is easy-enough to define, but when thinking about cross-component scenarios, it seems like you'd want a general-case fallback, but I'm not sure what that is. Also, the performance seems worse, requiring an extra intermediate allocation+copy.

Much farther out in the future, there has been early discussion (that we put on hold, since it turned out to be a much bigger bite to chew) around adding a second-class form of generics that, in the context of WIT, we've called "WIT templates". The rough idea is to have a form of early monomorphization (in the spirit of C++ templates, but at link-time instead of individual-component-compile-time) that allowed a component to statically specialize to a particular set of types (thereby avoiding the boxing/unboxing overhead of a universal representation). I hope to return to this after the Component Model MVP is done.

@oovm
Copy link
Author

oovm commented May 15, 2024

This sounds like C++'s export template, although C++ abandoned it for toolchain compatibility and other reasons (Why We Can’t Afford Export), but I still think this is the best of many parametric polymorphism designs.

It can even implement HKT, which is impossible to encode in platforms such as .Net and jvm.

But this is really too far away for us, there are too many details to be finalized, and there are more important things to be stabilized.


At this stage, I try to use resource RustType { } instead of boxing generics, copy in all boxing and unboxing operations, and manually add the recast function I need.

This is enough for my scenario and is a good temporary solution.

Please let me know if the time comes to discuss parametric polymorphism!

@oovm oovm closed this as completed May 15, 2024
@lukewagner
Copy link
Member

Agreed it's rather like export template (which I got to hear all the gory details of back in Bjarne's lab at A&M around the time of that paper). However, instead of framing this in terms of parametric polymorphism (which, to be "parametric", in the theoretical sense of the word, would need to be 100% oblivious to details of the type, including important details we need for performance like sizeof(T), I was instead thinking we should embrace the non-parametricity and frame this instead as staged meta-programming (where wasm can run and reflect on type parameters to generate wasm that is then validated and compiled, all still "ahead of time", preserving the AOT compilation model of wasm). But yes, that's all much farther out and, when it comes back to the front of the priority queue, I'll ping you.

@rossberg
Copy link
Member

@oovm:

but I still think this is the best of many parametric polymorphism designs

Side rant: Only if you don't mind having severely limited parametric polymorphism. For example, C++ cannot have polymorphic virtual methods, which means you cannot implement common patterns like a visitor generically without jumping through hoops. More expressive forms like first-class (or higher-rank) polymorphism or polymorphic recursion are outright impossible under this approach, and so is proper separate compilation, of course (leading to worst-case exponential compile times in C++).

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