Fork me on GitHub
#beginners
<
2021-07-31
>
Russell Mull23:08:16

It appears to be completely undocumented, afaict. But from what I could scrape together, it appears to control externs inference in some way, presumably by telling the compiler that the parameter will always be a clojure value, never a js value. See https://code.thheller.com/blog/shadow-cljs/2017/11/06/improved-externs-inference.html and https://github.com/reagent-project/reagent/commit/a9cace4e14d19a6ebbfdef3c0ec441dcd92ad38d

👍 4
stopa13:07:44

Hey team, noob q: I notice sometimes in clojure I get stacktraces, with errors on what looks like generated clj files:

at clojure.lang.Reflector.invokeMatchingMethod(Reflector.java:154)                                                                                                        
        at clojure.lang.Reflector.invokeStaticMethod(Reflector.java:332)                                                                                                          
        at consistent.slack.webhook$weight_modal.invokeStatic(form-init3437720926784297438.clj:46)                                                                                
        at consistent.slack.webhook$weight_modal.invoke(form-init3437720926784297438.clj:21)                                                                                      
        at consistent.slack.webhook$handle_open_weight_modal.invokeStatic(form-init3437720926784297438.clj:78)                                                                    
        at consistent.slack.webhook$handle_open_weight_modal.invoke(form-init3437720926784297438.clj:66)     
form-init3437720926784297438.clj:46
I am guessing these are because this is how anonymous functions get compiled in Java. Is there a handy way I could figure out “what” source code exactly this was, based on those generated names?

Cora (she/her)13:07:17

the bit to the left tells you what it's from: consistent.slack.webhook$handle_open_weight_modal.invokeStatic

stopa14:07:22

Indeed, but I’d love to know exactly where in that function the error was

noisesmith14:08:12

this "form_init" stuff is one of my least favorite things about lein

noisesmith14:08:25

it's emphatically not a clojure feature

stopa03:08:31

Aah, interesting! Will play with clj and see how it rolls!

noisesmith16:08:43

it can also be avoided via the trampoline feature iirc - I wll test that

noisesmith17:08:42

nope, trampoline doesn't actually help

👍 3
dpsutton14:07:43

how are you starting your process?

Jakub Šťastný14:07:17

After managing to get through the initial hurdles, figuring out how to edit code with structural editing, run it with REPL driven development and got an idea about CJ itself, the last thing that really does bother me a lot are the bloody strack traces and very cryptic error messages. I wish they'd simply make sense to a general dev person, but rather it's like a foreign language one has to learn. Which is not necessary, there are languages with pretty helpful errors, Elm comes to mind.

dpsutton14:07:45

that's been a common refrain. Especially to beginners, the stack traces can appear inscrutable. There has been a lot of work in one of the recent releases to improve error messages. If you have a scenario that you can repeat, you can post it on http://ask.clojure.org and perhaps they can make it better. One thing to point out before you go down this route, is that stack traces are quite wonderful. They point exactly where something has gone wrong. And it can seem quite verbose at first, but if you take a few seconds to look over it and understand how it is laid out, it can be a very useful tool as it is. There are libraries to "humanize" stacktraces more, or omit what the author of the library considers extraneous information. But these types of tools can end up hurting the user by omitting information describing the error.

solf14:07:38

Is there any clojure stacktrace guide?

dpsutton14:07:39

Not that I’m aware of

solf14:07:43

Found this one: https://purelyfunctional.tv/article/wrangling-clojure-stacktraces/ Dated from 2018, not sure if the changes since then are substantial. I know stacktraces were improved about a year ago?

dpsutton14:07:28

The best thing to do I think is when there is a stack trace, don’t let the size of it intimidate and take a moment. Then read the stack trace slowly and identifying which parts of code it is talking about

dpsutton14:07:53

They quickly become pointers to exact lines of code that has had an error

solf14:07:23

I’m actually reasonably good at reading stacktraces, but in my case it’s more of an art than an exact science 😅. I wonder if I’m missing some details As I’m introducing clojure to some people, I’m trying to collect relevant guides, and I’m sure stacktraces are going to come up at some point

dpsutton14:07:06

Fair point. @ghadi in the main channel mentioned a guide might be very welcome and offered to help interpret a stack trace. He’s very thoughtful and has a really methodical way of debugging. If he does a little walkthrough here it would help many passively watching I bet

Jakub Šťastný14:07:41

Oh that'd be cool!

emccue16:07:34

elm got their errors better by making an "error message catalog"

emccue16:07:46

then optimizing around what people ran into

ghadi14:07:34

stack trace "filtering" is a form of data loss

ghadi14:07:24

perhaps there can be better docs on how to read a stacktrace. It's an essential skill to develop

ghadi14:07:11

if you want to post a trace @jakub.stastny.pt_serv, I can help you orient to it

Jakub Šťastný14:07:48

