Hi Scaramaccai, Several posters in this thread have given you example code for how to solve your OAuth token problem in Clojure. Perhaps I can add to this discussion by pointing out the fundamentals of functional programming that can help you decide how to solve problems like this.
*Loops -> Recursions and State -> Bindings* You asked how to handle state in a functional programming language. In some situations, it may be easiest to just store stateful values in a mutable container type like a ref, agent, or atom. This is not a strictly functional approach, but these are tools that Clojure provides to make a variety of programming tasks somewhat easier (in the Rich Hickey sense of the word). In many cases, this is neither necessary nor preferable. Instead, you can use the functional programming approach of emulating state change over time by passing your new derived values as arguments to the next step in a recursive function. That is, in FP "state change" happens on the stack (through function bindings and let bindings) rather than on the heap (through direct assignment to mutable containers). Consider these two approaches to computing the factorial function. *1. Imperative (loops + mutation)* (defn fact-imp [n] (let [result (atom 1)] (dotimes [i n] (swap! result * (inc i))) @result)) *2. Functional (recursion + fn bindings)* (defn fact-rec [n] (if (<= n 0) 1 (* n (fact-rec (dec n))))) These two implementations will return the same outputs for the same inputs. Note that in the functional approach, fact-rec computes the next value of the result and passes it as the input to itself rather than mutating a local variable as in the imperative case with fact-imp. Savvy readers will notice that fact-rec is not tail recursive and is therefore prone to stack overflow for large values of n. Rewriting it to work with loop+recur is left as an exercise for the reader. ;) The approach shown above is a typical solution for state that goes through a series of intermediate changes to produce a final result. A similar approach for the same issue is to model all the values that you would have stored one at a time in a stateful variable as an immutable sequence of values. This approach relies on lazy evaluation. To illustrate, I will once again implement factorial using this technique. *3. Functional (sequences + lazy evaluation)* (defn fact-lazy [n] (letfn [(next-step [[i x]] [(inc i) (* x (inc i))]) (fact-seq [pair] (lazy-seq (cons pair (fact-seq (next-step pair )))))] (second (nth (fact-seq [0 1]) n)))) In this example, next-step derives the next state value from the current one. The fact-seq function returns a lazy sequence of all the [i factorial(i)] pairs from [0 1] to [infinity factorial(infinity)]. This sequence is obviously never fully realized since it would throw your application into an infinite recursion. We then use nth to grab the [n factorial(n)] pair off of the lazy sequence and second plucks out just factorial(n) to return as the result of our fact-lazy function. Once again, I never mutated any variables in place. I simply created a recursive algorithm that could derive the next value from the current value. Unlike the non-tail-recursive fact-rec above, this lazy sequence implementation is immune to stack overflow errors. However, fact-lazy will use more memory and more CPU cycles than fact-rec's eager implementation because it has to create and release the lazy sequence and intermediate vector pairs. These are all tradeoffs, which you would need to consider in determining the approach that might work best for your problem. *Hiding State* In the three approaches I showed to represent state change in your Clojure program, none of these went out of their way to either hide or share the state values over time. Here, you again have broadly two choices: *1. Global mutable variables* If you don't need to hide your application state, the best approach is just to store it in a global mutable container like a ref, agent, or atom. Then you can introspect or manipulate it from your REPL, and multiple functions in your program can all access it as needed. (def state (atom 0)) *2. Closures* If you need to hide your application state for some reason (and there are often less reasons to do this than you might imagine), then your best friend is a closure function. A closure is a function which "closes over" the bindings which exist when it is defined by capturing references to them in its free variables (i.e., variables which are not bound as function args or let args in the function body). Functions that return closures around mutable state can work a bit like OOP constructor functions, creating a function that behaves a bit like an object with internal stateful attributes. Welcome to OOP inverted! (defn get-token "Somehow get an OAuth token for this user+pass combination." [user pass] {:token "some-token" ; replace this with something real :expires (+ (System/currentTimeMillis) 1000000)}) (defn expired? "Returns true if the token has expired." [token] (> (System/currentTimeMillis) (:expires token))) (defn make-http-client "Return a closure that retains the token associated with this user+pass combination and can make HTTP requests using it." [user pass] (let [token (atom (get-token user pass))] (fn [url] (when (expired? @token) (reset! token (get-token user pass))) (client/get url {:oauth-token (:token @token)})))) (def get-response (make-http-client "my-user" "my-pass")) (get-response "some-url") (get-response "another-url") (get-response "yet-another-url") (get-response "even-another-url") The code above creates a closure function called get-response that contains an internal reference to a token atom. This atom is automatically updated using the stored user and pass whenever the token expires. All HTTP requests generated by get-response include the up-to-date OAuth token as expected. I hope this exposition on some of the approaches used to solve problems in a functional programming style will help you both in your current project and many more going forward. Just remember to visualize state change over time as a sequence of values which can be recursively derived by their previous values. Whether the transformation from current value to next value is best done in an eager fashion (like fact-rec) or in a lazy fashion (like fact-lazy) will be determined by your particular problem domain. In many cases, there is not much value to hiding state, so if you choose to use mutable container types like refs, atoms, or agents, you are likely better off just making them globally available. However, if you really do want to capture state lexically within a function (perhaps because you need to pass it to another namespace), then closures can give you that ability in a powerful yet succinct way. And to echo James Reeves' comments, your code will be shorter, simpler, and easier to extend if you just stick with plain maps. Records and protocols are great if you need fast polymorphism in your algorithm or if you need to extend a class that you don't control to implement one of your functions. However, they add a good bit of extra overhead to your code base that can make it more difficult to read, debug, and extend later. Alright, that's enough from me on this topic. Go forth and write beautiful, elegant, functional code. (hack :the-planet) ~Gary -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/clojure/abbce12a-e069-4ef0-adec-5e32e0d80a3do%40googlegroups.com.