Fork me on GitHub

Is it considered undefined behavior to use extend-type to “override” a record’s implementation of a protocol method? Concretely

(defprotocol Foobar
  (foo [this])
  (bar [this]))

(defrecord Thing []
  (foo [this] "Called foo")
  (bar [this] "Called bar"))

(bar (->Thing)) ;=> "Called bar"

(extend-type Thing
  (bar [this] "Overloaded!"))

(bar (->Thing)) ;=> "Overloaded!"
(foo (->Thing)) ;=> "Called foo"
This is behaving how I want it to behave, but is it undefined behavior or a bad practice?


It would not surprise me if in some cases you got either behavior


Oh, pardon me, missed that this in #C03S1L9DN


I just tried it in JVM Clojure and using extend-type this way indeed is an error, since under the hood the JVM disallows method implementations to be swapped in and out of classes


That makes me want to believe this is UB, which is unfortunate because there’s a record implementing a protocol in a library and I want to override one method it implements


I would say that patching one fn in a protocol is not really well-defined, it probably won’t change but if this is critical code maybe I wouldn’t rely on it

Braden Shepherdson13:02:33

it seems unfortunate that the ^:export metadata only takes a boolean. I'd like to have conventional Lisp names in my CLJC code, but export them as (a) camelCase and (b) changing things like * and ? to Java-style prefixes like is. (defn ^{:export 'isSameThing} same-thing? [args] ...) I suppose that simply isn't supported. unless maybe shadow-cljs has magic for it?


it takes a string


(defn ^{:export "isSameThing"} ...)

Braden Shepherdson13:02:16

oh so it does work, but it's not well documented.


at least I'm pretty sure it does 😛

Braden Shepherdson14:02:55

so yes and no. ^:export controls the .cljs.module.thisFunction export name. but in a shadow-cljs :npm-module the exports: {...} object uses the this_function snake case names.


ah, :npm-module is a different story. I can change that


^:export is also sugar, (goog/exportSymbol …) or something like that

Braden Shepherdson17:02:35

@U05224H0W is that a change you're open to making? we don't need this urgently, but we're at the start of a big effort of porting JS business logic to CLJC.


sure, open an issue on the shadow-cljs github please. I won't get to it tommorrow probably but should be easy fix soon