I've been using Clojure for a little while and want to create some projects that are bigger and more complicated than toys. I've been using Java for the past few years and have become accustomed to what IDEs do for me -- compile lots of classes, package them up in jars, create batch files for users to start them with.
When I look at examples of development in Clojure they seem to be along the lines of load files into the REPL, see how they work, edit the file, reload, repeat. Nary a class or jar being generated anywhere. In Stuart Halloway's terrific "Programming Clojure" I couldn't find a single example of ":gen-class", for example. The Clojure IDEs that I have used (ClojureBox and the enclojure NetBeans plugin) seem to promote that same work flow.
Is this intentional? Are the tools too immature or do I just not "get it"?
I'd like to hear some work flow examples from folks who have created some non-trivial programs to be used by regular users (not other devs) if possible.
Thanks for sharing your opinions.
I think there are really 2 questions here:
A) how to deploy (and build and manage dependencies). All I can say to that is look at other projects with similar goals/domains and copy them.
B) Workflow:
My work-flow is like this:
open a file and write some high level wishful thinking declarations
start writing some functions to support it
2.5 copy the function definitions to REPL as I create them
- open another file and write some basic tests to check the function works
3.5 copy these to the REPL
iterate between the two buffers building the tests up to an example and the program toward an end goal. These eventually become similar activities and I know I’m done.
wrap the secondary file up in deftest
Now when I come back in a month, I can just run my tests and be happy! Saving your REPL buffers can provide some value with little effort. That’s just what works for me at present, and I’m happy to be educated to better approaches.
As for selection of IDE vs REPL - most IDEs have plugins which have REPLs so I'm not sure its a one or the other choice - really its just about which text editor you are productive in, and how you want to manage your project structure. There aren't any 'do it this way' structures pre-made AFAIK so at this point it is easier to look at specific projects (like Clojure itself, or penumbra or compojure or any of the libraries listed on the main site.
The REPL development approach has been encouraged by most LISP family (and other functional language) IDE's for a long time. Some of these REPL's also feature the auto-complete features you might associate with a Java IDE.
REPL gives you a couple major advantages over the standard approach. The first is that it allows you to execute arbitrary code during the run-time of your program, which can make debugging multi-threaded systems much simpler. Second, and more importantly, it makes it easy to test your functions while you code. You don't need to build a framework around a new function or class, you can play with it directly in the REPL, and see how it responds to a variety of use cases.
Well, to start off, virtually any decent development plugin for any editor or IDE will give you a way to use the Clojure REPL from within the IDE. Probably even allow you to load files into the REPL for testing and such. You don't need to choose one or the other.
Enclojure is going a long way, that is for sure. However, most people are perfectly happy with using Emacs, including myself. Emacs uses a Lisp as its configuration language, so it's usually the most natural choice to a Lisper.
For languages that have REPLs, using the REPL as a major part of the development process is the norm. Editing files, loading them into the REPL, playing with them to see if a work, rinse, repeat. This is one of the major advantages of languages with REPLs like Clojure and Haskell and CL and such.
As for building jars, and compiling Clojure code and stuff, that's simple. You don't even really /have/ to Compile Clojure code most of the time if you don't want to. When you do, you AOT compile it with gen-class, which compiles it to class files that you can then put into a jar. There are tons of examples and even tutorials spread amongst the interwebs. The easiest and most efficient way is to use something like Ant and writing a build script that compiles Clojure code and generates the .jar for you. The first time I did it, I thought it was going to be hard to do, but it was actually really simple. I just looked at the Clojure and Clojure-Contrib Ant build files, and referenced the Ant help pages for everything else I needed.
One thing I should mention is the fact that Enclojure /does/ actually build executable .jar files for you, if you request it to do so. I'm sure more advanced things you're used to will be added in the future. They are, indeed, still quite new.
I use both - Eclipse IDE and Counterclockwise plugin which provides a REPL. This is a particularly nice combination if you develop Java code alongside Clojure (as I do).
My general approach is:
- Write Clojure code in the editor
- Keep a REPL open for testing things out (Ctrl+Enter is a useful shortcut here: it executes whatever code is selected in your editor in the REPL)
- Use the generic IDE tools for project management, building, testing, SCM etc.
At times , I also work purely in the REPL. This is usually better for testing things out quickly. If I particularly like a piece of test code, I will simply copy/paste it from the REPL into my test suite.
What I do is to create a project with Leiningen. If you just want to whack away for a while, you can just type lein repl and your project classpath will be set up for that repl.
Actually though, I use Emacs, slime and swank clojure. After navigating to the project, you simply type M-x clojure-jack-in. This starts the swank server and slime connects to it and you have a repl in a buffer. Of course just that is not worth more than running a repl in a shell. What you do get is the ability to write code in another buffer, and with a keybinding select sexps or larger units and execute them in the repl to see if it works. Also slime gives you handy keybindings for common tasks. See swank-clojure on github for more info.
JohnJ, You can do the same thing in Emacs. Actually that phrase is probably a tautology.
(add-hook 'after-save-hook etc.
Here is someone's example after-save-hook for git: https://gist.github.com/449668
With Eclipse, you can have unit tests (or any program) run every time you save a file in the project. The whole process takes less than a second -- it's great for test-driven development, and removes the need for cut-and-paste into the REPL for most situations. Plus you get to keep the tests! :-)
You'll want to use cake to avoid the JVM startup time every time you launch your tests. You can run cake test
on the command line, or just have Eclipse run it for you when you save any file in your project.
I got this to work by setting up a project with Leiningen, installing cake, and installing the counterclockwise Eclipse plugin. To set up Eclipse to run tests every time you save, select Project->Properties->Builders, click New, select Program, call it something like 'run tests', add the path to cake
under Location, select the Working Directory for your project, and add test
to the optional arguments. Under the 'Build Options' tab, select 'During Auto Builds.'
I got the general idea for this from Jeff Younker's book, "Foundations of Agile Python Development." Been an Emacs man for 20 years, but this trick has put Eclipse at the front of my workflow lately.
Update: roughly one year later, I now use Midje with the lazytest option to do the same thing while developing with both Emacs and Eclipse.
"When I look at examples of development in Clojure they seem to be along the lines of load files into the REPL, see how they work, edit the file, reload, repeat. Nary a class or jar being generated anywhere......I'd like to hear some work flow examples from folks who have created some non-trivial programs to be used by regular users (not other devs) if possible."
The examples at Debugging clojure functions which are invoked in java code (eclipse) are trivial, but illustrate how in eclipse one can link projects such that one can invoke clojure/scala functionality from within java.
来源:https://stackoverflow.com/questions/1610869/clojure-development-ide-or-repl