This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2023-03-03
Channels
- # announcements (15)
- # babashka (143)
- # babashka-sci-dev (2)
- # beginners (35)
- # biff (11)
- # calva (5)
- # cider (8)
- # clerk (4)
- # clj-kondo (58)
- # cljdoc (6)
- # clojure (88)
- # clojure-denmark (1)
- # clojure-europe (77)
- # clojure-nl (1)
- # clojure-norway (16)
- # clojure-uk (1)
- # clojurescript (19)
- # clr (32)
- # code-reviews (158)
- # datahike (5)
- # datomic (10)
- # deps-new (3)
- # fulcro (12)
- # graalvm (20)
- # honeysql (23)
- # hyperfiddle (32)
- # jobs (1)
- # kaocha (10)
- # membrane (6)
- # observability (1)
- # other-languages (2)
- # pathom (5)
- # practicalli (12)
- # reagent (4)
- # reitit (7)
- # releases (1)
- # remote-jobs (1)
- # sci (25)
- # shadow-cljs (52)
Hi! Since recently it was possible to initalize a def and displaying its value with
(clojure.pprint/pprint (def result (#{1 2 3} 4)))
That's no longer the case - I used it a lot in my REPL, employing a REPL-command in Cursive (with clojure-extras).
How could I get that functionality back?I forgot - no it just prints the var's name:
#'user/result
either way, it's the behavior of JVM Clojure as well:
$ clj
Clojure 1.11.0
user=> (require 'clojure.pprint)
nil
user=> (clojure.pprint/pprint (def x 10))
#'user/x
Thanks - I was quite sure that changed. Then something changed on my part.
Maybe in this release: https://github.com/babashka/babashka/blob/master/CHANGELOG.md#10169-2023-01-03
I guess you could make your own "spy" function for vars:
(defn spy [x]
(clojure.pprint/pprint (if (var? x) @x x)))
(spy (def x 10))
or this hack:
user=> (defmethod pp/simple-dispatch clojure.lang.Var [v] (print "#var[") (print @v) (print "]"))
#object[clojure.lang.MultiFn 0x2ce45a7b "[email protected]"]
user=> (clojure.pprint/pprint (def x 10))
#var[10]
Thanks!
If I have a script, foo.clj
:
(ns foo)
(defn bar [_] (println 42))
What's the shortest path to executing bar
via babashka?I would have expected
bb foo.clj -x foo/bar
to work, but that does nothing (exit code 0).
It seems I need a bb.edn
which contains {:paths ["."]}
, and then I can run
bb -x foo/bar
I know I can just do
(ns foo)
(defn bar [_] (println 42))
(bar)
and then simply run bb foo.clj
but that doesn't play well with my workflow, when I'm eg editing foo.clj
and evaluating the whole file in the repl (Conjure), since bar
will then run.Just wondering if bb foo.clj -x foo/bar
could be made to work as I expected, since it would lower the bar a bit for quick bash-replacement scripts.
does bb -m foo/bar
the trick?
you can also just do the top level side effecty thing with:
(when (= *file* (System/getProperty "babashka.file"))
(bar ...))
Ah, makes sense 👍 So as soon as we're dealing with namespaces and such, I'll need to think in classpaths. I guess that makes sense
> top level side effecty thing Oh, that's a nice trick. Like python's if main__ or however it looks
and to install scripts that look more like projects (with multiple namespaces) use #C0400TZENE7 to install them as system-global scripts
for project-local tasks, use babashka tasks: https://book.babashka.org/#tasks
Any guidance on how to print better stacktraces in bb with cognitect-test-runner - or any other runner? Currently I'm getting long unhelpful sci stackframes. I was able to hack cognitext-test-runner like so:
(let [original-report clojure.test/report]
(with-redefs [clojure.test/report
(fn [event]
(if (and (= :error (:type event))
(instance? Throwable (:actual event)))
(do
(println (:cause (Throwable->map (:actual event))))
(->> (:actual event)
(sci/stacktrace)
(sci/format-stacktrace)
(run! println)))
(original-report event)))]
(apply test/run-tests (filter contains-tests? nses))))
which gives me
Running tests in #{"test"}
Testing bblib.slack-test
Assert failed: false
bblib.slack/post - /Users/user/pitch/pitch-app/projects/bblib/src/bblib/slack.clj:5:1
bblib.slack-test - /Users/user/pitch/pitch-app/projects/bblib/test/bblib/slack_test.clj:15:7
clojure.core/with-redefs-fn - <built-in>
bblib.slack-test - /Users/user/pitch/pitch-app/projects/bblib/test/bblib/slack_test.clj:14:5
Ran 1 tests containing 0 assertions.
0 failures, 0 errors.
Any more elegant ideas about how to do this?
I would say that is currently the most important thing to improve, but I think what you did there is how I'd solve it too in the short term
At the moment I have a vendored copy of cognitect-test-runner for this. If you can think of a way how I can share this better with other folks who might be looking for this, I'm curious
if the cognitect test runner is using clojure.stacktrace - perhaps we can tweak bb's builtin clojure.stacktrace to do what you're doing in the patch. this was something I wanted to try, but haven't yet
cognitect-test-runner is literally just 130 lines of wrapper for selecting individual tests from the CLI: https://github.com/cognitect-labs/test-runner/blob/master/src/cognitect/test_runner.clj
It doesn't have any code for printing stacktraces, so it just does what clojure.test does - which does indeed involve clojure.stacktrace https://github.com/clojure/clojure/blob/master/src/clj/clojure/test.clj#L384-L395
If I read that correctly, you could also rebind stack/print-cause-trace
to customize printing
hmm, maybe but not sure if that's possible since those pre-compiled function won't see the SCI var re-binding
Yeah, I brought it up again because this time I made some minor progress towards getting better output
Yeah that seems sensible
Out of curiosity, how would you patch clojure.test - do you bundle your own copy of the file?
if you want to run / develop babashka locally, I recommend doing that with a JVM as to not have to compile it to test every little change
You're right btw - while I can rebind clojure.test/report, this doesn't work
(with-redefs [clojure.stacktrace/print-cause-trace (fn [& args] (prn :BOOM))]
(apply test/run-tests (filter contains-tests? nses)))
Gently dipping my toe into implementing this If that's ok I'll dump my thoughts here stream-of-consciousness style (don't hesitate to skip this or tell me to shut up)
So there's already nice stack trace printing https://github.com/babashka/babashka/blob/master/src/babashka/impl/error_handler.clj#L99
bb -e "(defn f [] (assert false)) (f)"
----- Error --------------------------------------------------------------------
Type: java.lang.AssertionError
Message: Assert failed: false
Location: <expr>:1:28
----- Context ------------------------------------------------------------------
1: (defn f [] (assert false)) (f)
^--- Assert failed: false
----- Stack trace --------------------------------------------------------------
user/f - <expr>:1:1
user - <expr>:1:28
What I understand from the above discussion is this: There's already babashka.impl.clojure.stacktrace, which at the moment simply defers to clojure.stacktrace. So the most natural place to implement sci-aware stacktrace printing would be providing a customized print-stack-trace
As a result, clojure.test would pick up better stack traces, but you'd also get better (pst)
from the repl
user=> (defn f [] (assert false))
#'user/f
user=> (f)
java.lang.AssertionError: Assert failed: false [at <repl>:2:1]
user=> (pst)
AssertionError Assert failed: false
java.lang.reflect.Constructor.newInstance (Constructor.java:490)
sci.impl.Reflector.invokeConstructor (Reflector.java:310)
sci.impl.interop/invoke-constructor (interop.cljc:78)
sci.impl.analyzer/analyze-new/reify--4282 (analyzer.cljc:1084)
sci.impl.analyzer/analyze-throw/reify--4242 (analyzer.cljc:968)
sci.impl.analyzer/return-if/reify--4197 (analyzer.cljc:850)
sci.impl.fns/fun/arity-0--1153 (fns.cljc:106)
sci.lang.Var (lang.cljc:198)
sci.impl.analyzer/return-call/reify--4474 (analyzer.cljc:1402)
sci.impl.interpreter/eval-form (interpreter.cljc:40)
babashka.impl.repl/repl/fn--27449 (repl.clj:81)
babashka.impl.clojure.main/repl/read-eval-print--12639 (main.clj:103)
So how about this as a plan: • Figure out how to customize functions in babashka.impl.clojure.stacktrace • Write a new print-stack-trace to behave like babashka.impl.error-handler/print-stacktrace • Write a unit test for the new function • Write an integration test similar to https://github.com/babashka/babashka/blob/master/test/babashka/test_test.clj#L16 • Optionally, make babashka.impl.error-handler use the new print-stacktrace function to reduce code duplication
sounds like a plan :) one challenge is how to unify the JVM stackstrace stuff with SCI's
Right. Do you want to see ONLY the sci stacktrace or both?
Maybe the sci-error print-stacktrace should be a separate function
Can't promise anything but will try
httpkit server with virtual threads in bb:
(require '[org.httpkit.server :as server])
(import '[java.util.concurrent Executors])
(server/run-server (fn [_]
{:body "Hello"})
{:worker-pool (Executors/newVirtualThreadPerTaskExecutor)
:port 11223})
@(promise)
i'm really enjoying the new http-client. is there a plan to make it possible to set the default interceptors when constructing a client?
@UDXEK491P This is already possible today, but the interceptor namespace isn't available in bb itself. you can load it from source though when you include the http client library
you can provide :request
options to the client when making one:
https://github.com/babashka/http-client/blob/f6903b38abc30efe19dceb27d42b6fec196f73f5/src/babashka/http_client.clj#L15
it doesn't seem like they get used: https://github.com/babashka/http-client/blob/main/src/babashka/http_client/internal.clj#L200 i tried doing this in a client but didn't have luck
{:request {:interceptors [,,,]}
would this work?
(or (:interceptors request-defaults)
(:interceptors req)
interceptors/default-interceptors)
this line should be moved one up: https://github.com/babashka/http-client/blob/f6903b38abc30efe19dceb27d42b6fec196f73f5/src/babashka/http_client/internal.clj#LL202-L202C57
The up arrow doesn't work for my when using bb. I get this:
λ ~/projects : bb
Babashka v1.1.173 REPL.
Use :repl/quit or :repl/exit to quit the REPL.
Clojure rocks, Bash reaches.
user=> ^[[A
Is there a way to fix that?you're running the butlast release btw, 1.2.174 is the latest which has the newer http-client built-in
I don't recommend replacing bb
with rlwrap bb
as this may cause issues, but use a different alias like bbr
or so
yeah, it works, just some minor improvements which may be nice to have, just in case :)
second question, how would you folks share a tiny bb cli to the community. It's like 40 lines. Should I throw it in a gist and tell people to run it like they do all bb scripts?
I'm running bbin install
but am getting this error:
----- Error --------------------------------------------------------------------
Type: clojure.lang.ExceptionInfo
Message: Invalid script coordinates.
If you're trying to install from the filesystem, make sure the path actually exists.
Data: {:script/lib "", :procurer :http, :artifact :unknown-artifact}
Location: /home/chase/.babashka/bbin/bin/bbin:629:11
----- Context ------------------------------------------------------------------
625: [:local :dir] (install-deps-git-or-local cli-opts' summary)
626: [:local :file] (install-local-script cli-opts')
627: [:local :jar] (install-local-jar cli-opts')
628: [:maven :jar] (install-deps-maven cli-opts')
629: (throw (ex-info "Invalid script coordinates.\nIf you're trying to install from the filesystem, make sure the path actually exists."
^--- Invalid script coordinates.
If you're trying to install from the filesystem, make sure the path actually exists.
630: {:script/lib (:script/lib cli-opts')
631: :procurer procurer
632: :artifact artifact})))))))
633:
634: (defn uninstall [cli-opts]
----- Stack trace --------------------------------------------------------------
babashka.bbin.scripts - /home/chase/.babashka/bbin/bin/bbin:629:11
babashka.bbin.cli/run - /home/chase/.babashka/bbin/bin/bbin:657:5
babashka.bbin.cli/run - /home/chase/.babashka/bbin/bin/bbin:654:1
babashka.bbin.cli - /home/chase/.babashka/bbin/bin/bbin:671:10
babashka.bbin.cli/bbin - /home/chase/.babashka/bbin/bin/bbin:706:5
babashka.bbin.cli/bbin - /home/chase/.babashka/bbin/bin/bbin:703:1
babashka.bbin.cli - /home/chase/.babashka/bbin/bin/bbin:709:3
clojure.core/apply - <built-in>
babashka.bbin.cli - /home/chase/.babashka/bbin/bin/bbin:713:3
babashka.bbin.cli - /home/chase/.babashka/bbin/bin/bbin:711:1
@U0CLCL6T0 Perhaps we can support the non-raw link
@U9J50BY4C can you post an issue about that?
yes, you should now be able to execute chatgpt-cli
if you added the bin dir to the path
so I'll throw this up in @announcements Any suggestions on how I should describe using this? Have them install bbin
? Alternatively, they can just take the file from the gist and run it with bb
?
oof, I forgot about this rlwrap
issue. and it doesn't act quite like using bb
to run this in the sense that I followed some other advice I got in another thread here to change my inputrc https://clojurians.slack.com/archives/C053AK3F9/p1677870509616049?thread_ts=1677868851.028919&cid=C053AK3F9
no it does work for me. but only when running clojure and bb. But I think if I wanted it to work for this new bbin
install I would have to put
$if chatgpt-cli
set enable-bracketed-paste off
$endif
You can also do this:
(when (= *file* (System/getProperty "babashka.file"))
(when-not (babashka.fs/windows?)
(when-not (str/includes? (.get (.command (.info (java.lang.ProcessHandle/current)))) "rlwrap")
(println "Relaunching with rlwrap for better readline support")
(babashka.process/exec "rlwrap bb" (str *file*)))))
ahh, cool. I will bookmark that comment. For now just throwing in alias chat="rlwrap chatgpt-cli"
works super fast. lol
thanks, this is awesome btw. Super quick and painless to convert over from my .clj file
Some more ideas for reading input from the console: https://rattlin.blog/bbgum.html gum is very cool, yet you will have a dependency that people have to install. There is also a library for bb for it, but shelling out to it should be easy as well. https://github.com/lispyclouds/bblgum
I filed that issue: https://github.com/babashka/bbin/issues/56
btw the rlwrap hack from above didn't work, this is a better version:
(require '[babashka.fs]
'[babashka.process])
(defn read-loop []
(while true
(prn (read-line))))
(when (= *file* (System/getProperty "babashka.file"))
(if-not (babashka.fs/windows?)
(if-not (System/getenv "BB_RLWRAP")
(do (println "Relaunching with rlwrap for better readline support")
(babashka.process/shell {:extra-env {"BB_RLWRAP" "true"}}
"rlwrap" "bb" (str *file*)))
(read-loop))
(read-loop)))
Do these instructions look correct? https://gist.github.com/chase-lambert/c5533d8e8fbb71268a25e83ecf8e3cc6
sorry to borry you again @U04V15CAJ but I think adding those comments in messes up the script somehow. How should I put those comments? I get this error now if trying to just run it like ./chatgpt-cli
----- Error --------------------------------------------------------------------
Type: java.lang.Exception
Message: No reader function for tag You
Also, if I alter the gist and then run the bbin install ...
again it fetches the new info right or is it a one install from the gist only?