Re: How to encapsulate local state in closures

2008-12-31 Thread Rich Hickey
On Dec 31, 2008, at 12:30 AM, Mark Engelberg wrote: On Tue, Dec 30, 2008 at 8:38 PM, Rich Hickey richhic...@gmail.com wrote: There's simply no value for Clojure to add to a simple mutable box. Clojure does provide the tools for low-level mutation - access to Java. You can wrap that in

Re: How to encapsulate local state in closures

2008-12-31 Thread Mark Engelberg
On Wed, Dec 31, 2008 at 6:27 AM, Rich Hickey richhic...@gmail.com wrote: I also think that your use cases for atoms for local mutation are a mismatch. atoms are about sharing. You really want something else for private/local mutable references, and I have some ideas for that. You're right

Re: How to encapsulate local state in closures

2008-12-31 Thread Rich Hickey
On Dec 31, 1:20 pm, Mark Engelberg mark.engelb...@gmail.com wrote: On Wed, Dec 31, 2008 at 6:27 AM, Rich Hickey richhic...@gmail.com wrote: I also think that your use cases for atoms for local mutation are a mismatch. atoms are about sharing. You really want something else for

Re: How to encapsulate local state in closures

2008-12-31 Thread Luc Prefontaine
I have not yet written thousands of line of parallel code in Clojure (I am in this learning curve as of now while experimenting with Terracotta). However I can compare with other frameworks I've used in the past: ASTs, Event Flags,... on VMS, semaphores, condition variables, mutexes, ... in

Re: How to encapsulate local state in closures

2008-12-31 Thread Timothy Pratley
On Dec 30, 2008, at 6:29 PM, Mark Engelberg wrote: Use Case #1: Implementing classic imperative algorithm (GDC) I replaced your (atoms) using (with-local-vars) and the function runs perfectly fine. The local vars are not closed over, so they cannot leak, and the code is cleaner. So this

Re: How to encapsulate local state in closures

2008-12-30 Thread Rich Hickey
On Dec 29, 8:08 pm, Mark Engelberg mark.engelb...@gmail.com wrote: On Mon, Dec 29, 2008 at 12:40 PM, Rich Hickey richhic...@gmail.com wrote: People who know what they are doing can do these things right now with Clojure's array support. There really isn't any more value for Clojure to

Re: How to encapsulate local state in closures

2008-12-30 Thread Mark Engelberg
On Tue, Dec 30, 2008 at 5:53 AM, Rich Hickey richhic...@gmail.com wrote: Could you provide an example of when you would need/use that? Sure. Use Case #1: Implementing classic imperative algorithms Consider the binary gcd algorithm on page 338 of The Art of Computer Programmiing, volume 2.

Re: How to encapsulate local state in closures

2008-12-30 Thread Rich Hickey
On Dec 30, 2008, at 6:29 PM, Mark Engelberg wrote: On Tue, Dec 30, 2008 at 5:53 AM, Rich Hickey richhic...@gmail.com wrote: Could you provide an example of when you would need/use that? Sure. Use Case #1: Implementing classic imperative algorithms Consider the binary gcd algorithm

Re: How to encapsulate local state in closures

2008-12-30 Thread Mark Engelberg
On Tue, Dec 30, 2008 at 8:38 PM, Rich Hickey richhic...@gmail.com wrote: There's simply no value for Clojure to add to a simple mutable box. Clojure does provide the tools for low-level mutation - access to Java. You can wrap that in whatever functions/macros you like. There's no way to use

Re: How to encapsulate local state in closures

2008-12-29 Thread Rich Hickey
On Sat, Dec 27, 2008 at 12:03 AM, Mark Engelberg mark.engelb...@gmail.com wrote: On Fri, Dec 26, 2008 at 8:35 PM, Adrian Cuthbertson adrian.cuthbert...@gmail.com wrote: It's important to distinguish between updating atoms within transactions and outside transactions. In the former case, one

Re: How to encapsulate local state in closures

2008-12-29 Thread Mark Engelberg
On Mon, Dec 29, 2008 at 8:05 AM, Rich Hickey richhic...@gmail.com wrote: It is certainly not the whole point of Clojure to make as much code as possible safe for its software transactional memory. Clojure is a set of tools. They are designed to allow for robust programs to be built, including

Re: How to encapsulate local state in closures

2008-12-29 Thread Rich Hickey
On Dec 29, 2:29 pm, Mark Engelberg mark.engelb...@gmail.com wrote: On Mon, Dec 29, 2008 at 8:05 AM, Rich Hickey richhic...@gmail.com wrote: It is certainly not the whole point of Clojure to make as much code as possible safe for its software transactional memory. Clojure is a set of

Re: How to encapsulate local state in closures

2008-12-29 Thread Dave Griffith
It looks like the mutable locals use case is covered by the with- local-vars binding form. That said, I'm not sure how useful this would be. Even in Java 5, 95% of my local vars are immutable, i.e annotated as final and never have any mutating methods called on them. Most of the rest are

Re: How to encapsulate local state in closures

2008-12-29 Thread Mark Engelberg
On Mon, Dec 29, 2008 at 12:40 PM, Rich Hickey richhic...@gmail.com wrote: People who know what they are doing can do these things right now with Clojure's array support. There really isn't any more value for Clojure to add to that, so no special primitives. I fully accept the necessity of

