Apologies in advance for the somewhat discursive nature of this clump of related questions; I hope the answers will be a useful resource for newcomers to Clojure.
I have just begun to learn Clojure, motivated in part by this essay. I'm not a professional developer but I have several decades of programming experience (ARexx, VB/VBScript/VBA, then Perl and daily use of R starting in 2011). My platform is Windows 7 64-bit. I'm using Emacs 24.3, cider 20131221 and Leiningen 2.3.3 on Java 1.7.0_45 Java Hotspot 64-bit server. I have bought Clojure Programming and the Clojure Data Analysis Cookbook and dipped into both. I have found them promising but I am getting lost in the detail.
Obviously the thing to do is to get stuck in and experiment with code exercises and small tasks, but the immediate problem for me has been the complexity of structuring, organising and even just plain running projects in Clojure. With R I can get away with a file of plain text containing the bulk of the code, perhaps with one or two others containing common functions for larger projects.
Clojure is very different and with no experience in Java I am struggling to put the pieces together. Clojure Programming has a whole chapter on organising and building projects, but it is so comprehensive that conversely I'm finding it difficult to tease out the information relevant to me now. I guess I'm looking for something like this answer on Swank, but the tools seem to have moved on since then. So here goes.
- Leiningen produces amongst other things a
project.clj
file that contains the project definition and dependencies. I think I get this. Can I use this file for code not related to the definition, below thedefproject
, or is it best to leave this untouched and have the code itself in differentclj
file(s)? - If the answer is to leave the
project.clj
file alone, how is the relationship between that and other files established? Is it simply that all theclj
files in the project folder are counted part of the project? - How do I define the main code file, the 'entry point' of the project? Let's say I have
project.clj
andmain.clj
with some helper functions incommon.clj
- how are the relations between these three files defined? I can call functions frommain.clj
but how does the project know that main is the core of the project if/when I package the project into an uberjar? - If I have a number of
clj
files, what is the best way to import functions? I have read aboutrequire
anduse
(andimport
andrefer
and...) but I don't fully understand the difference and those two keywords are difficult to search for. The examples for REPL in the Clojure Data Analysis Cookbook most often opt foruse
. I found a similar question but it was a little over my head. - This is more tool-specific, but as Emacs seems to be widely used it seems fair to ask: what's a good workflow to run small bits of code given (say) the
main.clj
example given above? Currently I just open themain.clj
file in Emacs, do anM-x cider-jack-in
to establish the REPL, experiment in the REPL, then when I want to try something I select the whole buffer and selectEval region
from the CIDER menu (C-c C-R
). Is this standard operating procedure or utterly misguided? - Is there a convention for defining namespaces? I think I understand that namespaces can cover multiple
clj
files and thatns
is used to define the namespace. Should I explicitly define the namespace (at the beginning of) every file of code? Clojure Programming has some recommendations but I'm interested in input from other users. - Clojure programming says to "Use underscores in filenames when namespaces contain dashes. Very simply, if your namespace is to be
com.my-project.foo
, the source code for that namespace should be in a file located atcom/my_project/foo.clj
". (EDIT as explained in this useful answer and also this one). This restriction would never have occured to me. Are there any other gotchas with regard to naming namespaces and variables? R frequently uses dots in variable names but I guess given the Java connection that dots should generally be avoided?
example-variable
. Also, dynamic vars should be named like this:*dynamic-var*
. – desudesudesu