We already have them! I actually think Clojure has really good editor support now. CIDER has much better Clojure support than most language modes in Emacs, proto-REPL is really nice for Atom and Cursive is good for IntelliJ. It’s hard to compare Cursive to JetBrains’ language support plugins since they have so many more resources and it takes so long to figure out IntelliJ plugin development, but Cursive is more polished than most other third-party language plugins.
I think the main thing that will always help is a larger community - that just leads to more OSS contributors, more money from companies for tooling, etc. One thing I would like to see is more people contributing to existing tooling projects rather than starting new ones - it’s always fun to build your own thing and working with large existing projects can be messy and, well, not fun. But in a lot of cases we’d be better off with improvements to what we have rather than new things, since what we have is what people are already using even if it’s not perfect.
As all strict necessities have been integrated into Cursive, I was wondering what Major Items you are working on. Any possibility we can get a glimpse of what’s coming?
Is it useful to allow IntelliJ to send crash reports to you, or do you not actively inspect those from time to time? (I probably hit that Send button about 20 times per week - mostly to get rid of the annoying flashing red icon.)
I’ll answer both of these together - initially Cursive started life as a fork of La Clojure, which was a Clojure IntelliJ plugin made by some JetBrains devs in their 20% time but was mostly abandoned at the time. My previous job was pretty stressful, and I’d decided to take some time off when that job finished for a sabbatical and work on something interesting for a while. I was interested in playing around with Clojure but I wasn’t keen to pick up Emacs again, I’d used it for years a long time ago when I worked with C++. So I started working on La Clojure and migrating a bunch of it to Clojure (it was all in Java) and I’d built up a pretty sizeable fork. I was about to submit it back when I started wondering if there might be a product in it. I really didn’t do a lot of market research, I just asked on the mailing list if anyone would pay for a professionally supported editor and a few people said yes - after that it was mostly just hoping for the best.
Yes, actually I’ve been working on these again recently - I got as far as a PoC for the conj talk but never took it any further. But I’ve recently rewritten the macro parser to use regexps rather than PEGs to make it more similar to spec - that work isn’t in Cursive yet but I hope to get it in there soon. The parser is now very fast and has some features that I need like returning a partial parse (like a partial conform in spec, with all the data that could be captured as well as errors where they were found) which will enable a lot of nice functionality like context-sensitive completion as well as better macro syntax errors in the editor.
I think I’d do it mostly the same. There are a lot of details about how I integrate into IntelliJ that I’d change and a few problematic early architectural decisions that are still painful, but the fundamental model of using static analysis rather than REPL introspection I still like a lot. It has tradeoffs like everything but I’m happy with how that part has worked out.
Sure - there’s still lots to do (in no particular order):
Better support for third-party macros - most of the low-hanging fruit is done here, so that means exposing the grammar parsing and extension points. This is a big project but is the last big thing that is very difficult for users to work around if they’re working on projects that need it. Libs like clara rules are currently painful to work with.
As mentioned, lots of CLJS improvements - support for the new node modules integration, better REPL support with macroexpansion, test integration etc. CLJS debugger, Lumo/Planck support etc.
Better support for spec, things like a data validator, a graphical error explainer etc.
A bunch of improvements I have planned to the Clojure debugger.
It’s not so useful to existing users, but I need to work on my doc and have better infrastructure around maintaining it. Currently updating screenshots and especially animations is a pain.
A better test runner for project-wide tests, and various improvements to how the test integration works.
I’m working on some changes which will make the REPL UI much better, and hopefully allow things like requesting a graphical diff of data structures from the REPL and have it open in the GUI. I’m also planning to experiment with things like the REPL results being interactive tree views rather than just text, and also painting REPL results in the editor - something like what proto-REPL allows, although I’m somewhat limited by what IntelliJ allows.
I’m working on Parinfer v3 support with smart mode, there are still some outstanding bugs in parinfer itself but the integration is basically done.
Support for socket REPLs, and different REPL types in general.
Better refactoring and ns form manipulation support, in particular things like move ns, move function, extract function and so forth.
edit: a lot of performance work, in particular moving everything to be eager using transducers when indexing etc.
edit: The standalone IDE and learning newbie mode mentioned above.
More I’m probably forgetting right now.
And finally, a feature voting system in the IDE to allow me to prioritise all this better, backed by Github issues. I’m going to separate it into new feature requests, and papercuts, i.e. small bug fixes which increase quality of life.
Yes, this is definitely useful. Cursive has a lot of users now so I can’t keep up with all the individual errors (and Rollbar’s UI isn’t very helpful at finding what I need to know), but the aggregates are very useful. In particular I try to fix the bugs that I see reported many times - I tend to check those after each release to see if I’ve introduced any new problems.
Ok folks, it’s way past my bedtime here. I’ll be back in the morning, I’ll answer any questions that have come in overnight and generally be around again then. Thanks for all the great questions!
Sure. In my most recent conj talk which I linked above, I spoke about how Cursive moved to parsing forms using a grammar. Clojure didn’t provide anything like that at the time, but now spec provides something similar if you write specs for your macro forms (you can see the specs for some of the core forms here). If macro library developers start writing similar specs for their macro forms, I should be able to use those to more easily produce the grammars that I need. I haven’t actually done this with any specs yet, but as I mentioned above I recently re-wrote my macro parser so that its semantics more closely match spec’s to make this easier. Cursive won’t use spec itself, but the translation should be easier and having an unambiguous grammar in any form is always very helpful.
As a more concrete example, a library that a lot of my users are struggling with is Clara rules. It essentially provides a sophisticated DSL embedded into Clojure. Unusually, they actually provide part of the grammar of their forms in their documentation (see here), but it’s incomplete and all the actual form parsing is done by hand in the code. I’ve been planning for a while (but got sidetracked) to help them write specs for the Clara macros, which will help users of Clara validate their forms and will also then help me add support for it to Cursive.
Omg I’m the author of Precept which is built on Clara rules. We use Clara’s syntax heavily with some inspired by Datomic .
I think it’d be kind of a game changer for Cursive to be able to recognize a DSL though I’m not a student of prior efforts to have an IDE “understand” a language that’s defined in it.
How can I help? I’m at @a_dixon on Twitter or Clojurians if you’d prefer to chat there.
Do you think we Cursive will be able to use specs to provide some of the benefits usually associated with statically typed language IDEs. (aka is spec useful enough in static analysis to pretend it’s static)
I’m shooting from the hip but broadly things like:
Function called with args of wrong type
Right-click “generate spec for defn”
There’s a code path which won’t return the expected type
First: a disclaimer - I’m only an interested observer of spec so far, I haven’t actually used it in anger yet.
The technical answer to this is “no”. This is because spec encourages the use of general predicates, which means that in general you can’t use it for static analysis because of the halting problem. It’s also problematic when trying to use macro specs for other uses like importing them for use in Cursive as I discussed above - that will require user guidance when you can’t figure out what to do automatically.
However the pragmatic answer is that you can probably fake it sometimes, with results that will probably be somewhere between “quite useful” and “better than nothing”. As long as it will fail gracefully when you really can’t do anything, something like this could still be a useful tool. The best project to check out for this is Allen Rohner’s Spectrum - I’ve been planning to look at it more closely but haven’t yet.
Specific comments:
Function called with args of wrong type - this is definitely feasible in simple cases, which would still be very useful. I often screw up the order of instance? tests, and this would catch that. It would probably also catch goofs like using -> instead of ->> for collection threading, or newbies getting the order of args wrong there. More sophisticated examples will really depend on the context of the code.
Right-click “generate spec for defn” - this is probably a pipe dream except in very simple cases.
There’s a code path which won’t return the expected type - this one is probably more feasible in obvious cases.
(mumbles) this destructuring looks wrong - things like destructuring syntax would be caught by the macro validation. More sophisticated checks like “you’re destructuring something that needs to look like x, but actually looks like y” - again, maybe, sometimes.
code completion based on s/keys etc - this is probably quite feasible, yes.
Thanks for your great Cursive make a painless development setup for Clojure!
The first question is it possible to have type info when call/write Java/Clojure function? we know that Clojure have quite rich type info behind the scene, But don’t know if it is rich enough to provide some helpful message?
The second question is it possible to have argument name shown when we are reading code like what android studio did