Clojure: Lein run unable to resolve symbol

read-file should be before main in your source OR you should put before -main a declare cause like that:

(declare read-file)

You have used only slurp from clojure core, meaning that every other core function is now unavailable to you :) Try changing your ns to use :require instead of :use, as this is more idiomatic.

One thing to note is that order does matter in clojure, so if you don't declare a function at the top of your file, as in C and some other languages, the earlier functions will not be able to make reference to them. This is what was causing your error before and is why I like to define my -main function at the bottom. It's a matter of style.

Another thing is that your -main function is taking variable args right now and not using them. In Clojure it is idiomatic to use _ to refer to a parameter that doesn't get used. You could use & _ to avoid error messages, for when the user passes in unnecessary args, but I would just have the -main function parameterless from the start. This is because nothing needs to be provided to main when you run the program, and errors do make debugging easier. It is good to know what is getting used and where. The sample.csv file is already provided and is having read-file called on it, so the program should run if your read-file function is correct and the sample.csv file is in the proper location.

Regarding your -main function, it would be nice to put a little test in there to see if it executes properly when you run it, so I changed it to print out the contents of the csv file onto your console. This way of printing from a file is efficient and worth studying in its own right.

Finally, Make sure you include clojure-csv.core in your project.clj file.

core.clj:

(ns fileops.core
  (:require
    [clojure-csv.core :refer [parse-csv]]))

(defn read-file
  "open and read the csv file"
  [fname]
  (with-open [file (clojure.java.io/reader fname)]
    (parse-csv (slurp fname)))) 

 (defn -main []
        (println (clojure.string/join "\n" (read-file "resources/test.csv"))))

project.clj:

...

:dependencies [[org.clojure/clojure "1.5.1"]
               [clojure-csv/clojure-csv "2.0.1"]
                ...]
:main fileops.core

You need to declare fileops.core as :main, as shown above. This tells Leiningen what function to execute when you enter lein run. Very important and tricky stuff.

So now make sure you are in the root of your project directory and at the terminal, run the following:

lein clean
lein deps 
lein run 

Good luck!

Further reading:

8th light blog on name-spaces

flying machine studios explanation of lein run

Tags:

Clojure