WebAssembly / component-model

Repository for design and specification of the Component Model
Other
897 stars 75 forks source link

mapping `any` type #357

Closed oovm closed 1 month ago

oovm commented 1 month ago

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 commented 1 month ago

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:

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 commented 1 month ago

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!

lukewagner commented 1 month ago

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 commented 1 month ago

@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++).