I'm working on some Clojure code that has some circular dependencies between different namespaces and I'm trying to work out the best way of resolving them.
Basic issue is that I get a "No such var: namespace/functionname" error in one of the files
I tried to "declare" the function but then it complains with: "Can't refer to a qualified var that doesn't exist"
I could of course refactor the entire codebase but that seems impractical to do every time you have a dependency to resolve..... and might get very ugly for certain networks of circular dependencies
I could separate out a bunch of interfaces / protocols / declarations into a separate file and have everything refer to that.... but that seems like it would end up getting messy and spoil the current nice modular structure that I have with related functionality grouped together
Any thoughts? What is the best way to handle this kind of circular dependency in Clojure?
I remember a number of discussions on namespaces in Clojure -- on the mailing list and elsewhere -- and I have to tell you that the consensus (and, AFAICT, the current orientation of Clojure's design) is that circular dependencies are a design's cry for refactoring. Workarounds might occasionally be possible, but ugly, possibly problematic for performance (if you make things needlessly "dynamic"), not guaranteed to work forever etc.
Now you say that the circular project structure is nice and modular. But, why would you call it that if everything depends on everything...? Also, "every time you have a dependency to resolve" shouldn't be very often if you plan for a tree-like dependency structure ahead of time. And to address your idea of putting some basic protocols and the like in their own namespace, I have to say that many a time I've wished that projects would do precisely that. I find it tremendously helpful to my ability to skim a codebase and get an idea of what kind of abstractions it's working with quickly.
To summarise, my vote goes to refactoring.
I had a similar problem with some gui code, what I ended up doing is,
(defn- frame [args]
((resolve 'project.gui/frame) args))
This allowed me to resolve the call during runtime, this gets called from a menu item in frame so I was 100% sure frame was defined because it was being called from the frame itself, keep in mind that resolve may return nil.
I am having this same problem constantly. As much as many developers don't want to admit it, it is a serious design flaw in the language. Circular dependencies are a normal condition of real objects. A body cannot survive without a heart, and the heart can't survive without the body.
Resolving at call time may be possible, but it won't be optimal. Take the case where you have an API, as part of that api is error reporting methods but the api creates an object that has its own methods, those objects will need the error reporting and you have your circular dependency. Error checking and reporting functions will be called often so resolving at the time they are called isn't an option.
The solution in this case, and most cases, is to move code that doesn't have dependencies into separate (util) namespaces where they can be freely shared. I have not yet run into a case where the problem cannot be resolved with this technique. This makes maintaining complete, functional, business objects nearly impossible but it seems to be the only option. Clojure has a long way to go before it is a mature language capable of accurately modeling the real world, until then dividing up code in illogical ways is the only way to eliminate these dependencies.
If A.a() depends on B.a() and B.b() relies on A.b() the only solution is to move B.a() to C.a() and/or A.b() into C.b() even though C technically doesn't exist in the real world.
Either move everything to one giant source file so that you have no external dependencies, or else refactor. Personally I'd go with refactor, but when you really get down to it, it's all about aesthetics. Some people like KLOCS and spaghetti code, so there's no accounting for taste.
It's good to think carefully about the design. Circular dependencies may be telling us that we're confused about something important.
Here's a trick I've used to work around circular dependencies in one or two cases.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; example/a.cljc
(ns example.a
(:require [example.b :as b]))
(defn foo []
(println "foo"))
#?(
:clj
(alter-var-root #'b/foo (constantly foo)) ; <- in clojure do this
:cljs
(set! b/foo foo) ; <- in clojurescript do this
)
(defn barfoo []
(b/bar)
(foo))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; example/b.cljc
(ns example.b)
;; Avoid circular dependency. This gets set by example.a
(defonce foo nil)
(defn bar []
(println "bar"))
(defn foobar []
(foo)
(bar))
I learned this trick from Dan Holmsand's code in Reagent.
Related
I need to do a big trick and am keen on hearing your suggestions.
What I need is a macro that takes ordinary clojure code peppered with a special "await" form. The await forms contains only clojure code and are supposed to return the code's return value. Now, what I want is that when I run whatever is being produced by this macro, it should stop executing when the first "await" form is due for evaluation.
Then, it should dump all the variables defined in its scope so far to the database (I will ignore the problem that not all Clojure types can be serialised to EDN, e.g. functions can't), together with some marker of the place it has stopped in.
Then, if I want to run this code again (possibly on a different machine, another day) - it will read its state from the DB and continue where it stopped.
Therefore I could have, for example:
(defexecutor my-executor
(let [x 7
y (await (+ 3 x))]
(if (await (> y x))
"yes"
"no")))
Now, when I do:
(my-executor db-conn "unique-job-id")
the first time I should get a special return value, something like
:deferred
The second time it should be like this as well, only the third time a real return value should be returned.
The question I have is not how to write such executor, but rather how to gather information from within the macro about all the declared variables to be able to store them. Later I also want to re-establish them when I continue execution. The await forms can be nested, of course :)
I had a peek into core.async source code because it is doing a similar thing inside, but what I have found there made me shiver - it seems they employ the Clojure AST analyser to get this info. Is this really so complex? I know of &env variable inside a macro, but do not have any idea how to use it in this situation. Any help would be appreciated.
And one more thing. Please do not ask me why I need this or that there is a different way of solving a problem - I want this specific solution.
I will ignore the problem that not all Clojure types can be serialised to EDN, e.g. functions can't
If you ignore this, it will be very restrictive for the kinds of Clojure expressions you can handle. Functions are everywhere, e.g. in the implementation of things like doseq and for. Likewise, a lot of interesting programs will depend on some Java object like a file handle or whatever.
The question I have is not how to write such executor, but rather how to gather information from within the macro about all the declared variables to be able to store them.
If you manage to write such an executor, I suspect its implementation will need to know about local variables anyway. So you can put off this question until you are done implementing your executor - you will probably find it obsolete, if you can implement your executor.
I had a peek into core.async source code because it is doing a similar thing inside, but what I have found there made me shiver - it seems they employ the Clojure AST analyser to get this info. Is this really so complex?
Yes, this is very intrusive. You are basically writing a compiler. Thank your lucky stars they wrote the analyzer for you already, instead of having to analyze expressions yourself.
I know of &env variable inside a macro, but do not have any idea how to use it in this situation.
This is the easy part. If you like, you can write a simple macro that gives you all the locals in scope. This question has been asked and answered before, e.g. in Clojure get local lets.
And one more thing. Please do not ask me why I need this or that there is a different way of solving a problem - I want this specific solution.
This is generally an unproductive attitude when asking a question. It's admitting you're posing an XY problem, and still refusing to tell anyone what the Y is.
I've been learning clojure for some weeks and recently I began reading some open source code: clojure and clojurescript compilers and some libraries like om, boot, figwheel.
I noticed some clojure files are very long, some of them more than a thousand LOC. Given that clojure's code is very terse and low ceremony, that code means much more code than a file that big in some other languages.
Coming from an OO background where you usually have one class per file and you try to keep your classes short (SRP) I found that a little weird.
I know that clojure code is mostly composed of pure functions and they're way easier to reason about than some mutable class where you need to keep the current state in mind, and I find that I can read and understand most of the functions one at a time. But most of those functions are very well designed so that they don't depend on each other: even though you can use (filter odd?) it doesn't mean that filter and odd? are related. But for "every day" code (LOB apps, web apps, etc) is very hard to keep the functions as self contained as those (at least that's my experience with OO programming).
I've also seen some demos of clojurescript applications (om, reagent, etc) where they declare all components in the same file. I don't know if that's because it's just a demo and in a real life application you'd have a product.clj and a category.clj or that's just the clojure way: to have one file per namespace/module/bounded-context.
I think that if I open a folder and I see product.clj, category.clj, order.clj, etc I can get the idea at a glance what's that folder about, better than just having a components.clj or core.clj.
So, my questions are:
Is it common for "every day" clojure code to have these very long files? or is it just because I'm reading libraries code and "normal" code is more "modular", I mean: more files and less length.
Does having long files like those actually make it harder to comprehend at a glance what's the application about? like my product/category/order example above, or by some clojuresque property that's not an issue.
In case long files are the "clojure way", how do you handle conflicts, refactorings, programming in a team... if everybody is touching the same file?
1: I looked at the reasonably large non-library clojure project i'm working on right now and ran this:
ls **/*.clj | xargs wc -l | awk '{print $1}' | head -n -1 > counts
and opend a repl and ran
user> (float (/ (reduce + counts) (count counts)))
208.76471
I see that on a project with 17k LOC our average clojure file has 200 lines in it. I found one with 1k LOC.
2: Yes, I'll get started breaking that long one down as soon as I have free time. some very long ones such as clojure.core are very long becaues of clojure's one pass design and the need to self-bootstrap. they need to build the ability to have many namespaces for instance before they can do so. For other fancy libraries it may very well be that they had some other design reason for a large file though usually it's a case of "pull request welcome" in my expierence.
3: I do work in a large team with a few large files, we handle merge conflicts with git, though because changes tend to be within a function these come up, for me, much less often than in other languages. I find that it's simply not a problem.
They tend to get long as you develop them. Say you need a function foo to do procedures [a b ...] on datastructure K. You first (def) the signature of the function and continue to implement helper functions a b ... since they're likely all pure functions and the functionality you need of foo is complex the namespace tends to get long.
Sometimes, but the repl is a really useful tool, to understand a new library's main functionality I often use clojure.repl/source on the function and work my way backwards on it's helper functions. I find that a lot of time Clojure libraries documentation is either cryptic or non existent, but as many in the community like to say Clojure's functions' source is self documenting.
I have no experience working in a large team, but Arthur Ulfeldt is right most changes happen in a single function, I gather it from reading the diffs of pull requests with Github's Blame feature.
It is pragmatic (clojure or not) to avoid dependencies. Naming and classifying abstract things makes our intellect feel good, but it sort of gives up when having to stitch back all the parts together. Why make three files when one will do?
Making your mind up on what an app / lib is all about, just by reading the code? There's the "what" and there's the "how". Better have a clue about the former if you want to dive into the latter. If you're on reading the code to get a clue about the purpose of an app, I'm not sure having it split amongst more files will make it easier. Think twice about your example, none of these things can exist without the others.
The difficulty with large teams is sharing up-to-date knowledge, not files or lines, thanks git. Maybe having everyone on the same single file would be a damn good thing after all?
No, large files are not a problem in clj or other tongues. Unit<->file is a totally javartificial concept that helps compilers, not men. Split the fg buffer.
In addition to the answers others have given, here are two more.
It may be that some files are long because in Clojure it's most straightforward to use one file per namespace, so that if you want all of those definitions in the same namespace, it's easier to put them in one file. One reason to want definitions to reside in the same namespace is given in #2.
The Clojure compiler won't allow certain kinds of cyclic dependencies between namespaces (other cyclic dependencies between namespaces are fine). One way to avoid an illegal cyclic dependency is to put the interdependent definitions into the same namespace. If you do that, it might make sense to pull other definitions that belong with the problematic ones into the single namespace as well. See #1 for the rest of this answer.
(My own taste is for several smaller files, although not as small as many Java class files. Also: Code is usually not as self-documenting as its author thinks. This may hold even when the author and the person reading the code later are the same person.)
I'm in the process of learning Clojure, and I'm using 4Clojure
as a resource. I can solve many of the "easy" questions on the site, but for me thinking in a functional programming mindset still doesn't come naturally (I'm coming from Java). As a result, I use a loop/recur iterative pattern in most of my seq-building implementations because that's how I'm used to thinking.
However, when I look at the answers from more experienced Clojure users, they do things in a much more functional style. For example, in a problem about implementing the range function, my answer was the following:
(fn [start limit]
(loop [x start y limit output '()]
(if (< x y)
(recur (inc x) y (conj output x))
(reverse output))))
While this worked, other users did things like this:
(fn [x y] (take (- y x) (iterate inc x)))
My function is more verbose and I had no idea the "iterate" function even existed. But was my answer worse in an efficiency sense? Is loop/recur somehow worse to use than alternatives? I fear this sort of thing is going to happen a lot to me in the future, as there are still many functions like iterate I don't know about.
The second variant returns a lazy sequence, which may indeed be more efficient, especially if the range is big.
The other thing is that the second solution conveys the idea better. To put it differently, it describes the intent instead of implementation. It takes less time to understand it as compared to your code, where you have to read through the loop body and build a model of control flow in your head.
Regarding the discovery of the new functions: yes, you may not know in advance that some function is already defined. It is easier in, say, Haskell, where you can search for a function by its type signature, but with some experience you will learn to recognize the functional programming patterns like this. You will write the code like the second variant, and then look for something working like take and iterate in the standard library.
Bookmark the Clojure Cheetsheet website, and always have a browser tab open to it.
Study all of the functions, and especially read the examples they link to (the http://clojuredocs.org website).
The site http://clojure-doc.org is also very useful (yes, the two names are almost identical but not quite)
The question should not be about performance (it depends!) but about communication: when using loop/recur or plain recursion or lazy-seq or sometimes even reduce, you make your code harder to understand: because the reader has to understand how you perform your iteration before getting to understand what you are computing.
loop/recur is real Clojure, and idiomatic. It's there for a reason. And often there is no better way. But many people find that once one gets used to it, it's very convenient to build many functions out of building blocks such as iterate. Clojure has a very nice collection of them. I started out writing things from scratch using truly recursive algorithms and then loop/recur. Personally, I wouldn't claim that it's better to use the functional building blocks functions, but I've come to love using them. It's one of the things that's great about Clojure.
(Yes, the many of the building block functions are lazy, as are e.g. for and map, which are more general-purpose. Laziness can be good, but I'm not religious about it. Sometimes it's more efficient. Sometimes it's not. Sometimes it's beautiful. Sometimes it's a pain in the rear. Sometimes all that.)
Loop and recur are not bad - in fact, if you look at the source code for many of the built-in functions, you will find that is what they do - the provided functions are often an abstraction of common patterns which can make your code easier to understand. How you are doing things is typical for many when they first start. How you are approaching this seems correct to me. You are not just writing your solution and moving on. You are writing your solution and then looking at how others have solved the same problem and making a comparison. This is the right road to improvement. Highly recommend that when you find an alternative solution which seems more elegant/efficient/clear, analyse it, look at the source code of the built-in functions it uses and things will slowly come together.
loop ... recur is an optimisation for recursive tail calls, and should
always be used where it applies.
range is lazy, so your version of it should strive to be so.
loop ... recur can't do this.
All the sequence functions that can sensibly be lazy (iterate,
filter, map, take-while ...) are so. As you know, you can use some of these
to build a lazy range. As #cgrand explains, this is the preferred approach.
If you prefer, you can build a lazy range from scratch:
(defn range [x y]
(lazy-seq
(when (< x y)
(cons x (range (inc x) y)))))
I wondered the same thing for some days but truly many tims I do not see any better alternative than loop recur.
Some jobs are not fully "reduce" or "map". It is the case when you update data base on a buffer you mutates at every iteration.
Loop recur is very convienient where "non linear precise work" is require. It looks like more imperative but if I remember well Clojure was designed with pragmatism. Buy yet, pragmatism means choosing what is more effficient.
That is why in complex programs, I use both Clojure and java code mixed. sometimes java is just more clear for "low level" or iterative jobs like taking a specific value and so on while I see Clojure functions more useful for big data processing (without so much level of detail : global filters, etc.).
Some people say that we must stock with Clojure as much as possible but I do not see any reason not to use Java. I did not programmed a lot but Clojure/Java is the best interop I have ever seen, very complementary approaches.
Quite often, I swap! an atom value using an anonymous function that uses one or more external values in calculating the new value. There are two ways to do this, one with what I understand is a closure and one not, and my question is which is the better / more efficient way to do it?
Here's a simple made-up example -- adding a variable numeric value to an atom -- showing both approaches:
(def my-atom (atom 0))
(defn add-val-with-closure [n]
(swap! my-atom
(fn [curr-val]
;; we pull 'n' from outside the scope of the function
;; asking the compiler to do some magic to make this work
(+ curr-val n)) ))
(defn add-val-no-closure [n]
(swap! my-atom
(fn [curr-val val-to-add]
;; we bring 'n' into the scope of the function as the second function parameter
;; so no closure is needed
(+ curr-val val-to-add))
n))
This is a made-up example, and of course, you wouldn't actually write this code to solve this specific problem, because:
(swap! my-atom + n)
does the same thing without any need for an additional function.
But in more complicated cases you do need a function, and then the question arises. For me, the two ways of solving the problem are of about equal complexity from a coding perspective. If that's the case, which should I prefer? My working assumption is that the non-closure method is the better one (because it's simpler for the compiler to implement).
There's a third way to solve the problem, which is not to use an anonymous function. If you use a separate named function, then you can't use a closure and the question doesn't arise. But inlining an anonymous function often makes for more readable code, and I'd like to leave that pattern in my toolkit.
Thanks!
edit in response to A. Webb's answer below (this was too long to put into a comment):
My use of the word "efficiency" in the question was misleading. Better words might have been "elegance" or "simplicity."
One of the things that I like about Clojure is that while you can write code to execute any particular algorithm faster in other languages, if you write idiomatic Clojure code it's going to be decently fast, and it's going to be simple, elegant, and maintainable. As the problems you're trying to solve get more complex, the simplicity, elegance and maintainability get more and more important. IMO, Clojure is the most "efficient" tool in this sense for solving a whole range of complex problems.
My question was really -- given that there are two ways that I can solve this problem, what's the more idiomatic and Clojure-esque way of doing it? For me when I ask that question, how 'fast' the two approaches are is one consideration. It's not the most important one, but I still think it's a legitimate consideration if this is a common pattern and the different approaches are a wash from other perspectives. I take A. Webb's answer below to be, "Whoa! Pull back from the weeds! The compiler will handle either approach just fine, and the relative efficiency of each approach is anyway unknowable without getting deeper into the weeds of target platforms and the like. So take your hint from the name of the language and when it makes sense to do so, use closures."
closing edit on April 10, 2014
I'm going to mark A. Webb's answer as accepted, although I'm really accepting A. Webb's answer and omiel's answer -- unfortunately I can't accept them both, and adding my own answer that rolls them up seems just a bit gratuitous.
One of the many things that I love about Clojure is the community of people who work together on it. Learning a computer language doesn't just mean learning code syntax -- more fundamentally it means learning patterns of thinking about and understanding problems. Clojure, and Lisp behind it, has an incredibly powerful set of such patterns. For example, homoiconicity ("code as data") means that you can dynamically generate code at compile time using macros, or destructuring allows you to concisely and readably unpack complex data structures. None of the patterns are unique to Clojure, but Clojure brings them all together in ways that make solving problems a joy. And the only way to learn those patterns is from people who know and use them already. When I first picked Clojure more than a year ago, one of the reasons that I picked it over Scala and other contenders was the reputation of the Clojure community for being helpful and constructive. And I haven't been disappointed -- this exchange around my question, like so many others on StackOverflow and elsewhere, shows how willing the community is to help a newcomer like me -- thank you!
After you figure out the implementation details of the current compiler version for the current version of your current target host, then you'll have to start worrying about the optimizer and the JIT and then the target computer's processors.
You are too deep in the weeds, turn back to the main path.
Closing over free variables when applicable is the natural thing to do and an extremely important idiom. You may assume a language named Clojure has good support for closures.
I prefer the first approach as being simpler (as long as the closure is simple) and somewhat easier to read. I often struggle reading code where you have an anonymous function immediately called with parameters ; I have to resolve to count parentheses to be sure of what's happening, and I feel it's not a good thing.
I think the only way it could be the wrong thing to do is if the closures closes over a value that shouldn't be captured, like the head of a long lazy sequence.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
Both look reasonably good. I'd like to understand what each library is particularly good at or lacking, especially for testing of web applications.
I haven't used speclj, and I was the first author of Midje. One point that hasn't been mentioned by others is that Midje tries to exploit differences between functional and object-oriented languages.
One difference is immutability. Because most functions depend only on their inputs, not on contained state, the kind of truth statements you make about them are different in feel than their object-oriented counterparts. In OO testing, you make examples of the form: "given this history and these inputs, this method produces such and so."
It would seem that examples in a functional language would just be simpler ones: "given these inputs, this function returns such and so". But I don't think that's quite right. I think the other functions in the system play a role analogous to state/history: they're one of the things you're trying to get intellectual control over. Functions and their relationships are the things you want the tests to help you think clearly about.
For that reason, Midje is written under the assumption that a sweet development process involves saying:
What do I want to be true of this function? In the world of the system, what's a good way to think of what this function does?
In the process of doing that, what other functions would be useful---would capture an important part of the domain---and what truth statements do I want to make about them?
And then, in typical mockist style, you develop roughly top-down or outside-in, allowing for the inevitable iteration as you recover from mistakes or have better ideas.
The end result is to be a big pile of functions, with their interrelationships documented by the tests or (as Midje calls them) the "facts" about functions and the functions they depend on. Various people have commented that Midje has a Prolog/logic programming feel to it, and that's not an accident. As always, tests are examples, but Midje tries to make them read more like truth statements. That's the justification for its only actually innovative feature, metaconstants. Here's an example of them:
(fact "right changes the direction, but not the position"
(right (snapshot north ...position...)) => (snapshot west ...position...)
(right (snapshot east ...position...)) => (snapshot north ...position...)
(right (snapshot south ...position...)) => (snapshot east ...position...)
(right (snapshot west ...position...)) => (snapshot south ...position...))
In this case, the actual position is irrelevant to what's true about the function right, except that it never changes. The idea of a metaconstant is that it is a value about which nothing is known except what's explicitly stated in the test. Too often in tests, it's hard to tell what's essential and what's incidental. That has a number of bad effects: understanding, maintainability, etc. Metaconstants provide clarity. If it matters that a value is a map or record that contains the value 3 for key :a, you say that explicitly:
(fact
(full-name ..person..) => "Brian Marick"
(provided
..person.. =contains=> {:given-name "Brian", :family-name "Marick"}))
This test is explicit about what matters about people---and also explicit about what doesn't matter (anything but the two names).
In math terms, Midje is trying to let you make statements like "for all x where x..." while still being a test tool rather than a theorem prover.
This approach was inspired by "London-style" mock-heavy TDD of the sort described in Growing Object-Oriented Software, which is the approach I usually use in writing Ruby code. But it's turned out to have a pretty different feel, in a way that's hard to describe. But it's a feel that needs more tool support than just with-redefs.
The upshot is that Midje is in part an attempt to find a style of functional TDD that's not just a port of OO TDD. It tries to be a general-purpose tool, too, but it's semi-opinionated software. As Abraham Lincoln said, "Those who like this sort of thing will find this the sort of thing they like."
The biggest benefit of using Midje is that it provides focused abstractions for testing things without testing all of their parts, parts that often drag in the whole rest of the world.
If you have a function that involves calling a subsidiary function to generate a timestamp, putting something in a database or message queue, make an API request, caching something, logging something, etc, you want know that these world-involving function calls occurred (and sometimes how many times they occurred), however actually executing them is irrelevant to the function you are testing, and the called functions will often deserve having their own unit tests.
Say you have this in your code:
(defn timestamp [] (System/currentTimeMillis))
(defn important-message [x y] (log/warnf "Really important message about %s." x))
(defn contrived [x & y]
(important-message x y)
{:x x :timestamp (timestamp)})
Here is how you could test it with midje:
(ns foo.core-test
(:require [midje.sweet :refer :all]
[foo.core :as base]))
(fact
(base/contrived 100) => {:x 100 :timestamp 1350526304739}
(provided (base/timestamp) => 1350526304739
(base/important-message 100 irrelevant) => anything :times 1))
This example is just a quick glimpse at what you can do with midje but demonstrates the essence of what it is good at. Here you can see there is very little extraneous complexity needed to express:
what the function should produce (despite the fact that what the
timestamp function would produce would be different each time you
call the function),
that the timestamp function and the logging function were called,
that the logging function was only called one time,
that the logging function received the expected first argument, and
that you don't care what the second argument it received was.
The main point I am trying to make with this example is that it's a very clean and compact way of expressing tests of complex code (and by complex I mean it has embedded parts that can be separated) in simple pieces rather than trying to test everything all at once. Testing everything all at once has its place, namely in integration testing.
I am admittedly biased because I actively use midje, whereas I have only looked at speclj, but my sense is that speclj is probably most attractive to people who have used the analogous Ruby library and find that way of thinking about tests ideal, based on that experience. That is a perfectly rspectable reason to chose a testing framework, and there are probably other nice things about it as well that hopefully others can comment on.
I'd definitely go with Speclj.
Speclj is simple to integrate and use. Its syntax is less flamboyant than Midje's. Speclj is based on RSpec to give you all the conforts that Ruby programmers are used to without losing the idiosyncrasies of Clojure.
And the auto runner in Speclj is great.
lein spec -a
Once you've used that for a while, you'll wonder how you ever got work done when you had to manually run tests.
Mocking is a non-issue since you can simply use with-redefs. #rplevy's example in Speclj would look like this.
(ns foo.core-spec
(:require [speclj.core :refer :all ]
[foo.core :as base]))
(describe "Core"
(it "contrives 100"
(let [message-params (atom nil)]
(with-redefs [base/timestamp (fn [] 1350526304739)
base/important-message #(reset! message-params [%1 %2])]
(should= {:x 100 :timestamp 1350526304739} (base/contrived 100))
(should= 100 (first #message-params))))))
This bare-bones approach to mocking is to-the-point; no misdirection.
As for testing web apps, Speclj works fine. In fact Speclj support is build into Joodo.
disclaimer: I wrote Speclj
I'd say that Midje is especially good at creating a DSL for expressing stubbing and mocking. If you care about stubbing and mocking, and want to use it a lot, I'd choose Midje over Speclj, because it has abstractions for expressing those types of tests that are more concise than the approach slagyr offered in his answer.
Another option, if you want a more light-weight approach, is the Conjure stubbing/mocking library intended to be used with clojure.test.
Where Speclj shines is in being a lot like RSpec, having 'describe' and 'it' included... Midje can support nested facts actually, but not as elegantly as Speclj.
disclaimer: I'm a contributor to Midje and Conjure. :)
I would suggest Midje over Speclj
For speclj, I don't think if it has good support for mocks, the documentation also looks sparse as compared to Midje.
Also the syntax for Midje is better:
(foo :bar) => :result compared to (should= (foo :bar) :result)