@ghadi @dpsutton thank you. I don't have one at the moment. Actually I'd say my problem is more with the error messages: if I don't get what the problem is, I then don't know what to look for in the stacktrace, that's really my problem. Things like clojure.java.something.something.something.IFs isn't whatever.something.something.else. And the likes.

Jakub Šťastný14:07:55

Reading https://8thlight.com/blog/connor-mendenhall/2014/09/12/clojure-stacktraces.html made me realise that one of the things that confuses me about the stacktraces is that the first line of the stack trace isn't where the problem happened and you actually have to go through the stacktrace and search for where it did. Unlike in many other languages, such as Ruby, where the first line of the trace is always where the error actually comes from. (The article says CJ catches and then re-throws the error, which is why is it this way.)

dpsutton14:07:30

Just an aside, I know what you mean by CJ but it is definitely not a widely used shortening

stopa19:08:51

Hey @dpsutton! I run lein repl, than (-main) , which kicks off a jetty server

Jakub Šťastný14:07:46

Can Cider help somehow with the stack traces? I know it can hide/show certain parts, but the cider-error buffer is still an unreadable mess.

Jakub Šťastný14:07:10

@dpsutton is it not? Is there one?

dpsutton14:07:27

It can filter to only project stack frames and a few other filters

dpsutton14:07:55

But I’d urge you to learn to read it. I believe it just vertically aligns the stack frames by default

dpsutton15:07:08

here are some keybindings for the stacktrace buffer: https://docs.cider.mx/cider/1.1/usage/dealing_with_errors.html#keybindings . Some interesting ones are ways to quickly hide or show internal clojure frames, java frames, duplicate frames, show only stack frames from your project namespaces, etc

👍 2
dpsutton15:07:29

it also is click enabled i believe. so you can click on a stack frame and it should open that code on that line

Jakub Šťastný15:07:15

Thank you, I'll check it out.

Jakub Šťastný15:07:05

I don't have touch enabled in my Emacs, I know I could, but was never bothered to do so. But I'll check the key bindings 🙂

dpsutton15:07:41

I don’t know what touch is in emacs

Jakub Šťastný15:07:03

I mean mouse but I don't have mouse since it's iPad

dpsutton15:07:37

Oh interesting. I didn’t know you could get a clojure dev environment up on that. That’s super interesting

👍 2
sb15:07:41

Yes, that is super interesting. More info? :)

Jakub Šťastný15:07:28

Well it doesn't run on the actual iPad. It's via Blink + Mosh + Ubuntu on a free Oracle VPS.

👍 2
Jakub Šťastný15:07:10

With that said, with Mosh (rather than using SSH directly), you cannot notice a difference, even on a slow connection, it's blazing fast.

Jakub Šťastný15:07:02

I prefer this setup for many reasons. Like it's easy to pair with someone, you can give your colleagues a preview of what you're doing, so they can check that the feature you're implementing is what they actually wanted (something like your private staging) etc. And of course would I need to say repair my iPad, I can connect immediately from any other device, iPad or otherwise, no need to set up the env again, all huge benefits to me.

👍 4
dpsutton15:07:47

it would make for a great article 🙂

👍 4
2
Jakub Šťastný15:07:28

I might consider writing something up. I've been on this iPad Pro + VPS setup for over 3 years now and I really love it. Initially big motivation was that I was travelling a lot, so having a device with mobile data built-in was amazing. Now I don't really travel much, but I still totally prefer this setup. I have some more tricks up my sleeve in this regard, the VPS itself is only a host for (my own) docker project manager, which is a management utility for Docker, that manages the life cycle of my development environments (based off https://github.com/jakub-stastny/dev, which already has all my favourite tools), generate new SSH keys, build, create, attach and so on. Being a freelancer, I'd have various projects going on at the same time, so being able to quickly spin off new environments is important, as well as not messing up the host machine. The environments would run SSH server, so I'd connect directly to the docker image, I wouldn't have to go through the host machine at all (I'd run each image on a different port, so they wouldn't conflict).

Jakub Šťastný15:07:39

Anyway I wrote docker project manager originally in Crystal, but I'll convert it to Clojure (as an exercise and also there are things I really have to improve/fix), so once that's done I'll make sure to share it here.

indy15:07:15

That’s quite nice

cp4n15:07:42

This might be a simple question to answer, but if I have a sequence that is just filled with numbers, is there a single function that can aggregate or sum them all up, or are there multiple steps to it?

javi16:07:24

(+ 1 2 3 4 ) when you have a vector you can use apply to ‘spread’ the contents (apply + [ 1 2 3 4])

indy15:07:06

(reduce + your-seq)?

2
cp4n15:07:26

Oh gotcha, I see now. Thanks!

tws16:07:07

also (apply + coll)

2
sova-soars-the-sora19:07:34

I'm looking for more examples of reduce