-
Notifications
You must be signed in to change notification settings - Fork 62
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
Mechanism for coercing non-records #38
Comments
It will not call Does this answer your question? If so, please feel free to close :) |
It answers my question but I'm not sure I agree! :) . What is the justification for not calling |
@matthewp I don't understand the language consistency argument. Can you explain where other cases exist that are calling |
I've renamed the title. I don't want this to be about whether |
FYI, this topic (whether to allow non-immutable types be values in Record/Tuple) is already tracked in #31 |
Thats not what this topic is about. |
@rickbutton it's a different topic effectively, the question here is around calling valueOf or not |
Ah yes, good point. #31 is more about "should objects be allowed in records" and this is more about "how to coerce objects into values that can fit into records", good point! |
This part of the proposal shows the usage of I imagine assert.equal(
Record.fromEntries([["date", new Date().toUTCString()]]),
#{ date: "Sat, 17 Aug 2019 19:19:42 GMT" }
); |
@matthewp can we close this issue? |
@mheiber No, fromEntries / from only do shallow conversion so they won't work for nested data structures. If this proposal supported some mechanism like |
Deep conversion could be implemented in user land on top of shallow conversion. It's likely to be expensive, so I worry about encouraging deep conversion.
|
I see two separate issues here:
|
@littledan On the second point, is your issue specifically with the literal form or does it apply to edit: rereading your first point makes me think that your issue is with the literal form. |
I would be surprised if we called ToPrimitive in either case. |
Not sure if ToPrimitive would be the right mechanism or something else. Often the use case is to convert an object to a record. Is a record a primitive? Whatever the mechanism, if we're talking about |
In general, I think records and tuples need to be treated as "primitives". So ToPrimitive would return the same record or tuple. I don't think toJSON is much precedent here. That's a really specific serialization. This is a general construct within the language. I think it'd be pretty odd for us to start calling methods in these cases; at the same time, if we start by throwing an exception, it may be possible for a follow-on proposal to call a method for the case. |
I'd like to propose that the current state of the proposal is a good conclusion for this issue: You can construct Records with |
Agreed, @matthewp please let me know if you want to add anything, otherwise I'm probably close the issue soon |
I disagree with the outcome here. I would like to create APIs that return objects and have those be serializable to Records transparently, without the consumer of the API being aware of every (nested) property on that object and having to do it manually themselves. We have this same capability with JSON today. Without something like this we will need to create |
At the moment we're trying to edge towards being explicit: what should be the behavior when you plug in an object there? TypeError, it's predictable and easy. Nothing prevents you to create a function that ensures serialization: function s(objOrValue) {
if (typeof objOrValue === "object" && "toPrimitive" in objOrValue) {
return objOrValue.toPrimitive();
}
return objOrValue;
}
class FooBar {
constructor(foo, bar) {
this.foo = foo;
this.bar = bar;
}
toPrimitive() {
return #{
foo: this.foo,
bar: this.bar,
};
}
}
const foobar = new FooBar(1, 2);
const meta = #{ message: "it's a foobar" };
const foobarContainer = #{
value: s(foobar),
meta: s(meta),
};
console.log(foobarContainer); |
I don't want to dismiss your use case but I'm not entirely sure we want to make it hard to explain why it does a TypeError sometimes and sometimes not because the object is serializable... |
This is where we disagree, it's not predictable if in some places the language requires explicitness and in some places the language is implicit. It becomes quite unpredictable, which makes the language more difficult to use overall. JavaScript has been an implicit language in a number of ways over the years from type coercion to
Since we know that such serialization functions are going to be written and bulk up bundle sizes, why not just build this useful feature into the language? |
Given the solution posed in #38 (comment) , and the language's history of not providing a built-in deep-copy/clone operation for objects, I think the conclusion here should be that the methods of coercion to |
No objection. |
Great! Thank you all :) |
What happens if you do:
Does it call .valueOf() which in this case returns a Number?
The text was updated successfully, but these errors were encountered: