Tag Archives: emacs

Tooling for Clojure and ClojureScript

[:ChangeLog
(:v0.2
“recognise that ‘resolving dependencies’ and ‘build’ are different operations.”
“Add conversion tools between project.clj & deps.edn”)
(:v0.3
“Remove CLI tools described as a build tool comment.”)]

WARNING
I still have much to learn about ClojureScript tooling but I thought I’d share what (I think) I’ve learned, as I have found it difficult to locate advice for beginners that is still current. This is very incomplete. It may stay that way or I may update it into a living document. I don’t actually have much advice to give and it’s only about the paths that have interested me.

Clojure development requires:

  • a text editor,

and optionally,

  • a REPL, for a dynamic coding environment
  • dependency and build tool(s).

The absolute minimum Clojure environment is a Java .jar file, containing the clojure.main/main entry point, which can be called with the name of your file.clj as a parameter, to read and run your code. I don’t think anyone does that, after they’ve run it once to check it flies.

Based on 2 books, ‘Clojure for the Brave & True’ and ‘Living Clojure’, my chosen tools are emacs for editing, with CIDER connecting a REPL, and Leiningen as dependency & build tool. ‘lein repl’ can also start a REPL.
Boot is available as an alternative to Leiningen but I got the impression it might be a bit too ‘exciting’ for a Clojure noob like me, so I haven’t used it yet.
CIDER provides a client-server link between an editor (I’m learning emacs) and a REPL.

If you use Leiningen, it comes with a free set of assumptions about development directory structure and the expectation that you will create a file, project.cli in the root directory of each ‘project’, containing a :dependencies vector. Then magic happens. If your change the dependencies of your project, the config fairies work out everything else that needs changing.

Next, I wanted to start using ClojureScript (CLJS.) I assumed that the same set of tools would extend. I was wrong to assume.
Unfortunately, CLJS tooling is less standardised and doesn’t seem to have reached such a stable state.

In ‘Living Clojure’, Carin Meier suggests using cljsbuild. It uses the lein-cljsbuild plugin and the command:

lein cljsbuild auto

to start a process which automatically re-compiles whenever a change is saved to the cljs source file. If the generated JavaScript is open in a browser, then the change will be shown in the browser window. This is enough to get you going. It is my current state.

I’ve read that there are other tools such as Figwheel, now transitioning to ‘Figwheel Main’ which hot-load the transcribed code into the browser as you change it.
There is a lein-figwheel as well as a lein-cljsbuild, which at least sounds like a drop-in replacement. I suspect it isn’t that simple.

There are several REPLs, though there seems to be some standardisation around nrepl.
It was part of the Clojure project but now has its own nrepl/nrepl repository on Github. It is used by Clojure, ‘lein repl’ and by CIDER.

There is something called Piggieback which adds CLJS support to NREPL. There is a CIDER Piggieback and an NREPL Piggieback. I have NO IDEA! (yet.)
shadow-cljs exists. Sorry, that’s all I have there too.

At this point in my confusion, a dependency issue killed my tool-chain.
I think one of the config fairies was off sick that day. The fix was a re-install of an emacs module. This forced me to explore possible reasons. I discovered the Clojure ‘Getting Started’ page had changed (or I’d never read it.)
https://clojure.org/guides/getting_started

There are also (now?) ‘Deps and the CLI Tools’ https://clojure.org/guides/deps_and_cli and https://clojure.org/reference/deps_and_cli

I think these are new and I believe they are intended to be the beginners’ entry point into Clojure development, before you dive into the more complex tools. There are CLI commands: ‘clojure’ and a wrapper that provides line-editing, ‘clj’
and a file called ‘deps.edn’ which specifies the dependencies, much as ‘projects.clj’ :depencies vector does for Leiningen but with a different syntax.

I’m less clear if these are also intended as new tools for experts, to be used by ‘higher order’ tools like Leiningen and Figwheel, or whether they will be adopted by those tools.

