| > Out of curiosity, do you think that the Shadow Realms proposal they refer to will ever go anywhere? I haven't really been following the Shadow Realm proposal (I'm not part of TC39, so only familiar with certain proposals), but I don't think it should conflict with R/T. If R/T values are allowed to be passed between realms, they should effectively be "transformed" such that eg, `f(#[v])` is equivalent to `f(#[f(v)])` (where `f` is the transformation that allows values to be passed between realms). For "deeply immutable" values (no object references), `f(v)` will simply return `v` (eg, `#[42]`, f(#[42])` and `f(#[f(42)])` are all the same) and a membrane should be able to trivially optimise this case. From this comment[0] it sounds like `f({})` in the current Shadow Realm proposal will throw an error, so I'd expect that `f(#[{}])` would also throw an error. As you were pointing out, I think the only real contention between R/T and realms is in existing JS implementations of membranes, particularly because they might use the following condition to detect if something is "deeply immutable": v === null || typeof v !== "object" && typeof v !== "function"
If `typeof #[{}] === "tuple"`, then their `f` function will pass that value through without handling the contained object value by throwing or by creating/finding a proxy.If `typeof #[{}] === "object"`, it should be fine because `f(#[{}])` will either throw or create/find a proxy for the tuple. There might be some unexpected behaviour around equality of R/T values passed through the membrane, but this is pretty obscure and it should be fixed once the membrane library is updated to handle R/T values. Personally, I'm still not 100% convinced that the assumptions made from the above condition are important enough to cause such a change to the proposal, but I don't see the value of `typeof #[]` as being a usability issue. Code that needs to check the types of things is a bit smelly to me, but in cases where you do need to check the type, `typeof v === "tuple"` and `Tuple.isTuple(v)` both seem usable to me, so just making `typeof #[] === "object"` should be fine and it solves this hypothetical issue. This is similar to array objects, which are also fundamentally special (`Object.create(Array.prototype)` is not an array object) and are detected using `Array.isArray(v)`. > Otherwise, there's the argument that "x.y" syntax shan't be used to access a mutable object from an immutable record, but that just feels like the all-too-common motive of "we must ensure that users write morally-correct code (given our weird idiosyncratic idea of moral correctness), or otherwise make them pay the price for their sins". Agreed, and I've pointed out[1] that even the current proposal doesn't address this, since unless you've done some defensive check on `x`, there's nothing stopping someone passing a mutable object for `x` instead of a record. If you do want to perform a dynamic[2] defensive check, perhaps you should be asking "is it deeply immutable?" or even checking its shape rather than "is it a record?". [0] https://github.com/tc39/proposal-record-tuple/issues/390#iss... [1] https://github.com/tc39/proposal-record-tuple/issues/292#iss... [2] If you're using a type system like TypeScript, this check should happen statically, because you'll use a type that specifies that it's both a record and the types of the properties within it, so your type will encode whether or not it contains mutable objects |