I’m Colin Fleming, I develop Cursive, an IDE for Clojure code. You might remember me from such Clojure conference talks as this one (introducing Cursive), this one about debugging Clojure with Cursive, or this one about parsing macros with grammars, similar to spec. I’m interested in dev tooling of all kinds, and generally improving the Clojure user experience. I also like and use Kotlin, which is a nice contrast to Clojure for some tasks.
I’m in New Zealand, so I’ll be around for a couple of hours answering questions and then off to bed, and I’ll pick up and answer any more questions in the morning my time (which is afternoon/evening US time).
No, I don’t think so, I still really enjoy writing Clojure code. I’d say it’s made me more aware of when I reach for one or the other - as much as I like Clojure, it’s not perfect for everything. If I’m working on some interop-heavy code Kotlin is generally nicer for that, and the null-safety is something that I really miss when I’m working in Clojure. I wrote a bit on Reddit recently about the main reason I use Kotlin/Java in Cursive, which is startup time - I don’t see that getting any better in Clojure any time soon.
But if I’m working with code that manipulates a lot of data Clojure is generally much easier to work with. And I really miss a REPL when working with Kotlin, so I generally use Clojure for exploratory fiddling around.
I think so (and hope so!) - there’s so much community investment around nREPL that it’s been sad to see it languishing. Chas seems keen to reinvigorate it and there have been a couple of people investigating things like a native CLJS implementation. It’s a somewhat difficult situation that there are two camps, people who believe that streaming REPLs are superior and those who like nREPL :-). I’ve found an RPC model easier to develop tooling over than pure streaming, but it’s not without its limitations too, especially around user input. Like most things, it’s a tradeoff - the problem is that it’s difficult for tools developers to write functionality supporting both (as I’m sure you’re aware!)
I’ve been (very pleasantly) surprised how well Cursive has been selling, before I started I really had no idea how many people would be interested in paying for tooling. Clojure is still a niche market - Cursive pays me a great salary, but it doesn’t pay me two great salaries so growing a team would be difficult even if I wanted to. By contrast, I think JetBrains have about 15 people working on PyCharm and they have multiple hundreds of thousands of users - it’s a totally different ball game.
In terms of growth, sales are pretty spiky so it’s difficult to tell. Currently my sales for the last year are slightly down on the previous year (I don’t maintain great stats so I’m just eyeballing numbers from my payments provider), about 5%. But it doesn’t take many sales to make that up, and when I first started selling Cursive there was a large spike as everyone in the beta program paid for it, so I’m not worried about it. I’d say it’s about stable over time. It’s an interesting figure as a proxy for Clojure community size - sales are generally the derivative of community growth, so perhaps the community is growing linearly? I’m not really sure though, since I don’t give back money when people stop using Clojure.
But the important thing for me is that Cursive is definitely sustainable financially for me at the moment, and it’s a really fun thing to work on.
In general, my main obstacle is just time - developing plugins for IntelliJ is a lot of work, and I do a lot of support work which leads to a ton of yak shaving. I’ve been planning better CLJS REPLs forever and it just always seems to be the next thing I’m planning to work on.
Two things that immediately spring to mind as hard to implement are better macro support, and boot support. The macro support is hard because it’s basically going to be an API to the Cursive internals, which will require documentation, support and so on. I also have a couple of fairly bad fundamental decisions which I made right at the start which are still blocking that. That’s an ongoing project which I’ll get done one day.
Boot support is hard because boot is so dynamic. Cursive (or IntelliJ, really) needs a bunch of static information about a project in order to index it correctly - which libs are dependencies, where are the source folders and so on. Lein is at least somewhat declarative so I can get that information out even though it’s surprisingly tricky at times, but it’s really hard with boot because that information can be calculated by any arbitrary code. I have a plan to do this with a mix of static analysis and just invoking custom boot tasks to get that information, but it’s a very hard problem. It’s one thing that gradle did really well - gradle is extremely flexible but it was designed with IDE support in mind so it supports that much better than boot.
This is difficult, unfortunately. IntelliJ has its own AST classes that my AST elements have to derive from, so code working with standard Clojure datastructures or e.g. the tools.analyzer AST format doesn’t work in Cursive, and the Cursive code doesn’t work with them well either. So I have my own Clojure reader, essentially (it’s a classical lexer + parser, not much like the actual Clojure reader). Most of the JetBrains IntelliJ plugins end up having to do the same, more or less reimplementing the semantics of the language which is a huge amount of work in some cases (e.g. Scala or Rust).
This is something that I’ve been thinking about for a long time, yes. However the benefit is currently pretty small - Cursive is pretty easy to get started with these days, you don’t even need to download a JVM (IntelliJ comes with one bundled which you can use) or lein.
Developing this is a lot of work because there’s a lot of black magic in the build process to do so, and it’s currently totally undocumented by JetBrains. I’m hoping to work with them at some point with the promise of documenting the process for them, I’m sure they’ll be keen to collaborate on that. I’m also a little worried about cross-platform support, which is currently an almost total non-issue for me - JetBrains have done a really great job of making IntelliJ work everywhere.
That said, there are a couple of use cases that this would be great for that I’d love to support better - things like ClojureBridge and also use in academic environments. As part of making a single downloadable build, I’d also like to modify the startup process to offer the possibility to simplify things, i.e. hide a lot of menus and UI by default, and have a simple UI similar to DrRacket so it’s not so intimidating for completely new users. But again, that’s probably quite a lot of work.
In no particular order: ease of use (i.e. just be able to click a button and get a CLJS REPL configured and running with figwheel and so on), the various niceties around the REPL which the Clojure support has such as macroexpansion, and things like better output formatting and highlighting. I’d also like a CLJS REPL to have a CLJ view and a CLJS view and intelligent switching between them - CIDER already has things like this but it’s currently very clunky in Cursive.
I’m also planning better support both in the editor and the REPLs for self-hosted CLJS environments like Lumo and Planck, so you’ll be able to just add a Lumo module to your project, tell Cursive where your Lumo is installed and spin up a REPL.