[ On the day I wrote this, I had a tip from didibus on clojureverse.org that there are plugins for Leiningen and Boot to use an existing deps.edn,

so perhaps this is the coming future standard for specifying & resolving dependencies, while lein and boot continue to provide additional build capabilities. deps.edn refers to Maven. I discovered elsewhere that Maven references existed but were hidden away inside Leiningen. It looks like I need to learn a little about Apache Maven. I didn’t come to Closure via Java but I can see the advantages to Java practitioners of using their standard build tool. I may need to drop down into Java one day, so I guess I may as well learn about Java-land now.

Also via: https://clojureverse.org/t/has-anyone-written-a-tool-to-spit-out-a-deps-edn-from-a-project-clj/2086, there is a https://github.com/hagmonk/depify, which ‘goes the other way’, trying it’s best to convert a project.clj to a deps.edn. Hopefully that would be a ‘one-off’? ]

I chose the Clojure language for its simplicity. The tooling journey has been longer than I expected, so I hope this information cuts some corners for you.

[ Please let me know if I’m wrong about any of this or if there are better, current documents that I should read. ]

Advertisement

Lispbian Pi. A Lambda Delta.

I’m conflicted. Part of me says that ‘us old timers’ shouldn’t assume ‘the way things were when we were kids’ were better but we know the Raspberry Pi was an attempt to recapture the spirit of the BBC Micro Model B and that seems to have gone quite well. I got a Pi 2 and I’ve worked out that it is more powerful than the first computer I worked on, a DEC VAX-11/780 which supported about 16 terminals, most used for teaching college level computing. Having that machine to myself would have been an unimaginable amount of processing power for one developer. Banks ran their financial modelling software on boxes like that. So why does the Pi feel so slow? We wasted our gains on GUI fluff.

When I started computing you learned just enough of the command language to get going. So, that’s bash on a pi. Then an editor. For reasons that should become obvious, let us choose emacs. When I first used the VAX/VMS operating system, it didn’t have command line editing. If you made an error, you typed it all again. Getting the facility to press up-arrow, edit the command and re-execute it was a big advance. We should keep it. Bash has that, using a sub-set of the emacs keys, so that’s a way into emacs.

The next big improvements I remember were X windowing and symbolic debugging. We got debugging first but it became far more powerful with multiple terminal windows. The GUI was OK, I guess but DEC didn’t give us many free toys so the main advantage to a developer was having lots of terminal windows. emacs can do that, without the overhead of X.

When I decided to re-learn coding a while back, I got my shortlist of languages down to Python, Java and JavaScript but picked Python because I was already learning a new language and the Object paradigm, so I didn’t want to have to learn web at the same time. I heard about the modern Lisp dialect Clojure and changed horses mid-stream. I’m convinced by the argument that functions and immutability can save the universe from the parallel dimension.

Last night I deep-dived into emacs and found myself in an editor session with 4 windows. Why do I need more than that to learn about computation and data transformation? This guy seems to have come to a similar conclusion http://hackaday.com/2015/09/23/old-lisp-languaged-used-for-new-raspberry-pi-os/ I’ve also wondered whether a purely functional OS might make Sun’s ‘the network is the computer’ dream a little easier. emacs is written in Lisp.

I think a dedicated Lisp machine may be a step too far back. How would you browse in the world-wide hypertext library when you got stuck? But a Linux with bash, emacs, the Java Virtual Machine and libraries, Clojure via Leiningen and Cider to plug everything together might make a fine Lispbian Pi! Is all this chrome and leather trim completely necessary in the engine compartment?

It is unfortunate that the Raspbian upgrade left Leiningen broken.

Learning to grok Lispen

This is not my late entrance into the Unix editor flame wars. I’ve always disliked vi and emacs about equally. I’m sure that both are amazing if you have a memory and use them every day. I don’t. I am, however, interested in computational models. The Unix ‘small pieces loosely joined’ philosophy had always leaned me towards vi. I knew emacs had ‘Lisp inside’ but I didn’t care. I had a bad experience with Lisp at university, but what really put me off was that emacs isn’t just an editor; it’s an environment. It duplicates things that happened elsewhere in Unix. You go in there and you don’t come out until home time. In the Winter, you don’t see light. It is neither small nor loose and I didn’t understand why. Was it the first IDE?

Richard M. Stallman hacked on emacs at MIT’s famous AI Lab. The Lab and its culture were torn apart by a war over intellectual property  of the family Lisp machines. It was a difficult breakup and RMS was abandoned by both halves of his family. In reaction to creeping commercialisation he started the GNU project which later enabled GNU/Linux &c.

I’ve realised only recently how incredibly unimportant Unix was to RMS. He simply wanted somewhere to run a Lisp environment that couldn’t be taken away from him, or others who subscribed to the original MIT AI hippy culture and ethics of free sharing of code and information. He ported a ‘C’ compiler to port emacs and started a movement to maintain everything else he needed.

The latest trend in current computing is ‘platforms’. We have gone back to worrying about the ancient concern of application portability. We’ve divided into language tribes: Java, JavaScript, Ruby, Python, .Net, Apple, Google – each with their own library system, to free us from the tyranny of operating systems, designed to free us from hardware. RMS did that in the 70s/80s.

I fought against the idea of Clojure (a Lisp dialect) running on the Java VM rather than a real OS. Another version runs on .Net and one is being ported to JavaScript. I get it now. People want to get stuff done and to do that, they need the support of a tribe (or two.)

MIT’s free educational videos contributed to my understanding of these issues. They used Scheme (another Lisp) before moving to Python to get access to more libraries. Perhaps they should move back to Clojure.