Constructive (non-destructive) operations should be preferred where possible because code without side-effects is usually more reusable and easier to reason about. There are two main reasons to use destructive operations:
For the side-effect. Some code is simpler to express with destructive operations; constructive operations return new objects, and sometimes ``threading'' the objects through the program manually complicates stack shuffling.
As an optimization. Some code written to use constructive operations suffers from worse performance. An example is a loop which adds an element to a sequence on each iteration. Either suffix or suffix! could be used; however, the former copies the entire sequence each time, which would cause the loop to run in quadratic time.

The second reason is much weaker than the first one. In particular, many combinators (see map, produce and Making sequences with variables ) as well as more advanced data structures (such as persistent.vectors ) alleviate the need for explicit use of side effects.