Shuffle a deck of cards, using the overhand shuffle method
A quick disclaimer: I am not really a clojure developer so take any of my recommendations with a pinch of salt.

Regarding your giant let:  I don't think that's necessarily a bad thing to do, but in some cases it might be worth splitting some of it off into separate functions.  For example max-slice-size and number-of-slices are only really needed to generate slice-sizes, so it may be worth splitting them off into a make-slice-sizes function or something.

Most of the reasons you listed for having things in a giant let are actually really good reasons to use smaller functions:


You've got a selection of smaller functions rather than the big dense mono-function you were trying to avoid.
Your individual functions are your manageable pieces, rather than each binding of the let.  You can call them from a repl, or write tests of just those individual functions to make sure they are behaving as expected.  
Debugging is also still possible, but with the benefit that it's easier to use a repl &amp; write tests.


A few points about your reduce:


You can simplify it a bit by returning a vector instead of a map and using argument destructuring instead of getting the values out of the map.
When you want to do a take &amp; a drop using the same numbers it's usually easier to use split-at.
Passing back 2 things from a reduce doesn't seem wrong.  However I would consider just using your reduce to build up a list of slices that you can manipulate afterwards rather than using concat to actually do the shuffling within the reduce.  The reductions function can help with this - it is like reduce, but it returns the intermediate steps that you can manipulate later.
Currently you are building up a list of random slice sizes, and then writing some more code to handle the remainder of the cards (top-cards in your code).  I think you could simplify your code a fair bit by just treating this as another slice and adding it in to your slice-sizes sequence.


I've had a go at implementing my suggestions, and ended up with this:

(defn overhand-shuffle
  "Shuffle the cards, using the overhand shuffle technique.
  REFL https://en.wikipedia.org/wiki/Shuffling#Overhand_shuffle"
  [cards]
  (let [slice-sizes        (make-slice-sizes (count cards))
        ; The first value returned by reductions is the initial value, so we
        ; drop it here.
        [_ &amp; slices]       (map first
                             (reductions (fn [[_ remaining-cards] slice-size]
                                           (split-at slice-size remaining-cards))
                                         [nil cards]
                                         slice-sizes))]
    (apply concat (reverse slices))))

(defn- make-slice-sizes
  "Randomly determine the size of the little slices we will take"
  [number-of-cards]
  (let [number-of-slices  (/ (* number-of-cards 7) 52)
        max-slice-size    (int (/ (* number-of-cards 0.6) number-of-slices))
        slice-sizes       (map inc (repeatedly
                                    number-of-slices
                                    #(rand-int max-slice-size)))
        remaining-cards   (- number-of-cards (apply + slice-sizes))]
    ;; We need to make sure all our cards get "shuffled", so add a slice of the
    ;; remaining cards on the end of our list of slices
    (concat slice-sizes [remaining-cards])))


Please let me know if I've explained any of this badly, and I'll try and improve it.

Edit: You can actually take this a bit further and split out your reduction into a function as well:

(defn build-slices
  "Builds a sequence of slices from cards.
   The sizes of the slices are determined using slice-sizes"
  [cards slice-sizes]
  ;; Perform a reduction where the first element of each step is the slice,
  ;; and the second element is the remaining cards.  Use a let binding to get
  ;; rid of the first reduction, because it is just the initial value we
  ;; passed in.
  (let [[_ &amp; slices]  (map first
                          (reductions (fn [[_ remaining-cards] slice-size]
                                        (split-at slice-size remaining-cards))
                                      [nil cards]
                                      slice-sizes))]
    slices))


Which allows you to simplify your overhand-shuffle function further:

(defn overhand-shuffle
  "Shuffle the cards, using the overhand shuffle technique.
  REFL https://en.wikipedia.org/wiki/Shuffling#Overhand_shuffle"
  [cards]
  (let [slice-sizes   (make-slice-sizes (count cards))
        slices        (build-slices cards slice-sizes)]
    (apply concat (reverse slices))))


Since both these functions are now just a series of steps each building on the last you could rewrite using one of the threading macros (-&gt; or -&gt;&gt;).  These let you list a series of forms and automatically insert the result of the last form into the next form, as either the first (for -&gt;) or the last (for -&gt;&gt;) parameter to each of them.  This allows you to make your function a series of "steps" that transform your input data, a bit like your original let bindings, but without the intermediate variables:

(defn build-slices
  "Builds a sequence of slices from cards.
   The sizes of the slices are determined using slice-sizes"
  [cards slice-sizes]
  (-&gt;&gt; slice-sizes
       ;; Perform a reduction where the first element of each step is the slice,
       ;; and the second element is the remaining cards.
       (reductions (fn [[_ remaining-cards] slice-size]
                     (split-at slice-size remaining-cards))
                   [nil cards])
       ;; Drop the first element, as it is just our initial [nil, cards] value.
       (drop 1)
       ;; Extract each of the slices.
       (map first)))

(defn overhand-shuffle
  "Shuffle the cards, using the overhand shuffle technique.
  REFL https://en.wikipedia.org/wiki/Shuffling#Overhand_shuffle"
  [cards]
  (-&gt;&gt; cards
       (count)
       (make-slice-sizes)
       (build-slices cards)
       (reverse)
       (apply concat)))


A bonus edit: the loop in your test-shuffle function is very procedural.  Could be better with iterate:

(defn test-shuffle
  "Simple invocation of shuffle, to show result"
  []
  (let [simple-cards (range 1 53)
        shuffle-times 10]
    (nth (iterate overhand-shuffle simple-cards) shuffle-times)))