Open lilactown opened 2 years ago
Not sure if this works nicely with treeshaking if you store protocols in a global table? I guess you could also store the nil methods on a per-protocol object
On Thu, 25 Aug 2022 at 16:28, Will Acton @.***> wrote:
nil (i.e. JS null) can have protocols extended to them in Clojure(Script). However, in JS one cannot set or access properties on null, so the way we extend protocols to all other types does not work.
We could have a simple nil-protocol-table which we would set and look up the value on if nil was passed to extend-type and satisfies?
const nil_protocol_table = Object.create(null); // to avoid prototypes extended to
object
export function satisfiesQMARK(protocol, x) { if (x === null) { x = nil_protocol_table; } return x[protocol];}We would also need to add this same redirection to all protocol method functions we emit.
export const IFoo_bar = Symbol("IFoo_bar");export function bar(foo, a, b) { if (foo === null) { let foo = nil_protocol_table; } return foo[IFoo_bar](foo, a, b);}
While not a lot of code, it's more than double it was before, which is a bummer. Perhaps we could encapsulate this in a helper function.
export function lookup_protocol_method(protocol_method, x) { if (x === null) { let x = nil_protocol_table; }; return x[protocol_method];} export function satisfiesQMARK(protocol, x) { return lookup_protocol_method(protocol, x);} // in user codeexport const IFoo_bar = Symbol("IFoo_bar");export function bar(foo, a, b) { return lookup_protocol_method(IFoo_bar, foo)(foo, a, b);}
— Reply to this email directly, view it on GitHub https://github.com/clavascript/clavascript/issues/130, or unsubscribe https://github.com/notifications/unsubscribe-auth/AACFSBQLEKNGYVSXUKSIQK3V257IVANCNFSM57TK2WUA . You are receiving this because you are subscribed to this thread.Message ID: @.***>
-- https://www.michielborkent.nl https://www.eetvoorjeleven.nu
yeah, we could store it on a per-protocol object too. I'll think more about that.
Is a Symbol an object as well? Maybe we could abuse the protocol symbol for it.
On Thu, 25 Aug 2022 at 17:12, Will Acton @.***> wrote:
yeah, we could store it on a per-protocol object too. I'll think more about that.
— Reply to this email directly, view it on GitHub https://github.com/clavascript/clavascript/issues/130#issuecomment-1227395237, or unsubscribe https://github.com/notifications/unsubscribe-auth/AACFSBX3RTRCEMA7DORBAQDV26EOLANCNFSM57TK2WUA . You are receiving this because you commented.Message ID: @.***>
-- https://www.michielborkent.nl https://www.eetvoorjeleven.nu
It doesn't seem to work like I would hope
Welcome to Node.js v18.7.0.
Type ".help" for more information.
> let s = Symbol("IFoo")
undefined
> s["foo"] = true
true
> s["foo"]
undefined
I believe that in CLJS information about extension is stored on the protocol object, not on the extended types.
This is what happens when you extend to string and null:
goog.object.set(cljs.user.Foo,"string",true);
goog.object.set(cljs.user.foo,"string",(function (_){
return "str";
}));
goog.object.set(cljs.user.Foo,"null",true);
goog.object.set(cljs.user.foo,"null",(function (_){
return "nil";
}));
So the protocol method foo
is both a function and an object that holds a mapping of type (as string) to the implementation.
nil
(i.e. JSnull
) can have protocols extended to them in Clojure(Script). However, in JS one cannot set or access properties onnull
, so the way we extend protocols to all other types does not work.We could have a simple
nil-protocol-table
which we would set and look up the value on ifnil
was passed toextend-type
andsatisfies?
We would also need to add this same redirection to all protocol method functions we emit.
While not a lot of code, it's more than double it was before, which is a bummer. Perhaps we could encapsulate this in a helper function.