Question: I tried setting the following:

set ftp:initial-prot ""
set ftp:ssl-force true
set ftp:ssl-protect-data true
set ftp:ssl-auth TLS

and am on RHEL4 trying to lftp to a 2010 Windows server but I am getting 

Fatal error: gnutls\_handshake: A TLS packet with unexpected length was received.

Can you please let me know what is that am missing now?

Answer: 
Let does not create local "variables", it gives names to values, and does not let you change them after giving them the name. So introducing a let is more like defining a local constant. 

First I'll just add another item into the `loop` expression to store the value so far. Each time through the loop we will update this to incorporate the new information. This pattern is very common. I also needed to add a new argument to the function to hold the initial state (reduce as a concept needs this)

```
user> (defn new-reduce [function initial-value coll]
        (loop [i 0 
               answer-so-far initial-value]
          (if (< i (count coll))
            (recur (inc i) (function answer-so-far (get coll i)))
            answer-so-far)))

user> (new-reduce + 0 [1 2 3])
6

```

This moves the "global variable" into a name that is local to the loop expression can be updated once per loop at the time you jump back up to the top. Once it reaches the end of the loop it will return the answer thus far as the return value of the function rather than recurring again. Building your own reduce function is a great way to build understanding on how to use reduce effectively. 

There is a function that introduces true local variables, though it is very nearly never used in Clojure code. It's only really used in the runtime bootstap code. If you are really curious read up on binding very carefully.
Here's a simple, functional solution that replicates the behavior of the standard `reduce`:

```
(defn reduce
  ([f [head & tail :as coll]]
   (if (empty? coll)
     (f)
     (reduce f head tail)))
  ([f init [head & tail :as coll]]
   (cond
     (reduced? init) @init
     (empty? coll) init
     :else (recur f (f init head) tail))))

```

There is no `loop` here, because the function itself serves as the recursion point. I personally find it easier to think about this recursively, but since we're using tail recursion with `recur`, you can think about it imperatively/iteratively as well:

1. If `init` is a signal to return early then return its value, otherwise go to step 2
2. If `coll` is empty then return `init`, otherwise go to step 3
3. Set `init` to the result of calling `f` with `init` and the first item of `coll` as arguments
4. Set `coll` to a sequence of all items in `coll` except the first one
5. Go to step 1

Actually, under the hood (with tail-call optimization and such), that's essentially what's really going on. I'd encourage you to compare these two expressions of the same solution to get a better idea of how to go about solving these sorts of problems in Clojure.