cursive

Issues at: https://git.io/cursive-issues
scarytom 2020-11-11T12:20:11.210500Z

@cfleming getting this strange behaviour, and wondered if I'm missing something obvious

cfleming 2020-11-13T20:28:00.235500Z

Not that I’m aware of, I’ll try to reproduce it. Is this CLJ, CLJS or CLJC?

scarytom 2020-11-14T23:08:44.235700Z

just plain old clj

2020-11-16T09:25:16.244400Z

I can reproduce it.

2020-11-16T09:25:30.244600Z

same code, same error message

2020-11-16T09:26:51.244800Z

it seems to be require specific - other functions (e.g. println, count) don't cause the error

scarytom 2020-11-18T23:15:26.246600Z

@cfleming did you try this out yet? The issue isn't really affecting me massively, but I am curious about it.

cfleming 2020-11-19T09:00:02.247300Z

@t.denley No, I’ve been off work for a couple of days but I’ll look at this when I’m back.

scarytom 2020-11-19T09:29:04.247500Z

No worries, thanks.

cfleming 2020-11-20T06:07:29.253800Z

@t.denley So this is just a common or garden variety bug, although it’s a tricky one. require was one of the first forms I added support for (along with all the other ns-related stuff), and since the ns form is so complicated I cribbed a bunch of code for parsing it from tools.namespace, including this: https://github.com/clojure/tools.namespace/blob/master/src/main/clojure/clojure/tools/namespace/parse.cljc#L63-L70

cfleming 2020-11-20T06:09:07.254100Z

Much of this code never got retrofitted to use my grammar parsing stuff which would have caught this. So this is still using old parsing code, which tries to parse the forms passed to require as a libspec and decides (due to that check) that it’s a prefix form.

cfleming 2020-11-20T06:12:00.254300Z

So when a form is a prefix form, the initial symbols will sometimes but not always refer to namespaces. If you have (require '(clojure string (java io))) for example, there’s actually no namespace called clojure anywhere, so Cursive marks that symbol as something that shouldn’t be resolved, since in an actual prefix forms that’s often valid. Obviously, no namespace called -> exists 🙂

cfleming 2020-11-20T06:13:57.254500Z

Then, since that symbol is marked as not resolving to anything, when Cursive is trying to figure out the arity that’s being used for string/split it looks at the parent list to see if it’s a threading form. But the head symbol doesn’t resolve to anything, so it can’t be, which is why Cursive thinks it’s not in a threading form when it actually is.

cfleming 2020-11-20T06:14:51.254700Z

The moral of the story is, as I have been preaching but obviously not entirely practising, is to always use grammars to parse your forms rather than ad-hoc parsing like this.

cfleming 2020-11-20T06:17:14.254900Z

(even when that ad-hoc parsing comes from something battle-tested like tools.namespace)

scarytom 2020-11-20T09:13:42.255100Z

Wow, that's quite a journey. Thanks very much for the explanation, it's very interesting, and I've learnt a lot from it.