Clojure from the ground up
aphyr.com
aphyr.com
1. Setup Cursive ( https://cursive-ide.com/ ) 2. Start a REPL on the command line with `lein repl :start :port 38123` and connect to that repl with cursive, a remote REPL. 3. Bind and learn the following structural editing commands:
a) Grow selection (this will be by FAR the most used in the beginning)
b) Slurp.
c) Send top form to REPL.
d) Join lines
Don't ever select by line, only use "grow selection". Don't ever break any parens ("[({") imbalance. Shouldn't happend if you use "grow selection".
Editing like this will get you pretty darn productive. I used it for probably 6-7 months before I introduced more structural editing commands (Next in line is IMO "Move Forward").
CIDER is extremely powerful and has a built in step-through debugger which is a complete joy to use. It also uses nREPL under the hood and Emacs being built for Lisps, the support for sexp editing is first class - use the Smartparens package and as the parent comment said - use slurp forward, backword, raise, kill form etc. Think of it as editing an AST instead of text.
But CIDER is worth it just for the debugging experience.
I believe failing to recommend parinfer to a newbie doesn't make sense in any case, as it binds a very common issue for newcomers (the parentheses management) with something that is very intuitive, indentation with meaning, which in my opinion is part of the huge success of python.
I've also seen at least 4 people in the chats/forums that had errors because of parinfer. So no, I won't recommend it to a beginner.
In my experience, as my IDE (Intellij Idea) highlights lines that are changes for git, these errors are trivially detected. But perhaps for a newbie, this could be confusing? In any case I still think it is a net win.
It should be noted however, that the project was put on hold several years ago, with the intent to eventually tackle: Polymorphism, Modularization and refactoring, object state, JVM interop, Clojure type system, Compiler at runtime, Build your own language, Performance analysis, Parsers and protocols, Storage and persistence, Networks and messaging, and Concurrency and queues.
Consider http://www.braveclojure.com/ as another free and well-written Clojure learning resource, that's more complete.
Error output is just java stacktraces, which for a newcomer make zero sense. I got stuck for two days on something before realising the problem was because of a lazy list elsewhere in the program. The CIDER debugger is pretty good, but I can't help feel that people who sing it's praises haven't been exposed to graphical debuggers like in Visual Studio, which offer a far superior experience. Additionally there is no break on exception functionality, and you have to actually commit a debuggable version of a method before you can step through it. Combined with the nonsensical erro output, you can be looking for hours for the actual location an error occurs. Which is bizzare because functional languages usually make error finding a breeze because mutable state is so locked down.
I'll mention Cursive too, which is an intelliJ plugin, that does actually offer a really good editing experience, and more importantly a modern graphical debugger that makes sense. But it's only a 30 day trial before you need to pay, and because Clojures error messages are still useless I just can't see a reason to pay for something I get for free with any other language. It's a shame because otherwise the Clojure library comes across as really well designed.
Since moving to Racket, I've been a lot more productive because of the out of the box editor it ships with, which along with its built-in package manager, really make it feel like you can hit the road running.
If you are working on personal projects, you are good to go.
For me its a huge advantage, massive ecosystem of existing libraries to fill any gaps in the clojure ecosystem and an extremely fast garbage collector + JIT.
Stack traces are annoying though, but fixing those is waayyyy easier than replicating the JVMs advantages.
Fast, bulletproof GC is beyond essential when using persistent data structures.