REPL driven programming in Clojure

I would like to learn to use the clojure repl for more than just entering code but I am unable to load an exercism lab at either the command line or in an nrepl. I think that is because exercism labs don’t have a main function so clj -M for example won’t work. If that is correct is there a general way to add a main function to exercises? I know this is a noob question but google has failed me.

The common way to use the repl is with an editor integration.

For some reason, the misconception that Clojure devs are typing things into the repl all the time keeps getting proliferated. Whenever people say that, what they really mean is to paste it into your editor and send the code to the running repl by using a key binding.

Which editor do you use?

VSCode: Clojure Interactive Programming for Visual Studio Code - Calva User Guide

Emacs: CIDER :: CIDER Docs

IntelliJ: Cursive: The IDE for beautiful Clojure(Script) code (cursive-ide.com)

vim: Conjure - Interactive evaluation for Neovim

Here is a more complete list, from the official docs: Clojure - Editors

To answer your question, a main function is written like this:

(ns test)

(defn -main
  [& opts]
  (println "Hello, World!"))

Which is invoked from the command line like this:

$ clj -X test/-main
Hello, World!

Thanks, this makes sense but I can’t seem to integrate it with longer bits of code. I’ve tried main as it’s own function at the top or else wrapping everything like so but get Namespace could not be loaded: tracks-on-tracks-on-tracks both ways:

(ns tracks-on-tracks-on-tracks)

(defn -main [& opts]

(defn new-list [] (list))

(defn add-language [lang-list lang] (cons lang lang-list))

(defn first-language [lang-list] (first lang-list))

(defn remove-language [lang-list] (rest lang-list))

(defn count-languages [lang-list] (count lang-list))

(defn learning-list []
(-> (new-list)
(add-language “Clojure”)
(add-language “Lisp”)
(remove-language)
(add-language “Java”)
(add-language “JavaScript”)
(count-languages)))
)

$ clj -X tracks-on-tracks-on-tracks/-main

The way you would do that would be to put -main on the bottom and have it call learning-list:

(ns tracks-on-tracks-on-tracks)

(defn new-list [] (list))

(defn add-language [lang-list lang] (cons lang lang-list))

(defn first-language [lang-list] (first lang-list))

(defn remove-language [lang-list] (rest lang-list))

(defn count-languages [lang-list] (count lang-list))

(defn learning-list []
(-> (new-list)
(add-language “Clojure”)
(add-language “Lisp”)
(remove-language)
(add-language “Java”)
(add-language “JavaScript”)
(count-languages)))

(defn -main [& opts]
  (println (learning-list)))

But the namespace error sounds strange. Is the file located in the src directory?

1 Like

I just tested it on my machine in a fresh downloaded exercise. But I had to replace the quotes with regular quotes because the code you posted has “smart” quotes.

This works thank you! Clojure’s main is not what I thought. I was comparing it to the only other main I’ve seen which was in C a million years ago lol. I will have to get used to this.

And sorry about the quotes, I will try formatting code in Markdown next time :slightly_smiling_face:

2 Likes