+1 This separation of behaviour and state is a key part of Clojure's
philosophy. That isn't to say that stateful components are bad as such
(Stuart Sierra's
https://github.com/stuartsierra/component is an
obvious analog here) only that they aren't a given as they are in OO
languages.
As Jony says, when functions only depend on their parameters it makes
many things simpler and more flexible, but can appear 'noisy'.
http://thinkrelevance.com/blog/2009/08/12/rifle-oriented-programming-with-clojure-2
is another good resource here, although I must say I haven't seen some
of those examples in the wild :).
From a similar background (Java) and having learnt some lessons, I
wish somebody hammered me on the head with the following:
- get real familiar with the notion of data transformations, particularly maps
- internalise map, reduce, filter, apply, loop/recur and into
- before writing any code check the API doesn't already provide it
- repeat the above three points
- embrace vanilla maps, they really are all you need (and also watch
https://www.youtube.com/watch?v=ZQkIWWTygio)
- small functions (10 lines is uncomfortable) always
- embrace pre/post conditions, documentation (defn doc and
marginalia) and prismatic schema
- read as much Clojure code as you can get your hands on
- TDD is still a helpful process/technique in Clojure ;)
Longer term, watch anything from Rich Hickey.
By far the biggest conceptual shift was thinking in terms of data
being the public API and data transformation over blobs of state and
data.
Hope this helps.