This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2023-06-27
Channels
- # announcements (10)
- # aws (5)
- # babashka (91)
- # beginners (15)
- # biff (3)
- # calva (5)
- # clerk (24)
- # cljdoc (63)
- # clojure (69)
- # clojure-denver (1)
- # clojure-europe (13)
- # clojure-nl (1)
- # clojure-norway (50)
- # clojure-uk (2)
- # clojurescript (2)
- # community-development (6)
- # cursive (3)
- # datomic (4)
- # events (2)
- # fulcro (8)
- # gratitude (1)
- # hyperfiddle (19)
- # jobs-discuss (36)
- # nbb (21)
- # pathom (16)
- # portal (6)
- # re-frame (14)
- # reagent (1)
- # reitit (1)
- # releases (3)
- # remote-jobs (2)
- # shadow-cljs (56)
- # sql (15)
Question about Java interop: is it possible to extend an abstract class and then call its static method?
E.g. Is it possible to call this launch
method? https://github.com/AlmasB/FXGL/blob/22c7ecf98ac2420afac8bd00b8cbed21f09b6f27/fxgl/src/main/java/com/almasb/fxgl/app/GameApplication.java#L49-L52
Apparently something is not working around this line var appClass = ReflectionUtils.getCallingClass(GameApplication.class, "launch");
?
That might be really expecting java stack trace and not clojure one. So you might want to have a slim java wrapper around it to make it work with clojure. https://github.com/AlmasB/FXGL/blob/dev/fxgl-core/src/main/java/com/almasb/fxgl/core/reflect/ReflectionUtils.java#L230
If I want to emit edn thatβs nicely formatted, not just all in one line, how would I do that?
https://github.com/brandonbloom/fipp would a nice production-oriented choice. Code formatters might be designed for a different set of constraints.
on the command line there's https://github.com/borkdude/jet, which I believe pretty-prints by default
I like to use https://github.com/greglook/puget on the command line if colors make sense
Thanks everybody
Hi i'm currently learning clojure and how you debug your programs? Is it possible to set a breakpoint and get a repl there? (I'm using neovim conjure and clojure lsp)
I use Cursive and debugging there is pretty much first-class, with breakpoints and whatnot. So it's at least possible in principle. Although not sure about having a REPL at a breakpoint.
However, FWIW I rarely use it. Instead, I usually use tap>
along with Portal and, if some piece of code is relatively self-contained, incremental evaluation via REPL (i.e. I send different pieces into REPL and check whether the output corresponds with my expectations).
REPL at breakpoint works great in CIDER at least :^): https://docs.cider.mx/cider/debugging/debugger.html
There are lots of other tools. Reveal, and a recently released Morse. If you like debuggers, you might find FlowStorm an amazing tool since it allows you to time travel, among other things (here's https://www.youtube.com/watch?v=YnpQMrkj4v8). There are definitely other things - these are just the ones I could remember at the moment.
Iβll put in a plug for https://github.com/vvvvalvalval/scope-capture. It lets you capture the local bindings at any given code site (kind of like a breakpoint, but without actually stopping execution). Then you can interact with them in the REPL.
Actually it seems like it does, see the doc: https://github.com/Olical/conjure/wiki/Clojure-nREPL-CIDER-deb
cursive's debugger is a traditional line-oriented debugger, allowing stepping out of uninstrumented clojure functions, as well as into and out of Java methods. I'm curious to know if Calva (and other tools mentioned here) support those operations? I just haven't looked.
hi @U0BQ9CF8T, I have been working in #flow-storm for quite some time which is a debugger that works for Clojure and ClojureScript and is IDE independent. Here I leave you a 10min video of some of the most important features https://www.youtube.com/watch?v=Mmr1nO6uMzc, which is newer than the video linked by @U2FRKM4TW before to give you a sense of how it can help you
@U05DWENKHSS The ones based on nRepl cider debugger do support that. But they only support it for Clojure code, so they won't step into/out of Java interop.
@U0K064KQV for a case like the following, if I instrumented ex-2
and stepped until that function returned, I would exit the debugger, unless ex-1
were also instrumented, right? I hope I didn't miss a big thing π
(defn ex-2 [x]
(+ x 1))
(defn ex-1 [x]
(let [x (ex-2 x)]
(+ x 1)))
(t/deftest example
(t/is (= 3 (ex-1 1))))
(mainly curious: If I could do those two debugging things, I'd be able to get along without cursive)
Hum, I was wrong, right I see, if you instrument ex-2, yes it will exit. You need to instrument the entry point. So if you instrument ex-1, when you step into ex-2 it will continue into ex-2 and step through ex-2
Thanks, I appreciate your verifying. It's sometimes been useful with cursive to explore beyond the entry point -- I realize that's a specific tactic, and that you could always look at the stack and choose earlier entry points.
Ya, Cursive is the champ I would say for debugging. But Cider's is easier to get in/out of, because it's repl based.
Both have advantages: I can't think of anything that one or the other didn't shed light on.
one disadvantage of the Cursive debugger (I think a big one) is that is not expression based, just line based, so it is "ok" for looking at the flow, but not good at looking at all the intermediate values, which I think is much more useful in Clojure. Same issue that the browser debugger has for ClojureScript
What exactly do you mean by looking at intermediate values? I'm not sure I follow the difference
@U0K064KQV here I just made a small video with what I mean
so, unless I'm missing something I don't get a lot of value from stepping over in Cursive, I just get to see that the local n has the value 70
the only pro I see for the Cursive debugger (comparing to FlowStorm and cider-nrepl ones) is in its ability to step also over Java code, if you normally do that
Hum, right like it doesn't show the intermediate values as it goes through the sequence pipeline? I'd have to try that in cider to see what it does.
As specific expressions can be evaluated in the REPL the need for a step debugger is far less in Clojure than with other (non-lisp) languages. I tend to pull apart any complex code and evaluate its parts to help me understand what it's doing. I rarely use a debugger except perhaps for convoluted loop recur code (which tends to be refactored anyway) Portal with Neovim Conjure are sufficient for the majority of cases (there is also a DAP feature planned for Conjure to provide debugging) https://practical.li/clojure/data-inspector/portal/
@U0739PUFQ I do need to try flowstorm again, the UX looks great. I think it's the added setup for it as compared to the cider debugger that's just there haha
@U0K064KQV it doesn't require much setup, just an alias that you copy and paste into your deps.edn or project.clj. Since ClojureStorm, for the most, you don't need to think about instrumentation either. So I would say you get to record everything your program is doing for free.
> As specific expressions can be evaluated in the REPL the need for a step debugger is far less in Clojure than with other (non-lisp) languages. I don't fully agree with it. I think it is super powerful to be able to call our functions from our editors, but for systems where functions inputs are complicated values, it is impractical to type the function calls inputs, so you need to rely on some kind of scope capturing, which is also not easy to do for different reasons, like capturing a function inputs when it is being called many times, etc. Also I think that because they are called debuggers a lot of people think about them only in the presence of bugs, which I find to be a small subset of their use. I mostly use them to understand by seeing, which is specially important in dynamic typed languages were you otherwise need to only rely on names and doc strings.
> I'd have to try that in cider to see what it does. @U0K064KQV Stepping wise, Cider will step like FlowStorm and show all intermediate values, the difference being that you can only step forward, and you need to explicitly instrument/un-instrument what you are interested in, while in FlowStorm you can jump around in time as you need.
Ya, I too think people devalue the usefulness of debuggers, I see people saying they use tap> or println, or even people add tracing libs and all that. Yes you can get away with just doing that, and sometimes I do that when I need to see a single value or something easy, but debugging with cider (or it looks like with FlowStorm), is super fast and you'll debug things way faster than manually adding some taps and removing them for example.
there is a bogus
library that does exactly what you want: it interrupts execution and shows a graphical window with REPL and local vars. It also doesn't depend on any kind of editor
sometimes, I spent hours hanging in it, querying the database in the middle of transaction, drinking tea
for people that don't like JavaFx or external windows want to mention that #C03KZ3XT0CF doesn't depend on it, if you are using Emacs there is cider-strom, which uses FlowStorm from an Emacs UI
looks like this
I found something interesting with EDN. Is there a way to specify a keyword with a space in it? It turns out that it is possible to encode one but not decode one in Clojure. Example:
(require '[clojure.edn :as edn])
nil
(def edn-string (prn-str {:color (keyword "Dark Blue")}))
#'user/edn-string
edn-string
"{:color :Dark Blue}\n"
(edn/read-string edn-string)
Execution error at user/eval7 (REPL:1).
Map literal must contain an even number of forms
user=>
Thanks for the responses. I've got some data already written with this so I'll have to come up with a way to read it.
Found a discussion about it in the google groups: https://groups.google.com/g/clojure/c/WvXYkvLoQhI/discussion?pli=1
I think I did add support for that in one of my code base once. Can you have a custom reader for keyword? Maybe it's possible to set one. Or it's possible what I had done is print those keywords with a custom literal and read them back.
(clojure.edn/read-str {:readers {'keyword custom-rdr}} ...) Not sure if something like that works
That's a neat idea.
I've never used #=
what does it mean?
Oh my. Well I guess I'd be in the camp that the clojure.core/keyword
should probably do some validation. Oh well. Thanks for the discussion.