Have a look at compojure - a good example of with-local-vars is where
a servlet request is executed. Each (get, post) request occurs in its
entirety on a single (jetty or tomcat) thread. The compojure call to
the application service function binds the http headers, servlet
request parameters, etc, using with-local-vars and then calls the app
function. These values are all then in scope for the called service
function _and_ any functions that it in turn calls. This is all safe
without using refs/atoms as the values are all "local-thread" bound.

Here's an application example...

(declare *locs*)
(declare my-service)

(def my-servlet
  (proxy [HttpServlet] []
    (service [request response]
      (binding [*locs* {:basedir "."}]
        (my-service this request response)))))

(defservice "my-"  ; this is a compojure macro defining my-service
    (ANY "*"
      (var-set (var *locs*)
        (authenticate cookies request))
      (if (nil? (:usr *locs*))
        (frm-login "No session")
        :next))
    (GET "/logged-in-app-call" ...

Here we declare *locs* as an unbound var in the namespace. Then
my-servlet proxies the servlet class and the compojure service call
has all the headers, etc bound in with-local-vars. Then for app
purposes, we bind *locs*  to some default app related stuff before the
call to my-service. Then in my-service, the first thing we do is to
authenticate the user using a cookie's information (cookies are local
thread bound). Authentication then adds {:usr <credentials or nil>} to
whatever was in *locs* and returns the new map. Var-set updates *locs*
and either a login page is invoked or we drop through (:next) to the
matching app "path". All app functions then have access to the *locs*
map and can use the :usr credentials, default stuff, etc.

A bit contrived from the actual app and a bit complex to explain, but
local vars are very useful in this situation.

Regards, Adrian.


On Fri, Feb 13, 2009 at 3:10 PM, Konrad Hinsen
<konrad.hin...@laposte.net> wrote:
>
> On Feb 13, 2009, at 13:31, Mark Volkmann wrote:
>
>> What are some reasons to use with-local-vars instead of let or
>> binding?
>
> Let just creates bindings for a lexical scope. They cannot be
> modified at all.
>
> Binding and with-local-vars deal with vars, i.e. mutable references.
> Binding creates a dynamic scope for already existing vars that are
> accessible in some namespace. With-local-vars also creates a dynamic
> scope, but for newly created anonymous vars.
>
> So far for the theory. I have to admit that in my own experience,
> every time I considered using with-local-vars, I ended up realising
> that what I really wanted is atoms or refs. Which means that I cannot
> cite a use case for with-local-vars. I scanned through the source
> code of clojure and clojure-contrib to see if with-local-vars is used
> anywhere at all, but the answer is no.
>
> Konrad.
>
>
> >
>

--~--~---------~--~----~------------~-------~--~----~
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
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
-~----------~----~----~----~------~----~------~--~---

Reply via email to