Fork me on GitHub
#nbb
<
2022-08-30
>
grzm04:08:43

I'm hoping to use the com.stuartsierra/component library with nbb. (I'm also pretty new to nbb.) I can't seem to load it directly.

npx nbb --classpath $(clojure -Sdeps '{:deps {com.stuartsierra/component {:mvn/version "1.1.0"}}}' -Spath) -e "(require 'com.stuartsierra.component)"
----- Error --------------------------------------
Message:  Could not find namespace: com.stuartsierra.component
Could not find namespace: com.stuartsierra.component

grzm04:08:06

Taking a look at the component library itself, I see there's a cljs.core/type->str function used in com.stuartsierra.component.platform namespace. I think this might not be available in nbb.

grzm04:08:22

As a way to confirm, I translated the component project.clj to deps.edn and ran:

npx nbb --classpath $(clojure -Spath) -e "(require 'com.stuartsierra.component.platform)"
----- Error --------------------------------------
Message:  Could not resolve symbol: type->str
Phase:    analysis
Could not resolve symbol: type->str

grzm04:08:06

Is this likely the root of why the component library can't be loaded? I didn't see any other nbb error logging, but I haven't dug in further.

borkdude06:08:54

The issue is that nbb doesn't load jar files. This is documented in the README. You can use nbb.edn though

borkdude06:08:29

What that does is copy the jar files to a working directory and unzips them, then adds them to the classpath

👍 1
borkdude09:08:58

The next error after type->str I get is:

user=> (require '[com.stuartsierra.component :as component])
"#error {:message \"No protocol method IDeref.-deref defined for type null

borkdude09:08:26

Ah this hinges on IPrintWithWriter on line 185. When I remove this, then it all seems to work

borkdude09:08:42

We should somehow add support for IPrintWithWriter...

borkdude09:08:00

but maybe you can fork for now and remove this, so you won't be blocked by this

grzm12:08:00

re: jars vs nbb. Thanks for the reminder. I knew that a couple of weeks ago and forgot it in the interregnum.

grzm12:08:20

re: type->str is this a case of "nbb doesn't have support yet" or "this isn't something nbb is likely to support in the future and we could look at an upstream patch to component"?

borkdude12:08:20

I added that on master now

grzm13:08:01

What's the path for IPrintWithWriter support? It looks like SciRecord implements it, but there's a piece I must be missing: https://github.com/babashka/sci/blob/3288e2988594a20daaadb4ee0662e0c2b2a8ca01/src/sci/impl/records.cljc#L223-L226

borkdude13:08:12

@U0EHU1800 Hmyeah. For the JVM Clojure path, there is hard-coded support for print-method (which is the JVM equivalent of IPrintWithWriter ). We should probably do something similar for the CLJS path. Haven't looked into this that much yet

borkdude13:08:39

But I have ran into this a couple of times, so it's probably good to address this sooner than later

grzm13:08:23

I noticed it came up in one of my first SCI issues 😉 https://github.com/babashka/sci/issues/684

grzm13:08:58

Clearly I've got some kind of inner magnetic pull towards this thing.

borkdude13:08:48

Ah, right, well, print-method now works :)

grzm13:08:28

Indeed it does! The progress you've made in this whole ecosystem is just amazing.

grzm13:08:00

And (as always happens) you rightly pointed out a better solution to what I was actually trying to do.

grzm04:09:30

Been seeing how frustrated I can make myself how much I can learn by poking around and trying to implement this. I've got a failing test (as expected) and would like to confirm the behavior of my local SCI build (from master including the type->str fix) in nbb with the component library. Would you say this is a reasonable thing to do? Or is there a shorter, more direct approach you'd recommend?

grzm04:09:34

(Here's the test I've written, unfinished, but minimal which shows a failure):

(ns sci.core-protocols-test ,,,)
,,,
#?(:cljs
   (deftest iprint-with-writer-test
     (is (= "#<Foo>" (eval* "(defrecord Foo [])
                             (extend-protocol IPrintWithWriter
                               Foo
                               (-pr-writer [this writer opts]
                                 (-write writer \"#<Foo>\")))")))))
And it even fails 🙂
% script/test/node -n sci.core-protocols-test
Running CLJS test in Node with optimizations :none

Testing sci.core-protocols-test

ERROR in (iprint-with-writer-test) (/Users/grzm/dev/sci/test/sci/core_protocols_test.cljc:118:10)
expected: (= "#<Foo>" (eval* "(defrecord Foo [])\n                             (extend-protocol IPrintWithWriter\n                               Foo\n                               (-pr-writer [this writer opts]\n                                 (-write writer \"#<Foo>\")))"))
  actual: #error {:message "No protocol method IDeref.-deref defined for type null: ", :data {:type :sci/error, :line 2, :column 30, :message "No protocol method IDeref.-deref defined for type null: ", :sci.impl/callstack #object[cljs.core.Volatile {:val ({:line 2, :column 30, :ns #object[sci.lang.Namespace], :file nil} {:line 2, :column 30, :ns #object[sci.lang.Namespace], :file nil, :sci.impl/f-meta {:ns #object[sci.lang.Namespace], :macro true, :sci/built-in true, :name extend-protocol}})}], :file nil}, :cause #object[Error Error: No protocol method IDeref.-deref defined for type null: ]}

Ran 5 tests containing 9 assertions.
0 failures, 1 errors.

borkdude14:09:30

Looking at this message now

borkdude14:09:13

Yes, a failing test is a good start :-D

borkdude14:09:38

I'll also take a look at this to investigate some possibilities

grzm15:09:05

Cheers. What's your development workflow for, say, testing the behavior of a sci change in nbb? For example, when you added clj->str in sci, and confirmed that the next issue for component was IPrintWithWriter, what was your setup? I assume you made a local sci build, used that in a local nbb build, and then used that nbb build on either the component source directly or via nbb.edn.

borkdude15:09:07

I added type->str directly in nbb, but in general, yes, that

borkdude15:09:32

but in this issue, I would usually just test on SCI directly

borkdude15:09:46

and then add the new version of SCI to nbb

grzm15:09:59

Right. My goal was to confirm that I was seeing the same deref error in nbb that I'm seeing in the failing sci test (to replicate what you did to find the next failure make sure I was setting up the test correctly, given I'm really cargo-culting/learning by example here)

borkdude15:09:06

What I did to test with component, was, I added it in nbb.edn, added test->str in nbb and then commented out the IPrintWithWriter in the .nbb directory

grzm15:09:39

(The deref error appears "odd" enough—far enough removed from the IPrintWithWriter protocol stuff—that I wasn't sure I wasn't just screwing up writing the test.)

grzm15:09:24

Cool. I'll see if I can follow that methodology myself.

grzm15:09:35

Gosh, now I want to work on this now. But $dayjob beckons.

grzm15:09:47

Thanks for looking at this.

borkdude16:09:22

@U0EHU1800 75693266c6690b0971155bd6139d9854e2b1289a fixes the weird deref error message and gives a better error message

😄 1
borkdude16:09:27

(on master)

grzm16:09:10

Nice. Good error messages are so helpful. I spent a couple of hours yesterday and the day before improving some in some internal tool that I released after Real Users™ found the edge cases I didn't catch.

grzm16:09:12

ERROR in (iprint-with-writer-test) (/Users/grzm/dev/sci/test/sci/core_protocols_test.cljc:118:10)
expected: (= "#<Foo>" (eval* "(defrecord Foo [])\n                             (extend-protocol IPrintWithWriter\n                               Foo\n                               (-pr-writer [this writer opts]\n                                 (-write writer \"#<Foo>\")))\n                             (pr-str (->Foo))"))
  actual: #error {:message "Protocol not found: IPrintWithWriter", :data {:type :sci/error, :line 2, :column 30, :message "Protocol not found: IPrintWithWriter", :sci.impl/callstack #object[cljs.core.Volatile {:val ({:line 2, :column 30, :ns #object[sci.lang.Namespace], :file nil} {:line 2, :column 30, :ns #object[sci.lang.Namespace], :file nil, :sci.impl/f-meta {:ns #object[sci.lang.Namespace], :macro true, :sci/built-in true, :name extend-protocol}})}], :file nil}, :cause #error {:message "Protocol not found: IPrintWithWriter", :data {:type :sci/error, :line 2, :column 30, :file nil}}}
😄