Re: How to encapsulate local state in closures

2008-12-29 Thread Mark Engelberg
On Mon, Dec 29, 2008 at 2:57 PM, Dave Griffith dave.l.griff...@gmail.com wrote: It looks like the mutable locals use case is covered by the with- local-vars binding form. Not really. with-local-vars has somewhat surprising semantics. For example, you'd expect this (contrived) function to

Re: How to encapsulate local state in closures

2008-12-29 Thread Timothy Pratley
I think if Clojure could do something like this (enforce a certain kind of referentially transparent mutable local), that would be neat, It is possible to achieve this behavior explicitly: (defn create-add-2 [] (with-local-vars [x 1] (do (var-set x 2) (let [z @x] (fn

Re: How to encapsulate local state in closures

2008-12-26 Thread Adrian Cuthbertson
On Dec 22, 2:34 pm, Mark Engelberg mark.engelb...@gmail.com wrote: On Mon, Dec 22, 2008 at 4:23 AM, Parth Malwankar parth.malwan...@gmail.com wrote: If I get it right, atoms are quite useful to maintain state in the context of a single thread with memoization and counter (within a

Re: How to encapsulate local state in closures

2008-12-26 Thread Mark Engelberg
On Fri, Dec 26, 2008 at 8:35 PM, Adrian Cuthbertson adrian.cuthbert...@gmail.com wrote: It's important to distinguish between updating atoms within transactions and outside transactions. In the former case, one has to ensure the update function can be retried without ill-effects. However,

Re: How to encapsulate local state in closures

2008-12-22 Thread Parth Malwankar
On Dec 22, 12:25 pm, Mark Engelberg mark.engelb...@gmail.com wrote: I misspoke; it's the call to counter that's the problem.  Let's say you want to use a counter to count the number of times a ref is set, something like this: (dosync (counter) (ref-set r 1)) If your var-set causes the

Re: How to encapsulate local state in closures

2008-12-22 Thread J. McConnell
On Mon, Dec 22, 2008 at 2:25 AM, Mark Engelberg mark.engelb...@gmail.com wrote: Aside from the memoization example for which it was invented, I am hard-pressed to think of a good use for atoms. Not having used them myself, I can't think of many good examples either. However, one in addition

Re: How to encapsulate local state in closures

2008-12-22 Thread Mark Engelberg
On Mon, Dec 22, 2008 at 4:23 AM, Parth Malwankar parth.malwan...@gmail.com wrote: If I get it right, atoms are quite useful to maintain state in the context of a single thread with memoization and counter (within a thread) being two examples. No, RH said that atoms were definitely intended

How to encapsulate local state in closures

2008-12-21 Thread chris
I would like to be able to encapsulate local state in a closure. Specifically, I would like a function that returns an incrementing integer, thus: (test_func) 1 (test_func) 2 What is the best way to go about this? With local bindings is failing and I can't figure just why... (def test_closure

Re: How to encapsulate local state in closures

2008-12-21 Thread Parth Malwankar
On Dec 21, 11:47 pm, chris cnuern...@gmail.com wrote: I would like to be able to encapsulate local state in a closure. Specifically, I would like a function that returns an incrementing integer, thus: (test_func) 1 (test_func) 2 What is the best way to go about this?  With local

Re: How to encapsulate local state in closures

2008-12-21 Thread Brian Doyle
I haven't been following the new atom stuff, so I was wondering why atom would be best in this situation, vs a ref? Thanks. On Sun, Dec 21, 2008 at 1:03 PM, Parth Malwankar parth.malwan...@gmail.comwrote: On Dec 21, 11:47 pm, chris cnuern...@gmail.com wrote: I would like to be able to

Re: How to encapsulate local state in closures

2008-12-21 Thread Mark Engelberg
But if mk-counter is called twice because it's retried in part of a transaction, then you're in big trouble when you use atom. Better to use a ref here. atom needs to be reserved for the very few cases when retries don't matter (like a cache).

Re: How to encapsulate local state in closures

2008-12-21 Thread Stephen C. Gilardi
On Dec 21, 2008, at 7:24 PM, Brian Doyle wrote: I haven't been following the new atom stuff, so I was wondering why atom would be best in this situation, vs a ref? Thanks. The implementation of atoms is supported by the JVM typically using a processor hardware instruction that

Re: How to encapsulate local state in closures

2008-12-21 Thread Parth Malwankar
On Dec 22, 5:24 am, Brian Doyle brianpdo...@gmail.com wrote: I haven't been following the new atom stuff, so I was wondering why atom would be best in this situation, vs a ref?  Thanks. Rich discusses the use of atoms, refs and agents in good detail in this thread:

Re: How to encapsulate local state in closures

2008-12-21 Thread Parth Malwankar
On Dec 22, 5:45 am, Mark Engelberg mark.engelb...@gmail.com wrote: But if mk-counter is called twice because it's retried in part of a transaction, then you're in big trouble when you use atom.  Better to use a ref here.  atom needs to be reserved for the very few cases when retries don't

Re: How to encapsulate local state in closures

2008-12-21 Thread Mark Engelberg
I misspoke; it's the call to counter that's the problem. Let's say you want to use a counter to count the number of times a ref is set, something like this: (dosync (counter) (ref-set r 1)) If your var-set causes the transaction to retry, an atom-based counter will increment twice. As I