-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Support for Option #14
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
Comments
Nah I think this should definitely be possible! It may be a little tricky getting optional integers working, but for sure optional structs/objects should work. |
I have been thinking about the orthogonal approach of creating an Option type in JS. Option.unwrap() -> returns value or raises an exception |
Hm yeah that's definitely possible! I was thinking though we'd probably interpret |
… that would then map to Maybe I was trying too much to make the interfaces for ?Option |
Just 5c - semantically, |
@s3bk er sorry what I mean is that Another example is |
I don't like that some cases would not work. (Then you also have to remember which cases don't work, or you will run into strange bugs.) |
That's true yeah, it can indeed have footguns. I'm somewhat hesitant to introduce JS abstractions though as it's not clear to me where the types/classes would be defined? Applications could also, for example, have their own "optional type" and/or abstraction which wouldn't necessarily jive well with another one being introduced... |
FWIW using For example, one can write function using parameter defaults: const unwrap_or_42 = (x = 42) => x; and just pass unwrap_or_42(/* Some(0) */ 0); // 0
unwrap_or_42(/* None */ undefined); // 42 And |
Just a thought: The same translates neatly to |
I agree that the translation should be lossless. I understand the desire to fit something into the existing idioms, and to avoid object allocations, but the reality is that it doesn't match up. I wonder if we could do some kind of church encoding, and if that would give us anything useful. |
If we are still brainstorming how to correctly represent the And for accurate representation, one would use
|
@csharad That's an odd inconsistency: let x: Option<T> = None; // null
let x: Option<Option<T>> = None; // undefined I would personally expect them to be the same. |
This |
@fitzgen Hmm, that's a good example. How about |
@RReverser I like that idea. Some possible bikeshedding: undefined | { value: T }
undefined | [T] I think using |
I don't see any fundamental issues with this translation 👍 |
FWIW I'm not personally sure if going for a full-on-generic implementation is worth it for something like this. I think we could get things like |
@alexcrichton So are you suggesting to make it a hard error to use types like Also, I think Since bindgen can generate TypeScript types, it would be weird if But I guess it depends on how you want to represent missing fields/arguments in bindgen. Maybe you would prefer to have an explicit |
Oh sure yeah sorry when I say Going the route of something more advanced like |
@alexcrichton Sounds good to me, I agree that nested boxing can be always done later with some explicit syntax or newtypes. |
May be that's a completely separate problem, but my need for #[wasm_bindgen]
extern {
type Element;
// ...
type HTMLDocument;
static document: HTMLDocument;
#[wasm_bindgen(method)]
fn querySelector(this: &HTMLDocument, selector: &str) -> Option<Element>;
} Note that, in that case, the JS function returns null or an element, and so |
@pchampin Yeah, unfortunately, DOM bindings and WebIDL in general don't follow the rest of JS world in this regard. We would probably need an annotation or a separate wrapper type for that. Or maybe just accept |
My proposal is two-fold. First, for None => undefined
None <= undefined | null
Some(x) <=> x In Javascript, people generally don't have doubly nullable types (i.e. nested The other motivation for this mapping is that is meshes nicely with optional arguments for Javascript functions. In the last few days we have been getting lots of pull requests for adding bindings for standard Javascript functionality, and in multiple cases we have had questions on how to handle optional arguments. Using this mapping, we could just make the optional arguments into Secondly, add a new type in enum FaithfulOption<T> {
Null,
Undefined,
Some(T),
}
Null <=> null
Undefined <=> undefined
Some(x) <=> { some: x } While I believe the |
Also, if this sounds like a good approach, I would be happy to do the work to implement it. |
Given the back-and-forths on this issue, and its potential impact on a large group of downstream users of wasm-bindgen, I think we should make this an RFC (your comment is pretty close to what we envision a lightweight RFC to be already, @ohanar). This way, we can solicit feedback from the larger group. I am working on writing up the template RFC and all that right now, will ping back here again when it is ready. |
@fitzgen Sounds good! |
FWIW that sounds reasonable to me @ohanar! I'd probably leave out |
I believe this is now effectively done in #507 and more types can be implemented in follow-ups! |
For people like myself stumbling onto this issue when googling for a way to do that: what's the currently proposed method? |
Unfortunately I don't think there's a great answer, ideally the macro would automatically implement |
Hm, I see. Is there any answer, not necessarily a great one? How should I go about implementing these traits manually for my type? |
What do you mean by "nullify the value"? I don't think I've experienced the issue you're describing, but some clarification would help. |
@RReverser: I have a method #[wasm_bindgen]
pub fn func(&self, param: Option<MyStruct>) -> bool { ... } When I call it from JS as let param = new MyStruct();
console.log(param);
obj.func(param);
console.log(param); I get the output
As I rationalized it for myself, it's a way to preserve Rust semantics of functions "using up" values (but this behavior still persists even if I derive |
@fjarri sorry I haven't looked into what it would take to support this feature, so it may not work today at all. If you'd like, though, can you open a separate issue for this? |
This issue looked like it would be a good match for it, but sure: filed #2370 |
Ideally this would be returned as
null
on the JS side(this seems like lower hanging fruit than
Result
)The good news is that I'm getting my head around WebAssembly so I may be able to help in the future 🤞
Edit: Oof, maybe it's best to tackle the general generics problem before specializing for the
Option
use case.The text was updated successfully, but these errors were encountered: