Re: Clojure equivalent of special common lisp vars: still looking for that zen place...

2014-05-05 Thread Gary Trakhman
Sometimes you do want a mutable thing with thread-local binding, noir does
this for it's mutable session-flash stuff:
https://github.com/noir-clojure/lib-noir/blob/master/src/noir/session.clj#L95

I don't really recommend the approach, but I could see it being convenient.


On Mon, May 5, 2014 at 1:38 PM, John Gabriele  wrote:

> On Saturday, May 3, 2014 10:53:40 AM UTC-4, Bob Hutchison wrote:
>>
>>
>> On May 3, 2014, at 9:45 AM, Dave Tenny  wrote:
>>
>> I'm still struggling with how to write the most readable, simple clojure
>> code
>> to deal with dynamically bindings.
>>
>> What is the graceful clojure equivalent of common lisp special variables
>> for the following scenario.
>>
>> If I were writing common lisp I'd just do something like (pardon if my
>> lisp is rusty here):
>>
>> (defvar *x* 1)
>> ... do stuff with *x* ...
>> (setq *x* 2)
>> ... do stuff with *x* ...
>> (let ((*x* 3))  (do stuff with *x*...)
>> ;; do stuff with *x* that's currently at 2
>>
>>
>> The way I'm tempted to do this in clojure is
>>
>> (def ^{:dynamic true} *x* (atom 1))
>> ... do stuff with @*x* ...
>> (reset! *x* 2)
>> ... do stuff with @*x* ...
>> (binding [*x* (atom 3)] (do stuff with @*x*))
>>
>>
>> You can also just write it:
>>
>> (def ^:dynamic *x* (atom 1))
>>
>> which is a little less verbose.
>>
>>
> My understanding is that it's more common to *either*
>
>   * use `(def ^:dynamic *x* 1)`, *or*
>   * use `(def x (atom 1))`,
>
> but not both at the same time.
>
> That is to say, either you specifically want at dynamic var which you can
> change via a `binding`, or else you just want a global mutable (the atom).
>
> Would love to be corrected if I'm wrong though.
>
> -- John
>
>  --
> 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.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
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.
For more options, visit https://groups.google.com/d/optout.


Re: Clojure equivalent of special common lisp vars: still looking for that zen place...

2014-05-05 Thread John Gabriele
On Saturday, May 3, 2014 10:53:40 AM UTC-4, Bob Hutchison wrote:
>
>
> On May 3, 2014, at 9:45 AM, Dave Tenny > 
> wrote:
>
> I'm still struggling with how to write the most readable, simple clojure 
> code
> to deal with dynamically bindings.
>
> What is the graceful clojure equivalent of common lisp special variables 
> for the following scenario.
>
> If I were writing common lisp I'd just do something like (pardon if my 
> lisp is rusty here):
>
> (defvar *x* 1)
> ... do stuff with *x* ...
> (setq *x* 2)
> ... do stuff with *x* ...
> (let ((*x* 3))  (do stuff with *x*...)
> ;; do stuff with *x* that's currently at 2
>
>
> The way I'm tempted to do this in clojure is
>
> (def ^{:dynamic true} *x* (atom 1))
> ... do stuff with @*x* ...
> (reset! *x* 2)
> ... do stuff with @*x* ...
> (binding [*x* (atom 3)] (do stuff with @*x*))
>
>
> You can also just write it:
>
> (def ^:dynamic *x* (atom 1))
>
> which is a little less verbose.
>
>
My understanding is that it's more common to *either*

  * use `(def ^:dynamic *x* 1)`, *or*
  * use `(def x (atom 1))`,

but not both at the same time.

That is to say, either you specifically want at dynamic var which you can 
change via a `binding`, or else you just want a global mutable (the atom).

Would love to be corrected if I'm wrong though.

-- John

-- 
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.
For more options, visit https://groups.google.com/d/optout.


Re: Clojure equivalent of special common lisp vars: still looking for that zen place...

2014-05-03 Thread Dave Tenny
re: binding behavior, I've only been using clojure since 1.5.1, but in my
travels I get the impression that the binding form didn't always enforce
the variable to be declared dynamic, and so maybe didn't behave the way
you'd expect if the ^:dynamic was missing from the target of the binding
form.  Just guessing.


On Sat, May 3, 2014 at 11:08 AM, Lee Spector  wrote:

>
> On May 3, 2014, at 9:45 AM, Dave Tenny  wrote:
> >
> > The way I'm tempted to do this in clojure is
> >
> > (def ^{:dynamic true} *x* (atom 1))
> > ... do stuff with @*x* ...
> > (reset! *x* 2)
> > ... do stuff with @*x* ...
> > (binding [*x* (atom 3)] (do stuff with @*x*))
>
>
> Having also come from Common Lisp and having once done things similar to
> your suggestion in Clojure, I got burned by the fact (I *think* it was a
> fact) that "binding" created thread-local bindings that reverted to global
> bindings inside of code executed in another thread, e.g. in a pmap buried
> somewhere within the code executed within the binding form. I found this to
> be unexpected and problematic.
>
> Trying some simple examples with your outline, however, I don't see this
> happening. And I wonder if it's because of changes in more recent versions
> of Clojure related to ^{:dynamic true}.
>
> Does anyone know if the reversion of "binding"-bound vars to global
> bindings when crossing thread boundaries has really been eliminated? Or am
> I just not seeing it because my examples have been too simple?
>
>   -Lee
>
> --
> 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 a topic in the
> Google Groups "Clojure" group.
> To unsubscribe from this topic, visit
> https://groups.google.com/d/topic/clojure/Wh1M345Y5u4/unsubscribe.
> To unsubscribe from this group and all its topics, send an email to
> clojure+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
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.
For more options, visit https://groups.google.com/d/optout.


Re: Clojure equivalent of special common lisp vars: still looking for that zen place...

2014-05-03 Thread Dave Tenny
On Sat, May 3, 2014 at 10:53 AM, Bob Hutchison wrote:

> You can also just use ‘def’ to redefine the global binding.



Thanks, though in this case it's a mixed use.  In some cases I want to
change the root of the global binding, in others I want to rebind to a new
value in some context without changing the value seen in other contexts.

-- 
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.
For more options, visit https://groups.google.com/d/optout.


Re: Clojure equivalent of special common lisp vars: still looking for that zen place...

2014-05-03 Thread Lee Spector

On May 3, 2014, at 9:45 AM, Dave Tenny  wrote:
> 
> The way I'm tempted to do this in clojure is
> 
> (def ^{:dynamic true} *x* (atom 1))
> ... do stuff with @*x* ...
> (reset! *x* 2)
> ... do stuff with @*x* ...
> (binding [*x* (atom 3)] (do stuff with @*x*))


Having also come from Common Lisp and having once done things similar to your 
suggestion in Clojure, I got burned by the fact (I *think* it was a fact) that 
"binding" created thread-local bindings that reverted to global bindings inside 
of code executed in another thread, e.g. in a pmap buried somewhere within the 
code executed within the binding form. I found this to be unexpected and 
problematic.

Trying some simple examples with your outline, however, I don't see this 
happening. And I wonder if it's because of changes in more recent versions of 
Clojure related to ^{:dynamic true}.

Does anyone know if the reversion of "binding"-bound vars to global bindings 
when crossing thread boundaries has really been eliminated? Or am I just not 
seeing it because my examples have been too simple?

  -Lee

-- 
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.
For more options, visit https://groups.google.com/d/optout.


Re: Clojure equivalent of special common lisp vars: still looking for that zen place...

2014-05-03 Thread Bob Hutchison

On May 3, 2014, at 9:45 AM, Dave Tenny  wrote:

> I'm still struggling with how to write the most readable, simple clojure code
> to deal with dynamically bindings.
> 
> What is the graceful clojure equivalent of common lisp special variables for 
> the following scenario.
> 
> If I were writing common lisp I'd just do something like (pardon if my lisp 
> is rusty here):
> 
> (defvar *x* 1)
> ... do stuff with *x* ...
> (setq *x* 2)
> ... do stuff with *x* ...
> (let ((*x* 3))  (do stuff with *x*...)
> ;; do stuff with *x* that's currently at 2
> 
> 
> The way I'm tempted to do this in clojure is
> 
> (def ^{:dynamic true} *x* (atom 1))
> ... do stuff with @*x* ...
> (reset! *x* 2)
> ... do stuff with @*x* ...
> (binding [*x* (atom 3)] (do stuff with @*x*))

Inside the binding you can call set! if you must.

You can also just use 'def' to redefine the global binding. It says this:

"Using def to modify the root value of a var at other than the top level is 
usually an indication that you are using the var as a mutable global, and is 
considered bad style. Consider either using binding to provide a thread-local 
value for the var, or putting a ref or agent in the var and using transactions 
or actions for mutation." in the docs at http://clojure.org/special_forms#def 
which is roughly what you did with the atom. But it'll work.

You can also just write it:

(def ^:dynamic *x* (atom 1))

which is a little less verbose.

Cheers,
Bob

> 
> 
> Is that the simplest way to map between the two language scenarios?
> Or is there something simpler, perhaps using some var-* apis or what have you?
> 
> 
> 
> -- 
> 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.
> For more options, visit https://groups.google.com/d/optout.

-- 
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.
For more options, visit https://groups.google.com/d/optout.


Clojure equivalent of special common lisp vars: still looking for that zen place...

2014-05-03 Thread Dave Tenny
I'm still struggling with how to write the most readable, simple clojure 
code
to deal with dynamically bindings.

What is the graceful clojure equivalent of common lisp special variables 
for the following scenario.

If I were writing common lisp I'd just do something like (pardon if my lisp 
is rusty here):

(defvar *x* 1)
... do stuff with *x* ...
(setq *x* 2)
... do stuff with *x* ...
(let ((*x* 3))  (do stuff with *x*...)
;; do stuff with *x* that's currently at 2


The way I'm tempted to do this in clojure is

(def ^{:dynamic true} *x* (atom 1))
... do stuff with @*x* ...
(reset! *x* 2)
... do stuff with @*x* ...
(binding [*x* (atom 3)] (do stuff with @*x*))


Is that the simplest way to map between the two language scenarios?
Or is there something simpler, perhaps using some var-* apis or what have 
you?


-- 
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.
For more options, visit https://groups.google.com/d/optout.