Fork me on GitHub
#babashka
<
2022-04-16
>
Tomas Brejla08:04:24

Hi, should it be possible in babashka to set a *print-length*, so that clojure.pprint/pprint doesn't hang on trying to print huge/infinite sequences? While it's possible to perform (set! *print-length* 10) in usual clojure and pprint's output gets trimmed accordingly, the same statement just prints out Can't change/establish root binding of #'clojure.core/*print-length* with set . Is there any alternative approach to achieve "trimming" of pprint output?

borkdude08:04:22

@brdloush binding or alter-var-root should work, you can post an issue about set!

borkdude08:04:43

user=> (alter-var-root #'*print-length* (constantly 10))
10
user=> (range)
(0 1 2 3 4 5 6 7 8 9 ...)

borkdude08:04:41

Did you mean for a REPL or while running a script btw?

Tomas Brejla08:04:49

Not sure yet. I came to *print-length*, because I was trying to work with a huge csv inside calva with cider-jack-in to bb repl. And calva always seemed to try to printout the whole output, no matter the pprint output is limited to something like 50 rows via calva.prettyPrintingOptions.maxLength. When I start the clj repl instead, the output gets correctly truncated, but not with bb repl. Not sure whether that's an issue in calva or bb/sci yet. Or wheter it's an issue really or just expected behavior 🙂 regarding the alter-var-root .. (clojure.pprint/pprint (take 50 (range))) still prints out 50 items though. I guess that's why you asked the question whether "for REPL or running a script", right?

borkdude08:04:20

might be a bug in the pprint bindings. should work if it works in clj, else please post an issue

borkdude09:04:24

@brdloush Fixed on master

🤯 1
👏 1
borkdude 2
Tomas Brejla09:04:21

Awesome, thanks a lot! 😍 I'll try that asap. I believe this fix will help a lot with calva evaluations within bb repl. It's super annoying when the output gets stuck and sometimes one has to kill and restart the repl.

borkdude09:04:40

OK, a new binary will be posted in #babashka-circleci-builds and https://github.com/babashka/babashka-dev-builds once CI finishes

Tomas Brejla09:04:48

;; using following configuration:

;;     "calva.prettyPrintingOptions": {      
;;         "maxDepth": 50,
;;         "printEngine": "pprint",
;;         "enabled": true,
;;         "width": 120,
;;         "maxLength": 5                       <-- important setting
;;     }

(set! *print-length* 5)
;; => 5               <-- no longer an warning printout, seems to work fine

(clojure.pprint/pprint (take 10 (range)))
;; (0 1 2 3 4 ...)  <-- this one seems to behave ok now, nice!

(take 10 (range))
;; => (0 1 2 3 4 5 6 7 8 9)   <-- still not limitting the number of results 

Tomas Brejla09:04:57

It seems to me that calva might be using cider.nrepl.pprint(ie https://github.com/clojure-emacs/cider-nrepl/blob/master/src/cider/nrepl/pprint.clj#L18-L47) for the printout of evaluated results.

borkdude10:04:16

ah then it would be a fix in babashka.nrepl, let me take a look there

borkdude10:04:16

the nrepl fix is a little bit more involved, I see some things about :print-length as an option that CIDER sends, but I'd have to test this

Tomas Brejla10:04:20

I hope that's actually the correct assumption I made about that cider.nrepl/pprint). https://github.com/BetterThanTomorrow/calva/blob/d12ea27fc193aa3001dcf8658d238ed88648ce7f/src/printer.ts#L63-L70 seems to reference cider.nrepl.pprint/pprint. But on the other hand, when I look into that function, it seems to delegate the call to clojure.pprint/write . So effectively something it probably executes something like this ... which already works even on current bb (0.8.1).

(apply clojure.pprint/write (take 10 (range)) (mapcat identity {:stream nil
                                                                :length 5}))
So perhaps calva is printing that using even some other way, don't know.

borkdude10:04:18

This is what I'm getting from CIDER:

:msg {"nrepl.middleware.print/options" {"right-margin" 80}, "id" #object["[B" 0x17a0eed9 "[B@17a0eed9"], "nrepl.middleware.print/buffer-size" 4096, "nrepl.middleware.print/stream?" #object["[B" 0x24ffa64c "[B@24ffa64c"], "nrepl.middleware.print/quota" 1048576, "line" 2, "column" 1, "file" #object["[B" 0x494f56c9 "[B@494f56c9"], "op" #object["[B" 0x2d59adc6 "[B@2d59adc6"], "session" #object["[B" 0x1c97c1d6 "[B@1c97c1d6"], "code" #object["[B" 0xdd07349 "[B@dd07349"], "nrepl.middleware.print/print" #object["[B" 0x96abd9a "[B@96abd9a"], "ns" #object["[B" 0x7b6ed293 "[B@7b6ed293"]}

borkdude10:04:28

More readable:

:msg {:nrepl.middleware.print/buffer-size 4096, :ns "user", :file "/tmp/dude.clj", :nrepl.middleware.print/quota 1048576, :nrepl.middleware.print/print "cider.nrepl.pprint/pprint", :op :eval, :column 1, :line 2, :id "83", :code "(binding [*print-length* 20]\n  (range 20))", :nrepl.middleware.print/stream? "1", :nrepl.middleware.print/options {"right-margin" 80}, :session "ad04d342-2974-48e2-95f2-4

borkdude10:04:38

After alter-var-root of print-length:

:msg {:nrepl.middleware.print/buffer-size 4096, :ns "user", :file "/tmp/dude.clj", :nrepl.middleware.print/quota 1048576, :nrepl.middleware.print/print "cider.nrepl.pprint/pprint", :op :eval, :column 1, :line 3, :id "107", :code "(binding [*print-length* 20]\n  (range 20))", :nrepl.middleware.print/stream? "1", :nrepl.middleware.print/options {"right-margin" 80}, :session "ad04d342-2974-48e2-95f2-

borkdude10:04:02

I don't see the print-length here but maybe this is something you can configure?

borkdude10:04:26

ah right, that must be the maxLength value in Calva

borkdude10:04:22

where do you set those pprint options in calva? I can't find them

borkdude10:04:22

From Calva I get:

:msg {:file "/private/tmp/dude.clj", :nrepl.middleware.print/print "cider.nrepl.pprint/pprint", :op :eval, :column 1, :line 5, :id "29", :code "(range 20)", :stderr {}, :pprint 1, :stdout {}, :nrepl.middleware.print/options {"right-margin" 120, "length" 50, "level" 10}, :session "f044f468-0367-4f8b-9f21-7b3790566066"}
c

Tomas Brejla10:04:13

strange.. "length" 50 in that last output seems to be what shall get passed to clojure.pprint/write here https://github.com/clojure-emacs/cider-nrepl/blob/master/src/cider/nrepl/pprint.clj#L47

borkdude10:04:18

Got it working now:

Tomas Brejla10:04:09

did you have to change anything?

Tomas Brejla10:04:19

I don't get it.. if those options in you last snippet ^^^ get correctly passed to that cider.nrepl.pprint/pprint, it effectively turns into something like this, doesn't it?

(apply clojure.pprint/write (take 10 (range)) '(:right-margin 120 :length 5 :level 10 :stream nil))
;; => "(0 1 2 3 4 ...)"
And this already works OOTB to me.

Tomas Brejla10:04:44

(I just modified length to 5, not 50)

borkdude10:04:45

babashka.nrepl has to pick up on those options

borkdude10:04:05

so I added this:

(let [{:strs [right-margin length level]} (get msg :nrepl.middleware.print/options)]
        (binding [*print-length* length
                  *print-level* level
                  clojure.pprint/*print-right-margin* right-margin]
          (with-out-str (pprint-fn v))))

borkdude10:04:54

Pushing to master now

Tomas Brejla10:04:57

seems like a way to go :thumbsup:

borkdude11:04:38

well, did it work?

Tomas Brejla13:04:16

Just checked the lastest built master. Yes, it works just great now, excelent job!

Tomas Brejla13:04:05

Thanks a lot. I'm wondering.. did this affact only Calva, or even other editors which are using cider nrepl?

borkdude13:04:29

Probably others too

👍 1
pez20:04:14

Yeah, Calva doesn't do anything fancy here. Happy to learn that bb.nrepl supports the pprint pretty printer!

Tomas Brejla22:04:09

And I can confirm that it's a game changer. It's just so nice when your editor doesn't get stuck trying to printout 200k items parsed off a huge csv file and instead just prints a few.

👍 1
Tomas Brejla22:04:15

Not to mention infinite seqs.

willier12:04:52

Hi, I am following the example from dainiusjocas/babashka-lambda and am using a bb.edn with pods . Within my docker image, I am building an uberjar and I would like to include pods in the final zip file (package for aws lambda) Where can I find the pods within the Docker image? or is there a way to tell bb to load the pod into a given directory?

borkdude14:04:50

@U440E3Q0K Pods are installed in ~/.babashka/pods

willier21:04:15

thank you!

willier23:04:13

So when I included the pod in my zip file and bootstrap with the command:

./bb --config bb-local-pods.edn -jar lambda.jar -m lambda.core
where bb-local-pods.edn contains:
{:pods {org.babashka/aws {:path "./pod-babashka-aws"}}}

willier23:04:44

and the full contents of my zip are:

bb
bb-local-pods.edn
bootstrap
lambda.jar
pod-babashka-aws

willier23:04:23

I now encounter the error: Exception in thread "main" java.io.FileNotFoundException: /var/task/.babashka/pod-babashka-aws.metadata.cache (No such file or directory)

willier05:04:45

FWIW i got it to work by turning namespace caching off with

{:path "./pod-babashka-aws"
 :cache false}

borkdude06:04:46

This may be a bug as caching should work. /cc @U06FS3DLH . Perhaps a mkdir -p like bug

borkdude06:04:48

Perhaps you can create the parent directory of that cache file and see if that works

willier07:04:29

I don’t control the container that it’s running in - I’m only uploading a zip file

cap10morgan13:04:08

Seems likely that it's a read-only file system then?

borkdude15:04:36

@U440E3Q0K take a look at #holy-lambda - it has a solution for that

willier22:04:24

cap10morgan: yea, I suspect that you are right borkdude: thanks for your assistance - will take a look into holy-lambda