Re: Poll for a new name for clojure eclipse plugin 'clojure-dev'

2009-07-11 Thread Anand Patil

There's going to be a solar eclipse in a couple of weeks visible from
lots of places with great names: Varanasi, Darjeeling (has a j in it!)
and Surat, for example.

An alignment of three cosmic bodies is a syzygy.

Many eclipse cycles seem to have neat names:
http://www.phys.uu.nl/~vgent/eclipse/eclipsecycles.htm


On Sat, Jul 11, 2009 at 1:48 PM, beatle...@gmail.combeatle...@gmail.com wrote:

 I like Corona as well. Maybe taking it one little step further and
 turn it into Clorona, which has a more clojurish sound to it.

 On Jun 24, 1:47 am, Rayne disciplera...@gmail.com wrote:
 I vote Corona.
 


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



Re: Incanter classpath difficulties

2009-06-22 Thread Anand Patil
On Mon, Jun 22, 2009 at 2:41 AM, liebke lie...@gmail.com wrote:


 Hi Anand,

 Try changing the INCANTER_HOME variable in the clj script to the
 absolute path to the incanter directory, instead of a relative path,
 like ./ or ../

 Let me know if that doesn't work.


Hi David,
Didn't
work, unfortunately. I can still import the required class directly, but (use
'(incanter core)) fails.

Thanks again,
Anand

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



Re: Incanter classpath difficulties

2009-06-22 Thread Anand Patil
Hi David, no worries, thanks for trying. I'll let you know if I find a
solution.
Cheers
Anand

On Mon, Jun 22, 2009 at 1:41 PM, liebke lie...@gmail.com wrote:


 Anand, you've stumped me! You can import the class directly, but you
 can't load incanter.core because it can't import the class? I'm not
 sure what would cause that behavior, and I can't reproduce it.
 Whenever I encounter weird errors like this, I try rebooting. You
 might also try cloning incanter in a fresh directory and see it if has
 the same behavior. Sorry, I can't be more helpful.

 good luck,
 David



 On Jun 22, 4:43 am, Anand Patil anand.prabhakar.pa...@gmail.com
 wrote:
  On Mon, Jun 22, 2009 at 2:41 AM, liebke lie...@gmail.com wrote:
 
   Hi Anand,
 
   Try changing the INCANTER_HOME variable in the clj script to the
   absolute path to the incanter directory, instead of a relative path,
   like ./ or ../
 
   Let me know if that doesn't work.
 
  Hi David,
  Didn't
  work, unfortunately. I can still import the required class directly, but
 (use
  '(incanter core)) fails.
 
  Thanks again,
  Anand
 


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



Re: Incanter classpath difficulties

2009-06-22 Thread Anand Patil
OK, figured it out... the problem was I had copied incanter.clj to
/Library/Java/Extensions. When I removed that copy, everything worked as
expected. Weird, but I'm glad it's not happening anymore.
Anand

On Mon, Jun 22, 2009 at 1:52 PM, Anand Patil 
anand.prabhakar.pa...@gmail.com wrote:

 Hi David, no worries, thanks for trying. I'll let you know if I find a
 solution.
 Cheers
 Anand

 On Mon, Jun 22, 2009 at 1:41 PM, liebke lie...@gmail.com wrote:


 Anand, you've stumped me! You can import the class directly, but you
 can't load incanter.core because it can't import the class? I'm not
 sure what would cause that behavior, and I can't reproduce it.
 Whenever I encounter weird errors like this, I try rebooting. You
 might also try cloning incanter in a fresh directory and see it if has
 the same behavior. Sorry, I can't be more helpful.

 good luck,
 David



 On Jun 22, 4:43 am, Anand Patil anand.prabhakar.pa...@gmail.com
 wrote:
  On Mon, Jun 22, 2009 at 2:41 AM, liebke lie...@gmail.com wrote:
 
   Hi Anand,
 
   Try changing the INCANTER_HOME variable in the clj script to the
   absolute path to the incanter directory, instead of a relative path,
   like ./ or ../
 
   Let me know if that doesn't work.
 
  Hi David,
  Didn't
  work, unfortunately. I can still import the required class directly, but
 (use
  '(incanter core)) fails.
 
  Thanks again,
  Anand
 



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



Re: Clojure in Computing in Science and Engineering

2009-06-21 Thread Anand Patil
On Sat, Jun 20, 2009 at 11:29 AM, Jon Harrop j...@ffconsultancy.com wrote:


 The Task Parallel Library. It uses concurrent wait-free work-stealing
 queues
 to provide an efficient implementation of work items than can spawn other
 work items with automatic load balancing on shared memory machines. Cilk
 uses
 the same technology (well worth a look if you haven't already seen it!).
 That
 makes it easy to write efficient parallel algorithms in any .NET language.
 In
 particular, it can sustain billions of work items (as opposed to thousands
 of
 threads or processes) and the time taken to spawn is ~30,000x faster than
 forking a process. Extremely useful stuff!


Sounds similar to ForkJoin, which Rich pointed out to me a while ago:
http://www.ibm.com/developerworks/java/library/j-jtp11137.html

Anand

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



Incanter classpath difficulties

2009-06-21 Thread Anand Patil
Hi David and all,

Just trying to get up and running with Incanter, on a Mac with the github
head. The clj script doesn't find part of parallel colt:

(head-mac bin) ./clj
Clojure 1.1.0-alpha-SNAPSHOT
user= (use '(incanter core))
java.lang.NoClassDefFoundError:
cern/colt/matrix/tdouble/impl/DenseColDoubleMatrix2D (internal.clj:19)
user= (import cern.colt.matrix.tdouble.impl.DenseColDoubleMatrix2D)
java.lang.ClassNotFoundException:
cern.colt.matrix.tdouble.impl.DenseColDoubleMatrix2D (NO_SOURCE_FILE:2)
user=


When I change INCANTER_HOME=. to INCANTER_HOME=.. in the clj script, I can
import the required class but still not use Incanter:

(head-mac bin) ./clj
Clojure 1.1.0-alpha-SNAPSHOT
user= (import cern.colt.matrix.tdouble.impl.DenseColDoubleMatrix2D)
cern.colt.matrix.tdouble.impl.DenseColDoubleMatrix2D
user= (use '(incanter core))
java.lang.NoClassDefFoundError:
cern/colt/matrix/tdouble/impl/DenseColDoubleMatrix2D (internal.clj:19)
user=


The problem seems to be in the Matrix class:

user= (import incanter.Matrix)
java.lang.NoClassDefFoundError:
cern/colt/matrix/tdouble/impl/DenseColDoubleMatrix2D (NO_SOURCE_FILE:3)


Thanks in advance for any help,
Anand

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



Re: Clojure in Computing in Science and Engineering

2009-06-18 Thread Anand Patil
On Thu, Jun 18, 2009 at 5:48 PM, Konrad Hinsen konrad.hin...@laposte.netwrote:


 On 18.06.2009, at 16:47, psf wrote:

  That is funny... I put a little Clojure plug into the article entitled
  Trailblazing with Roadrunner in the very same issue of CiSE.

 Great minds think alike ;-)


 On 18.06.2009, at 18:16, Michel Salim wrote:

  Really neat -- hopefully there will be a follow-up that demonstrates
  Clojure's concurrency features (perhaps contrasting it with Haskell).

 The problem is that neither one is particularly well suited for the
 majority of scientific applications, which work best on distributed-
 memory machines. Of course this may change with the increasing number
 of cores-per-processor, shared-memory SMP may become fashionable
 again even for number crunching.

 Anyway, if anyone has a scientific (in the widest possible sense)
 application that exploits Clojure's currency, contact me if you want
 to write about it!


Great article, Konrad. Thanks for giving us something to email to
colleagues!

I've got something bubbling away on the back burner, but will let the
suspense build up a bit ;).

Anand

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



Re: Feedback on new persistentmatrix datatype

2009-05-18 Thread Anand Patil
On Sun, May 17, 2009 at 1:15 PM, Konrad Hinsen konrad.hin...@laposte.netwrote:


 On 16.05.2009, at 15:53, aperotte wrote:

  Yes Anand, I'm worried about that.  What I think the solution should
  be is to allow mutability in the implementation of algorithms in the
  java back end for the reasons you mentioned, but a clean immutable
  interface on the clojure side.  When users are faced with serious
  memory limitations, though, that could be a problem.  The question is
  whether that sacrifice is worth the cleanliness of immutability.

 A detailed explanation is given in Philip Wadler's paper Monads for
 functional programming (downloadable from http://
 homepages.inf.ed.ac.uk/wadler/topics/monads.html). The principle is
 to have a specialized version of the state monad in which the state
 is the array. The only way to get an array into the state is by
 creating a new one immediately as a state monad value (meaning there
 is no way to access the array otherwise). It can then be modified
 using a set of monadic expressions that can be combined arbitrarily.
 They guarantee that updates happen in the specified order without
 permitting any other access to the array, meaning that the updates
 can be made destructively without causing any problems.


Huh, sounds like just the thing. Security is going to be especially
difficult in Clojure, though. For example, say I stuck the array into a ref
from within the monad, then carried on overwriting it. A consumer who gets
the array out of the ref from another thread might get it while I'm still
mutating it.

Granted that would be a pretty stupid thing for me to do, but it would be
nice to guarantee immutability to consumers.

Anand

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



Re: Feedback on new persistentmatrix datatype

2009-05-18 Thread Anand Patil
On Mon, May 18, 2009 at 10:54 AM, Konrad Hinsen
konrad.hin...@laposte.netwrote:


 On May 18, 2009, at 11:21, Anand Patil wrote:

  Huh, sounds like just the thing. Security is going to be especially
  difficult in Clojure, though. For example, say I stuck the array
  into a ref from within the monad, then carried on overwriting it. A
  consumer who gets the array out of the ref from another thread
  might get it while I'm still mutating it.

 Here is an example of how this might look, using 1D Java arrays for
 simplicity:

 (def an-array
   (initalize-array Integer/TYPE 10
 [_ (set-element 0 1)
  x (get-element 0)
  _ (set-element 1 (inc x)]))


I understand better now, thanks. That seems pretty much ideal to me.

Anand

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



Re: Feedback on new persistentmatrix datatype

2009-05-15 Thread Anand Patil
On Sat, May 9, 2009 at 7:09 PM, aperotte apero...@gmail.com wrote:


 It shouldn't be a problem to maintain immutability and also perform a
 cross/cartesian product. I'm not sure I understand the problem.


It was a pretty bad example... what I meant was, in scientific computing,
people often have to take a deep breath and mutate because of speed or
memory limitations. It would be nice to be able to 'unlock' the immutability
somehow if you really need to.

Anand

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



Re: Feedback on new persistentmatrix datatype

2009-05-06 Thread Anand Patil
On Sat, May 2, 2009 at 11:19 PM, aperotte apero...@gmail.com wrote:


 Hello everyone,

 I just uploaded some of my work on a new datatype for clojure to a git
 repository.

 http://github.com/aperotte/persistentmatrix

 A bit of the rationale and motivation for the datatype is described on
 the github page.  I basically wanted to create a datastructure for
 manipulating large amounts of data efficiently and in a human friendly
 way in clojure.

 Its main features are:

   1. Immutability
   2. Primitive Support
   3. N-Dimensional – Arbitrary number and size of dimensions (ie.
 ability to create a 4×3×5x6 datastructure)
   4. N-Dimensional units (ie. ability to create a 10×10 matrix with
 2×1 units to represent complex numbers)
   5. Fast submatrix views via structural sharing (ie. constant time
 slicing, transposing, and other data manipulations)
   6. Maintenance of both deep and superficial dimensionality (ie.
 slicing a 4×3×5x6 along the 3rd dimension will yield a datastructure
 with a superficial dimensionality of 3 and a deep dimensionality of 4)
   7. Axis and element labeling and label indexing (ie. ability to
 label axes and elements of an axis with strings or any arbitrary
 object)
   8. Implementing many of the clojure interfaces and thereby
 automatically inheriting much of the functionality of the standard
 library for data structures.

 I would welcome any feedback.  Also, if anyone is interested in
 working together to accelerate its development, that would be welcome
 too!


Great work! I'm glad to see some numerical advances in Clojure.

I've got a couple of suggestions: first, you might want to follow numpy and
call n-dimensional arrays 'arrays', and reserve 'matrix' for 2d arrays. Or
not...

Second, immutability is definitely the right default, but it would be nice
to be able to create nonstandard arrays from Clojure somehow. For example,
say I wanted to compute the matrix (f (- x y)) over the Cartesian product of
vectors x and y.

Anand

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



Re: March 20th 2009 Rich Hickey Appreciation Day!

2009-03-22 Thread Anand Patil
Clojure's great, thanks very much for making it available  supporting it!
Anand

On Fri, Mar 20, 2009 at 6:26 PM, Rayne disciplera...@gmail.com wrote:


 I Anthony Simpson, with the support of fellow Clojurists hereby
 declare March 20th, the first day of spring, Rich Hickey appreciation
 day!

 Rich Hickey has certainly done a lot for us, making this wonderful
 language and continuing to take his time to work on it. He is
 dedicated and he wants to bring Clojure along with it's users to
 heights that Lisp has never been before. In just some 2 years, Rich
 has gathered together a vibrant and large community of users and
 contributors who believe in Clojure's future immensely . One such
 contributor who believes in Clojure enough to write an entire book on
 it! Clojure gains more attention and support everyday.

 I believe in the bright future that Rich Hickey believes exists for
 Clojure. I believe that with this community, and with such a wonderful
 creator as Rich Hickey, Clojure will achieve it's goals and meet the
 destiny that Rich is writing for it.

 I thank you Rich Hicky for all your work on Clojure. I thank you for
 all the time you've spent building this community and giving us one of
 the most awesome languages that have existed. Thank you for caring
 about us enough to listen to the community before making big changes,
 I believe in Clojure and I will be here watching it evolve with you!

 If you would like to thank Rich Hickey for all he has done for us, you
 can post in this thread, or tell him yourself in the #Clojure IRC
 channel. :)

 March 20th 2009 Rich Hickey Appreciation Day

 -Rayne
 


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



Re: Synchronous watches

2009-03-05 Thread Anand Patil
Excellent point. Yes, get-watches seems like a better option.
Anand

On Thu, Mar 5, 2009 at 3:33 AM, Timothy Pratley timothyprat...@gmail.comwrote:


 I forgot to mention the reason I don't feel it should be an error to
 remove a non-existent watch
 user= (dissoc {:a 1 :b 2} :c)
 {:a 1, :b 2}


 


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



Re: Synchronous watches

2009-03-05 Thread Anand Patil
I've managed to create weird race conditions by adding watches while actions
are running. Are there guarantees about the scheduling of actions and
adding/ removing watches? If I add or remove a watch on an agent while an
action is running, what happens?
So to summarize, my feedback that still may be sensible consists of this
question and a request for watches that respond to errors.

Thanks, Anand


On Thu, Mar 5, 2009 at 9:34 AM, Anand Patil anand.prabhakar.pa...@gmail.com
 wrote:

 Excellent point. Yes, get-watches seems like a better option.
 Anand


 On Thu, Mar 5, 2009 at 3:33 AM, Timothy Pratley 
 timothyprat...@gmail.comwrote:


 I forgot to mention the reason I don't feel it should be an error to
 remove a non-existent watch
 user= (dissoc {:a 1 :b 2} :c)
 {:a 1, :b 2}


 



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



Re: Metadata on functions

2009-03-04 Thread Anand Patil
On Wed, Mar 4, 2009 at 12:50 PM, Konrad Hinsen konrad.hin...@laposte.netwrote:


 Rich,

 is there a reason why metadata is explicitly disabled on function
 objects?

 I find myself wanting to put metadata on functions frequently. It
 seems even more important for functions than for anything else, given
 that there is no way to inspect a function object at all, it's a
 complete black box. So I looked at the implementation to see if it
 would be easy to add metadata handling, and found to my surprise that
 function objects already have a metadata pointer but that setting it
 is disabled.

 Two situations where I think metadata on functions would be very useful:

 - To put on a type tag. If functions are to be first-class data
 objects, it should be possible to have multimethods dispatching on a
 function argument. My concrete use case is stream-generating
 functions with different interfaces that I would like to use with a
 common interface defined as a multimethod.

 - For implementing automatic derivatives, it would be useful to
 attach a derivative function to a mathematical function such as log
 or sqrt.

 Konrad.


+1. Also, are there any plans to allow function introspection in the future?

Anand

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



Re: Synchronous watches

2009-03-04 Thread Anand Patil
On Wed, Mar 4, 2009 at 10:35 AM, Anand Patil 
anand.prabhakar.pa...@gmail.com wrote:


 Hi Rich,

 I like the flexibility of the new watches, but I'm missing a way to
 watch for errors. Currently, if an agent's action results in an error
 its watchers aren't even triggered.

 Thanks,
 Anand


Also, (remove-watch a key) fails to raise an error if a doesn't have any
watches associated with key.

Anand



 On Feb 27, 2:57 pm, Rich Hickey richhic...@gmail.com wrote:
  I've added (back)synchronouswatches(svn 1309+), which used to exist
  for agents, now for all reference types.
 
  (defn add-watch
 
Experimental.
 
Adds a watch function to an agent/atom/var/ref reference. The watch
fn must be a fn of 4 args: a key, the reference, its old-state, its
new-state. Whenever the reference's state might have been changed,
any registeredwatcheswill have their functions called. The watch
  fn
will be called synchronously, on the agent's thread if an agent,
before any pending sends if agent or ref. Note that an atom's or
ref's state may have changed again prior to the fn call, so use
old-state rather than derefing the reference. Note also that watch
  fns
may be called from multiple threads simultaneously. Var watchers are
triggered only by root binding changes, not thread-local set!s
 
   [reference key fn] ...)
 
  (defn remove-watch [reference key]...)
 
  I've left in add/remove-watcher for now, in order to avoid disruption.
  It is defined in terms of add-watch, demonstrating add-watch is the
  more flexible core function. My plan is to remove add-watcher/remove-
  watcher, since you can build your own such variants.
 
  Highlights are:
 
  - Deterministic times when callbacks will occur.
 
  - Provision of before/after state - you determine what constitutes an
  interesting change.
 
  - Arbitrary key will be passed back to callback.
 
  Please try them out for your latest Cells-like and other reactive
  programs. I'd like to move this out of the experimental category.
 
  Feedback and questions welcome,
 
  Rich
 


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



Re: So what do we want for a Cells-alike ?

2009-03-03 Thread Anand Patil

On Mar 3, 1:04 pm, Rich Hickey richhic...@gmail.com wrote:
 I think it is important to embrace asynchrony and concurrency as
 Clojure does. Any Cells-for-Clojure that presumes the world is a
 single synchronous chain of events would be a misfit. The whole notion
 of a 'current step' is suspect.

I'd appreciate it if my asynchronous lazy cells got a look, as I've
given them a few revisions now. They're at 
http://github.com/onyin/lazy-agent/tree.
They don't have any global counter, but the diamond pattern is no
problem for them. As noted in an earlier thread, my def-cell macro is
not as nice as it could be, but it wouldn't be hard for someone who is
good at macros to write a quick wrapper.

The readme:

Implements two types of agent-based 'cells' for Clojure: lazy agents
and oblivious agents. These complement the auto-agents available in
Clojure Contrib. Both allow for concurrent cell updates with
respectably efficient scheduling and avoid unnecessarily repeating
cell updates.

If you deref a lazy cell, you'll see a map: {:value xxx :status
yyy}. :status may be :needs-update, :updating, :up-to-date
or :oblivious. If a cell is up-to-date or oblivious, :value gives the
value of the cell.

When a lazy agent's ancestor changes, its value changes to {:value
nil :status :needs-update} but it does not compute its new value until
it receives a message instructing it to do so. To send the update
message to a group of agents, do (update a b c d e). To send the
update message and wait for the values, do (evaluate a b c d e).

Oblivious agents are even lazier than lazy agents. When an oblivious
agent is up-to-date, its status is :oblivious. If an ancestor
subsequently changes, the oblivious agent will not do anything. It
needs to receive a 'force-need-update' message to change state to
{:value nil :status :needs-update}, but then it starts watching its
parents for changes like a lazy agent until it computes.

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



Re: So what do we want for a Cells-alike ?

2009-03-03 Thread Anand Patil



On Mar 3, 3:22 pm, Raffael Cavallaro raffaelcavall...@gmail.com
wrote:
 On Mar 3, 8:04 am, Rich Hickey richhic...@gmail.com wrote:

   If B and C depend on A in such
  a way that their values must be coordinated in order to be valid and
  consistent, then maybe they shouldn't independently depend on A,
  instead a transaction should fire on changes to A, which in turn
  updates B and C. Then any downstream consumers of B and C could never
  see inconsistent values, all without a notion of 'current step'.

 Certainly you can and should hide the notion of current step for
 *most* purposes. Using transactions is certainly a good way to do it;
 but you must expose it in some way or you won't be able to express the
 full range of dataflow models.

 Typically:

 ;; pseudocode

 (defmodel my-model
    (a :independent)
    (b (fn [a] (+ (* a 12) 3)))
    (c (fn [a] (+ a 7)))
    (d (fn [c b] (* c d 3.2

 Here the step is implicit, as each reference to another cell in the
 functions above really means the value of that cell at the *same*
 step/time/data pulse.  However:

 1.  failing to deal with this issue in the *implementation* of a
 dataflow
 library leads to the wrong semantics; the absence of this notion or
 any other means of dealing with it, (such as a transaction as you
 suggest)
 commonly leads to bugs in cells-alikes, including at least one clojure
 implementation.

 2. there are certain types of models where one needs to be able to
 refer to previous pulses/steps. These include reflexive update
 functions, (where the value of a cell depends on its own value at some
 previous step/time/pulse), and time lags. With these types of
 dependencies, there must be some way to explicitly refer to step or
 pulse:

 ;pseudocode with time lag

 ((defmodel my-model
    (a :independent)
    (b (fn [a] (previous a 3))) ;; i.e., how many steps back
    (c (fn [a] (+ a 7)))
    (d (fn [c d] (* c d 3.2

 You can certainly hide the most common case (i.e., everything is at
 the same
 step/pulse), but it has to be there internally or the semantics will
 be
 wrong, and it has to be exposed in some way or you won't be able to
 express many interesting types of models in a simple, direct way.

Laziness can work like a step counter, too. When you update a group of
the lazy cells in my previous post, you cause a single data pulse.
Cells don't update until all of their parents have reported in, ie
reached the current step.

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



Re: Making agents able to temporarily yield place on thread pool

2009-03-02 Thread Anand Patil

On Mar 2, 1:16 am, MikeM michael.messini...@invista.com wrote:
 Not sure if I understand what you need, but could you build on the
 existing capability to send to the current agent: (send *agent* ...) ?
 You could have the agent send to itself, then exit the function with
 some work left to do that would be restarted on the next go-around.

I could get away with sending to b with instructions to send back to
a... the yield suggestion was just syntactic sugar for doing that.

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



Re: Making agents able to temporarily yield place on thread pool

2009-03-02 Thread Anand Patil



On Mar 1, 10:58 pm, Rich Hickey richhic...@gmail.com wrote:
 On Mar 1, 2009, at 1:53 PM, Anand Patil wrote:
 I've made futures use the Agents' CachedThreadPool, which should  
 prevent the thread pool exhaustion (svn 1316). You shouldn't worry  
 about the expense of the threads, that's why there's a pool.

 Yield as you've described it is definitely not going to happen.

Rich,

If you'll bear with me a bit longer- what if I set breadth=1000 and
depth=1000 in the program above. The thread pool would have to grow by
thousands to avoid a deadlock, whereas with something like yield it
could stay alive using only the standard, fixed-size thread pool.

Anand

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



Re: Making agents able to temporarily yield place on thread pool

2009-03-02 Thread Anand Patil



On Mar 2, 12:48 pm, Rich Hickey richhic...@gmail.com wrote:
 On Mar 2, 2009, at 5:15 AM, Anand Patil wrote:


  On Mar 1, 10:58 pm, Rich Hickey richhic...@gmail.com wrote:
  On Mar 1, 2009, at 1:53 PM, Anand Patil wrote:
  I've made futures use the Agents' CachedThreadPool, which should
  prevent the thread pool exhaustion (svn 1316). You shouldn't worry
  about the expense of the threads, that's why there's a pool.

  Yield as you've described it is definitely not going to happen.

  Rich,

  If you'll bear with me a bit longer- what if I set breadth=1000 and
  depth=1000 in the program above. The thread pool would have to grow by
  thousands to avoid a deadlock, whereas with something like yield it
  could stay alive using only the standard, fixed-size thread pool.

 I understand the problem and there is already a solution - it's called  
 the Fork/Join framework, and you can use it easily from Clojure:

 http://www.ibm.com/developerworks/java/library/j-jtp11137.htmlhttp://gee.cs.oswego.edu/dl/concurrency-interest/index.html

Good to know- I'll have a look at Fork/Join.

Thanks,
Anand
--~--~-~--~~~---~--~~
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
-~--~~~~--~~--~--~---



Re: Making agents able to temporarily yield place on thread pool

2009-03-02 Thread Anand Patil

On Mar 2, 2:34 pm, Anand Patil anand.prabhakar.pa...@gmail.com
wrote:
 On Mar 2, 12:48 pm, Rich Hickey richhic...@gmail.com wrote:
  On Mar 2, 2009, at 5:15 AM, Anand Patil wrote:
   On Mar 1, 10:58 pm, Rich Hickey richhic...@gmail.com wrote:
   If you'll bear with me a bit longer- what if I set breadth=1000 and
   depth=1000 in the program above. The thread pool would have to grow by
   thousands to avoid a deadlock, whereas with something like yield it
   could stay alive using only the standard, fixed-size thread pool.

  I understand the problem and there is already a solution - it's called  
  the Fork/Join framework, and you can use it easily from Clojure:

 http://www.ibm.com/developerworks/java/library/j-jtp11137.htmlhttp://...

 Good to know- I'll have a look at Fork/Join.

OK, ForkJoin really does solve exactly that problem. Nice. Out of
curiosity, what's your vision for how ForkJoin would ideally
interoperate with Clojure's own agents and futures? Specifically,
would they share a thread pool, and would the availability of ForkJoin
actually change the behavior of agents and futures at all?

Thanks,
Anand
--~--~-~--~~~---~--~~
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
-~--~~~~--~~--~--~---



Making agents able to temporarily yield place on thread pool

2009-03-01 Thread Anand Patil

Hi all,

My concurrent dabblings in Clojure have been a real pleasure so far.
In terms of concurrency, it's just in a completely different league
from any other language I've tried. However, I think agents could be
made even more friendly by allowing them to temporarily surrender
their place in the thread pool pending another computation.

Specifically, I'm thinking of a function 'yield' called as (yield
other-agent msg-fn args) from within agent actions. If agent a yields
to agent b, a gets off the thread pool and msg is sent to b with given
args. When b finishes executing the message, the yield call returns
b's new value, and a gets back on the thread pool.

I _think_ the language could prevent deadlocks by:
- making agents not take any messages while they are 'yielded'
- keeping a 'yield stack' and checking that no cycles happen.

Here are two use cases for yield:

1) Say an 'auto-agent' cell needs to run an expensive, parallelizable
computation to update its value. Without yield you could do this by
dispatching the action with send-off, or by splitting the cell up into
multiple cells, each handling a chunk of the computation. Yield would
be nicer than both: send-off spawns an expensive kernel thread (as I
understand it) and breaking up the cell complicates the dataflow model
unnecessarily.

2) Currently this program, which creates a tree of dependent futures,
deadlocks on my 8-core mac pro:

(def breadth 4)

(defn with-deref [fun]
(fn [ x] (apply fun (map deref x

(defn future-tree [depth]
(if (= depth 0) (future 1)
(let [new-futures (map future-tree (repeat breadth (- depth
1)))]
(future (apply (with-deref +)  new-futures)

; WARNING: This deadlocks on 8-core Mac Pro!
(future-tree 4)

I'm guessing it deadlocks because the thread pool fills up with
futures that aren't ready to go, but it feels like the language should
be able to avoid the deadlock without requiring the programmer to
think about how many threads are actually in the thread pool. If
futures were based on agents, which yielded when deref-ing other
futures, the deadlock wouldn't happen.

I have no idea how hard it would be to implement yield, as I have very
little practice with Java. Thoughts?

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



Re: Synchronous watches

2009-02-27 Thread Anand Patil

Hi Rich,

On Feb 27, 2:57 pm, Rich Hickey richhic...@gmail.com wrote:
 I've added (back) synchronous watches (svn 1309+), which used to exist
 for agents, now for all reference types.

 (defn add-watch

   Experimental.

   Adds a watch function to an agent/atom/var/ref reference. The watch
   fn must be a fn of 4 args: a key, the reference, its old-state, its
   new-state.

Could you say more about the key? Who gets to decide what it is, and
what does it mean?

Thanks,
Anand
--~--~-~--~~~---~--~~
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
-~--~~~~--~~--~--~---



Re: Synchronous watches

2009-02-27 Thread Anand Patil

Never mind, I get it now.

Thanks,
Anand

On Feb 27, 4:32 pm, Anand Patil anand.prabhakar.pa...@gmail.com
wrote:
 Hi Rich,

 On Feb 27, 2:57 pm, Rich Hickey richhic...@gmail.com wrote:

  I've added (back) synchronous watches (svn 1309+), which used to exist
  for agents, now for all reference types.

  (defn add-watch

    Experimental.

    Adds a watch function to an agent/atom/var/ref reference. The watch
    fn must be a fn of 4 args: a key, the reference, its old-state, its
    new-state.

 Could you say more about the key? Who gets to decide what it is, and
 what does it mean?

 Thanks,
 Anand
--~--~-~--~~~---~--~~
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
-~--~~~~--~~--~--~---



Richer 'partial'

2009-02-26 Thread Anand Patil

Hi all,

I could use a version of 'partial' that would allow me to:

- Partially apply a function to any of its arguments, not just the
first one
- 'Unapply' a partially-applied function from one of its arguments.

Is any such thing already available?

Thanks,
Anand
--~--~-~--~~~---~--~~
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
-~--~~~~--~~--~--~---



Re: Richer 'partial'

2009-02-26 Thread Anand Patil

Thanks for the responses, guys.

 - Partially apply a function to any of its arguments, not just the
 first one

That's already the case, haven't you made a little test ?

I meant I want to apply it out of sequence, sorry.

 You can easily partially apply to other arguments by doing this: #(fred %1
 some-arg %2 other-arg).

That makes sense, thanks, though it's not any easier to unapply than
partial. I guess I could make a new 'partial-like' function that
returns code to apply a function, with nil's in unapplied argument
slots... ?

 Not possible as far as I know. Could you please explain use cases you have
 in mind for such a feature ?

Sure, it's the lazy cells I've been working on. When a cell's parent
changes, I don't want it to compute right away- I want it to register
the fact that the parent has changed, switch to an 'unevaluated'
state, and 'unapply' its childrens' update functions on itself.

I won't explain how I'm doing it right now for fear of muddying the
waters, but it feels overcomplicated and un-idiomatic.

Thanks,
Anand
--~--~-~--~~~---~--~~
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
-~--~~~~--~~--~--~---



Re: Richer 'partial'

2009-02-26 Thread Anand Patil

Thanks for the responses, guys.

 - Partially apply a function to any of its arguments, not just the
 first one

That's already the case, haven't you made a little test ?

I meant I want to apply it out of sequence, sorry.

 You can easily partially apply to other arguments by doing this: #(fred %1
 some-arg %2 other-arg).

That makes sense, thanks, though it's not any easier to unapply than
partial. I guess I could make a new 'partial-like' function that
returns code to apply a function, with nil's in unapplied argument
slots... ?

 Not possible as far as I know. Could you please explain use cases you have
 in mind for such a feature ?

Sure, it's the lazy cells I've been working on. When a cell's parent
changes, I don't want it to compute right away- I want it to recognize
the new value, but switch to an un-evaluated state. Since the cell has
no value, it would be nice if its children could just un-apply their
update functions on it.

I won't explain how I'm doing it right now for fear of muddying the
waters, but it feels overcomplicated and un-idiomatic.

Thanks,
Anand

On Feb 26, 4:00 pm, Laurent PETIT laurent.pe...@gmail.com wrote:
 2009/2/26 Jeffrey Straszheim straszheimjeff...@gmail.com

  partial is a currying function.  It can be provided any number of
  parameter(s), but it is always behaves sequentially from start to finish.
   That is what currying *is*.

 Ah, I thought currying / uncurrying what the term reserved for this
 operation (as I remember from Haskell) that changes the arity of functions (
 transforming and untransforming a function of n parameters into a function
 of a tuple of n elements) ?



  You can easily partially apply to other arguments by doing this: #(fred %1
  some-arg %2 other-arg).

  partial could not easily support unapplying it.

  On Thu, Feb 26, 2009 at 10:24 AM, Anand Patil 
  anand.prabhakar.pa...@gmail.com wrote:

  Hi all,

  I could use a version of 'partial' that would allow me to:

  - Partially apply a function to any of its arguments, not just the
  first one
  - 'Unapply' a partially-applied function from one of its arguments.

  Is any such thing already available?

  Thanks,
  Anand
--~--~-~--~~~---~--~~
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
-~--~~~~--~~--~--~---



Re: Richer 'partial'

2009-02-26 Thread Anand Patil

Sorry, I thought I had pushed 'stop' in time to stop the first
response.

On Feb 26, 4:16 pm, Anand Patil anand.prabhakar.pa...@gmail.com
wrote:
 Thanks for the responses, guys.

  - Partially apply a function to any of its arguments, not just the
  first one
 That's already the case, haven't you made a little test ?

 I meant I want to apply it out of sequence, sorry.

  You can easily partially apply to other arguments by doing this: #(fred %1
  some-arg %2 other-arg).

 That makes sense, thanks, though it's not any easier to unapply than
 partial. I guess I could make a new 'partial-like' function that
 returns code to apply a function, with nil's in unapplied argument
 slots... ?

  Not possible as far as I know. Could you please explain use cases you have
  in mind for such a feature ?

 Sure, it's the lazy cells I've been working on. When a cell's parent
 changes, I don't want it to compute right away- I want it to recognize
 the new value, but switch to an un-evaluated state. Since the cell has
 no value, it would be nice if its children could just un-apply their
 update functions on it.

 I won't explain how I'm doing it right now for fear of muddying the
 waters, but it feels overcomplicated and un-idiomatic.

 Thanks,
 Anand

 On Feb 26, 4:00 pm, Laurent PETIT laurent.pe...@gmail.com wrote:

  2009/2/26 Jeffrey Straszheim straszheimjeff...@gmail.com

   partial is a currying function.  It can be provided any number of
   parameter(s), but it is always behaves sequentially from start to finish.
    That is what currying *is*.

  Ah, I thought currying / uncurrying what the term reserved for this
  operation (as I remember from Haskell) that changes the arity of functions (
  transforming and untransforming a function of n parameters into a function
  of a tuple of n elements) ?

   You can easily partially apply to other arguments by doing this: #(fred %1
   some-arg %2 other-arg).

   partial could not easily support unapplying it.

   On Thu, Feb 26, 2009 at 10:24 AM, Anand Patil 
   anand.prabhakar.pa...@gmail.com wrote:

   Hi all,

   I could use a version of 'partial' that would allow me to:

   - Partially apply a function to any of its arguments, not just the
   first one
   - 'Unapply' a partially-applied function from one of its arguments.

   Is any such thing already available?

   Thanks,
   Anand
--~--~-~--~~~---~--~~
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
-~--~~~~--~~--~--~---



Re: Richer 'partial'

2009-02-26 Thread Anand Patil



On Feb 26, 4:41 pm, mikel mev...@mac.com wrote:
 Other people have explained currying and partial application, and why
 it doesn't normally spply the feature you want.

I'd be interested in reading about this if you know of a link.

 Normally, in a lnaguage that supplies partial application, the way to
 achieve the effect you want is to use combinators that change the
 order of arguments.

OK, that sounds like a clean functional way to do it. Thanks.

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



Re: How to get rid of reflection warning from countdown latch?

2009-02-24 Thread Anand Patil

Thanks Miʃel,

On Feb 23, 10:15 pm, Michel Salim michel.syl...@gmail.com wrote:

 What's the object on which .countDown is called? You need to find
 where it's first declared and give it a type annotation.


It's created here:

let [
  latch (java.util.concurrent.CountDownLatch. n)
  ...

Sorry if I'm being dense, but do you mean I should annotate it in the
arguments list of the function where it's used, like so:

(defn unlatching-watcher [#^java.util.concurrent.CountDownLatch latch
cell cell-updated?]
A watcher function that decrements a latch when a cell updates.
(if cell-updated?
(if (not (:updating @cell))
(.countDown latch

or annotate in when it's actually created? If the latter, what's the
syntax for that?

Thanks,
Anand

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



Re: How to get rid of reflection warning from countdown latch?

2009-02-24 Thread Anand Patil

On Feb 24, 1:32 pm, Michel Salim michel.syl...@gmail.com wrote:
 On Tue, Feb 24, 2009 at 4:44 AM, Anand Patil

 anand.prabhakar.pa...@gmail.com wrote:

  Thanks Miʃel,

  On Feb 23, 10:15 pm, Michel Salim michel.syl...@gmail.com wrote:

  What's the object on which .countDown is called? You need to find
  where it's first declared and give it a type annotation.

  It's created here:

  let [
           latch (java.util.concurrent.CountDownLatch. n)
           ...

  Sorry if I'm being dense, but do you mean I should annotate it in the
  arguments list of the function where it's used, like so:

  (defn unlatching-watcher [#^java.util.concurrent.CountDownLatch latch
  cell cell-updated?]
     A watcher function that decrements a latch when a cell updates.
     (if cell-updated?
         (if (not (:updating @cell))
             (.countDown latch

  or annotate in when it's actually created? If the latter, what's the
  syntax for that?

 I was unclear in my hint, apologies. You need a type hint in the
 function that takes a CountDownLatch, otherwise Clojure would not know
 what it is until you try to call a method on it (and it has to do
 reflection)

 Annotating in the arguments list, as you showed in the example, is
 fine. This way, you only annotate once for the entire function (I
 didn't know you can do (.method #^classname foo) before, actually,
 that was neat)

Thanks for the help!

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



How to get rid of reflection warning from countdown latch?

2009-02-23 Thread Anand Patil

Hi all,

I'm getting

Reflection warning, line: 150 - reference to field countDown can't be
resolved.

from

(if cell-updated?
(if (not (:updating @cell))
(.countDown latch

Is there any way to get rid of it?

Thanks,
Anand
--~--~-~--~~~---~--~~
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
-~--~~~~--~~--~--~---



Re: How to get rid of reflection warning from countdown latch?

2009-02-23 Thread Anand Patil

This blind stab worked... is it correct?

(if cell-updated?
(if (not (:updating @cell))
(.countDown #^java.util.concurrent.CountDownLatch
latch

Thanks,
Anand

On Feb 23, 5:20 pm, Anand Patil anand.prabhakar.pa...@gmail.com
wrote:
 Hi all,

 I'm getting

 Reflection warning, line: 150 - reference to field countDown can't be
 resolved.

 from

     (if cell-updated?
         (if (not (:updating @cell))
             (.countDown latch

 Is there any way to get rid of it?

 Thanks,
 Anand
--~--~-~--~~~---~--~~
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
-~--~~~~--~~--~--~---



Re: Feedback sought on yet another cells implementation!

2009-02-22 Thread Anand Patil

Hi Tim, thanks for the feedback!


On Feb 21, 11:16 am, Timothy Pratley timothyprat...@gmail.com wrote:
 (1) auto-agents by SS in contrib has a more convenient syntax [maybe
 you can mimic it]

Agreed, it is nicer. At the moment 'def-cell' is already a stretch for
me, but maybe someday I'll get there. :)

 (2) I can add a watcher to one of your cells - it wont do anything
 unless evaluate is called. I can see the advantage of not calculating
 needlessly, but if it is not going to be updated dynamically it is a
 bit misleading to allow watchers.

The cell changes to {:needs-update true} as soon as one of its
ancestors changes (plus the time it takes for the messages to
propagate). Watchers could make use of that information, no?

 (3) I don't see the need for agents and watcher for lazy cells, after
 all can't they just be formula which are evaluated/updated in the
 correct order? I have a feeling this would be more efficient (seeing
 that is your goal).

It's the concurrency. If you have a cell setup like

(def a (agent 0))
(def-cell b fn [a])
(def-cell c fn [a])

the agent-based implementation allows b and c can update concurrently,
whereas if they were just formulas they would of course have to update
sequentially. Or do you have some clever use of pmap in mind?

Either way, I'm planning on using this for cells whose update
functions involve reasonably heavy number-crunching, so I'm hoping
that the concurrency will be worth the overhead it requires.

However the overhead in my implementation is admittedly substantial...
I couldn't figure out a way to keep the number of updates to a minimum
yet keep the updates concurrent that required less than two watchers
per cell.

 (4) Both lazy and watchable cells are useful.

Good point... and come to think of it, there's no reason why these
cells shouldn't be able to mix with Stuart Sierra's auto-agents, given
that they're both just agents with watchers.

 (5) id? could be just:  instance? IDeref x   unless I'm missing
 something

Thanks for the tip!

 (6) case macro - not used in the code, and doesn't cond suffice?

You're right, as of version two case is officially cruft, and anyway
cond does the same job. No problem, it was good macro practice. :-)

That was very helpful, I appreciate it! Please pass along any other
thoughts on this.

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



Re: Feedback sought on yet another cells implementation!

2009-02-21 Thread Anand Patil

Hi all,

My second attempt is lazy-cells.clj in this group's files. The cells
are actual agents rather than ugly maps, and all the information about
parents is hidden in watchers.

If you change a cell, the cells that depend on it all change their
values to {:needs-update true}. You can subsequently tell cells a b c
d e to update by calling (update a b d c e), which will change their
values to {:needs-update true :updating true} and eventually an actual
value. To wait for and get the results, do (evaluate a b c d e).

The updates should (hopefully) be as economical as in the first
version.

Thanks,
Anand


On Feb 19, 6:46 pm, Anand Patil anand.prabhakar.pa...@gmail.com
wrote:
 Hi all,

 I would really appreciate some comments and criticism on 
 mycellsimplementation, which I've uploaded to this group's files as
 dataflow.clj . My goal was to fully exploit the available concurrency,
 but not do any unnecessary cell evaluations.

 My solution is lazy rather than push-based; if you change a ref 
 thatcellsdepend on, nothing happens to thecellsuntil you actually ask
 for their values. If you call

     (evaluate [cell1 cell2 cell3 ...])

 first cell1, cell2, cell3, ... and all their ancestors have their
 values set to {:updating}, and the rootcellsof the computation (all
 ancestors of cell1 etc. whose parents are non-cell identities like
 refs) are identified. Then, messages are sent to the rootcells
 telling them to recompute their values.

 Each time a cell p is able to compute its value, it sends a message to
 each of its children c that needs to update. The message extends c's
 value, which is a map, with the key and value {p (p's value)}. If c
 has received reports from all its cell parents, it retrieves values of
 its non-cell parents, computes its value, and reports to its children.
 When cell1, cell2, cell3 ... are all able to compute, the computation
 is over. You can optionally call

     (sync-evaluate [cell1 cell2 cell3 ...])

 which blocks until the computation finishes using a Java countdown
 latch.

 This approach (I think) guarantees that each cell recomputes at most
 once per computation. This helps certain models perform much better
 than with push-basedcells. For example, think about m generations of
 ncellseach, where every cell in a generation is a parent of every
 cell in the next generation. Say all the rootcellsdepend on a single
 ref. If you change the value of the ref, all nmcellsneed to update.
 If you do it with pushes, you first have to update all the rootcells,
 for n updates. Then each root cell pushes to all of its children, for
 n^2 updates. You end up doing waaay more than nm updates.

 You could update the generations sequentially to get back to good
 performance... but I feel like my approach will incur less overhead
 than finding all of the generations.

 The example in the testing section of dataflow.clj is less dramatic.
 The dependency graph, with - pointing from parents to child, is:

 a b - c
 a c - d
 a - e
 c e - f

 The roots are a and b, and each update function takes 1s.

 With myimplementation, it runs in 3s with 6 updates:
 - a and b update together
 - c and e update together
 - d and f update together

 whereas if you were using a push-based scheme I think it would take 4s
 with 9 updates. It would take 4s because:
 - a and b update together
 - c has to update twice in sequence, once in response to a and once in
 response to b
 - d and f have to update together in response to c's final update.

 Myimplementationruns the test, but:
 - It's pretty ugly,
 - I'd eventually like it to be fast  am sure it's nowhere near its
 potential,
 - I feel like I'm not taking full advantage of the language.

 After the basic idea gets some scrutiny, I'd like to include a system
 for handling exceptions. I'll also make thecellsmaintain caches
 keyed by their non-cell ancestors. This will save a lot of
 coordination overhead in addition to actual computation because if you
 evaluate a cell twice in a row it won't have to bother its cell
 ancestors at all the second time.

 I haven't given much thought to circular dependencies, because I don't
 currently need them.

 Thanks very much!

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



Feedback sought on yet another cells implementation!

2009-02-19 Thread Anand Patil

Hi all,

I would really appreciate some comments and criticism on my cells
implementation, which I've uploaded to this group's files as
dataflow.clj . My goal was to fully exploit the available concurrency,
but not do any unnecessary cell evaluations.


My solution is lazy rather than push-based; if you change a ref that
cells depend on, nothing happens to the cells until you actually ask
for their values. If you call

(evaluate [cell1 cell2 cell3 ...])

first cell1, cell2, cell3, ... and all their ancestors have their
values set to {:updating}, and the root cells of the computation (all
ancestors of cell1 etc. whose parents are non-cell identities like
refs) are identified. Then, messages are sent to the root cells
telling them to recompute their values.

Each time a cell p is able to compute its value, it sends a message to
each of its children c that needs to update. The message extends c's
value, which is a map, with the key and value {p (p's value)}. If c
has received reports from all its cell parents, it retrieves values of
its non-cell parents, computes its value, and reports to its children.
When cell1, cell2, cell3 ... are all able to compute, the computation
is over. You can optionally call

(sync-evaluate [cell1 cell2 cell3 ...])

which blocks until the computation finishes using a Java countdown
latch.


This approach (I think) guarantees that each cell recomputes at most
once per computation. This helps certain models perform much better
than with push-based cells. For example, think about m generations of
n cells each, where every cell in a generation is a parent of every
cell in the next generation. Say all the root cells depend on a single
ref. If you change the value of the ref, all nm cells need to update.
If you do it with pushes, you first have to update all the root cells,
for n updates. Then each root cell pushes to all of its children, for
n^2 updates. You end up doing waaay more than nm updates.

You could update the generations sequentially to get back to good
performance... but I feel like my approach will incur less overhead
than finding all of the generations.


The example in the testing section of dataflow.clj is less dramatic.
The dependency graph, with - pointing from parents to child, is:

a b - c
a c - d
a - e
c e - f

The roots are a and b, and each update function takes 1s.

With my implementation, it runs in 3s with 6 updates:
- a and b update together
- c and e update together
- d and f update together

whereas if you were using a push-based scheme I think it would take 4s
with 9 updates. It would take 4s because:
- a and b update together
- c has to update twice in sequence, once in response to a and once in
response to b
- d and f have to update together in response to c's final update.


My implementation runs the test, but:
- It's pretty ugly,
- I'd eventually like it to be fast  am sure it's nowhere near its
potential,
- I feel like I'm not taking full advantage of the language.

After the basic idea gets some scrutiny, I'd like to include a system
for handling exceptions. I'll also make the cells maintain caches
keyed by their non-cell ancestors. This will save a lot of
coordination overhead in addition to actual computation because if you
evaluate a cell twice in a row it won't have to bother its cell
ancestors at all the second time.

I haven't given much thought to circular dependencies, because I don't
currently need them.


Thanks very much!

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



Pmapping force over treed delays

2009-02-08 Thread Anand Patil

Hi all,

Say I have a collection of delays, some of which need to get others'
values in order to compute (there are no cyclic dependencies). If I
just pmap force over the entire collection, do I run the risk of
filling up a thread pool with operations that aren't ready to go yet?
Would it be better to represent the collection as a tree-seq and then
pmap force over that?

Many thanks,
Anand
--~--~-~--~~~---~--~~
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
-~--~~~~--~~--~--~---



Discarding entire transactions

2009-02-08 Thread Anand Patil

Hello again,

In my application, I'll frequently want to quickly discard all the
changes made during a transaction involving many refs. I don't want to
force the refs to roll back to their values at the beginning of the
transaction, I just want to end the transaction immediately and skip
the write stage; updates made in other transactions should still
'stick'. What's the most efficient way to do this?

Thanks again!
Anand
--~--~-~--~~~---~--~~
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
-~--~~~~--~~--~--~---



Re: Discarding entire transactions

2009-02-08 Thread Anand Patil

On Feb 8, 7:29 pm, Shawn Hoover shawn.hoo...@gmail.com wrote:
 On Sun, Feb 8, 2009 at 12:23 PM, Anand Patil 

 anand.prabhakar.pa...@gmail.com wrote:

  Hello again,

  In my application, I'll frequently want to quickly discard all the
  changes made during a transaction involving many refs. I don't want to
  force the refs to roll back to their values at the beginning of the
  transaction, I just want to end the transaction immediately and skip
  the write stage; updates made in other transactions should still
  'stick'. What's the most efficient way to do this?

  Thanks again!
  Anand

 You can abort a transaction by throwing an exception, but in that case all
 refs automatically retain their pre-transaction values. You can't partially
 roll back a transaction, because by definition all changes to refs in a
 transaction occur or none do.

 By the way, what do you mean by other transactions?
   - Transactions running on other threads? Aborting in one thread does not
 affect refs in other threads.
   - Transactions that completed earlier in time on the same thread? Those
 values are not affected by aborting a later transaction.
   - dosync calling dosync on the same on the same thread? Aborting from an
 inner dosync aborts the whole stack of dosyncs in that thread.

I think your first response covers my case. Here's an example of what
I mean:

(def a (ref 1))
(def b (ref 1))

; Do these concurrently, either from separate agents or using pmap
(dosync (commute b error-throwing-fn a))
(dosync (commute a + @b))

I want to have the option to abort the first transaction without
rolling back the second. Based on what you said, if the first
transaction is aborted but the second is not then no matter what a's
value will be 2 and b's value will be 1, correct?

Thanks for the replies,
Anand
--~--~-~--~~~---~--~~
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
-~--~~~~--~~--~--~---



Re: Possible bug in preduce

2009-02-04 Thread Anand Patil



On Feb 3, 11:09 pm, Rich Hickey richhic...@gmail.com wrote:
 On Feb 3, 4:43 pm, Anand Patil anand.prabhakar.pa...@gmail.com
 wrote:

 No, it's not. as the docs for preduce say:http://clojure.org/api#preduce

 Also note that (f base an-element) might be performed many times

 in fact, an arbitrary number of times depending on how many parallel
 tasks are fired up. So, the function with base value should produce an
 identity, e.g. (+ 0 x) and (* 1 x), and your q with 0 does not.

Ah, thanks. I interpreted the docs as meaning preduce might do this:

(q (q (q 2 0) (q 3 0)) (q 1 0))

meaning (f base an-element) is performed many times, but just once per
an-element. I didn't understand that f with base needed to be an
identity.

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



Re: Stupid Java questions

2009-02-04 Thread Anand Patil

I agree  don't mean to complain. I'm just flagging the issues to make
it easier for whoever goes through the docs after clojure 1.0 is
tagged.

Anand

On Feb 4, 9:45 am, Zak Wilson zak.wil...@gmail.com wrote:
 The namespace is correct on clojure.org/api, but there it doesn't
 mention that it has a dependency that isn't included with Clojure.

 Clojure has been evolving very quickly, and sometimes the website
 doesn't keep up. It might be nice if somebody could take charge of
 making sure the site is up to date, but right now I'd rather keep
 being thrilled by the fact that the feature I find myself needing
 today was just added yesterday.
--~--~-~--~~~---~--~~
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
-~--~~~~--~~--~--~---



Stupid Java questions

2009-02-03 Thread Anand Patil

Hi all,

I'm using the system java on Mac OS Leopard, and confused about how to
get the parallel library working. I've got the necessary jar file on
my classpath:

sihpc03:clojure anand$ echo $CLASSPATH
/usr/local/clojure:/Library/Java/Extensions
sihpc03:clojure anand$ ls /Library/Java/Extensions/
clojure.jar jline-0.9.94.jar
jsr166y.jar libsvnjavahl-1.jnilib   libsvnjavahl.jnilib

and I include it when I start up clojure:

sihpc03:clojure anand$ java -server -cp
jline-0.9.94.jar:jsr166y.jar:clojure.jar jline.ConsoleRunner
clojure.lang.Repl

However, when I try to load parallel.clj from the clojure source
directory, a problem happens:

user= (load-file parallel.clj)
java.lang.ClassNotFoundException: jsr166y.forkjoin.ParallelArray
(parallel.clj:0)

How can I fix that?


Another question: in the example on the clojure webpage, the load-file
command is (load-file src/parallel.clj). To make that work do I have
to have clojure's source directory on my classpath, or my regular
path, or are the sources available from inside the jar file somehow?

I'm sure the answers are available from Java documentation somewhere,
but the fact that I'm working from closure adds a thick enough layer
of confusion that I considered this worth posting... hope I'm not
taking advantage.


Thanks,
Anand
--~--~-~--~~~---~--~~
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
-~--~~~~--~~--~--~---



Re: Stupid Java questions

2009-02-03 Thread Anand Patil

OK, I get it:
  - parallel.clj writes into the namespace 'clojure.parallel, not
plain 'parallel as written on clojure.org/other_libraries
  - parallel.clj needs to be on my path, not my classpath.

That wasn't so bad, but It'll be easier if the examples on the website
were brought up to date.

Cheers,
Anand
--~--~-~--~~~---~--~~
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
-~--~~~~--~~--~--~---



Possible bug in preduce

2009-02-03 Thread Anand Patil

Hi all,

Messing around with preduce at the REPL I saw this:

user= (defn q [sofar new] (do (print new sofar\n) (+ (+ 1 new)
sofar)))
#'user/q
user= (reduce q 0 [1 2
3])
1 0
2 2
3 5
9
user= (preduce q 0 [1 2
3])
3 2
6 1
8

It looks like preduce takes its arguments in the opposite order from
reduce, but of course with this fn it shouldn't make any difference:

user= (defn q [new sofar] (do (print new sofar\n) (+ (+ 1 new)
sofar)))
#'user/q
user= (preduce q 0 [1 2
3])
2 3
1 6
8

Looks like it's using 3 where it should compute (q 3). This is a bug,
correct?

Thanks,
Anand
--~--~-~--~~~---~--~~
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
-~--~~~~--~~--~--~---



Re: Stupid Java questions

2009-02-03 Thread Anand Patil

Thanks Zak,

With the other jar I could load parallel.clj without errors, but I
wasn't able to refer to the parallel namespace as on clojure.org/
other_libraries, nor was preduce present in the user namespace:

user= (load-file parallel.clj)
nil
user= (refer 'parallel)
java.lang.Exception: No namespace: parallel (NO_SOURCE_FILE:0)
user= preduce
java.lang.Exception: Unable to resolve symbol: preduce in this context
(NO_SOURCE_FILE:0)

Also, the word 'jsr166y.jar' on clojure.org/other_libraries should
probably point to the working jar.

Thanks,
Anand

On Feb 3, 6:22 pm, Zak Wilson zak.wil...@gmail.com wrote:
 I had similar results when I compiled jsr166y myself. There's a jar in
 the group's files that is known to work.
--~--~-~--~~~---~--~~
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
-~--~~~~--~~--~--~---



definline example?

2009-01-25 Thread Anand Patil

Hi all,

I'd like to repeat my request for an example of definline usage; I
feel I've tried everything.

user= (definline f [x] x)
java.lang.ExceptionInInitializerError (NO_SOURCE_FILE:1)
user= (definline [x] x)
java.lang.NullPointerException (NO_SOURCE_FILE:2)
user= (definline (f [x] x))
java.lang.NullPointerException (NO_SOURCE_FILE:3)
user= (definline (defmacro f [x] x))
java.lang.NullPointerException (NO_SOURCE_FILE:4)
user= (definline f)
java.lang.NullPointerException (NO_SOURCE_FILE:12)

Thanks,
Anand
--~--~-~--~~~---~--~~
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
-~--~~~~--~~--~--~---



Re: definline example?

2009-01-25 Thread Anand Patil

On Jan 25, 5:27 pm, Chouser chou...@gmail.com wrote:
 On Sun, Jan 25, 2009 at 8:01 AM, Chouser chou...@gmail.com wrote:
  On Sun, Jan 25, 2009 at 7:06 AM, Anand Patil
  anand.prabhakar.pa...@gmail.com wrote:

  I'd like to repeat my request for an example of definline usage; I
  feel I've tried everything.

  I looked into this yesterday, and it seems to me that definline has
  been broken since SVN rev 1065.  I don't know why the usages of it in
  core.clj don't cause errors at compile time, but they don't seem to
  work quite right.

 I wrote a new definline that seems to work correctly:

 (defmacro definline
   Experimental - like defmacro, except defines a named function whose
   body is the expansion, calls to which may be expanded inline as if
   it were a macro. Cannot be used with variadic () args.
   [name  decl]
   (let [[pre-args [args expr]] (split-with (comp not vector?) decl)]
     `(do
        (defn ~name ~...@pre-args ~args ~(apply (eval (list `fn args expr)) 
 args))
        (alter-meta! (var ~name) assoc :inline (fn ~args ~expr))
        (var ~name

 Using definline work, and return the Var, just like defn does:
 user= (definline inc2 returns x plus 2 [x] `(+ 2 ~x))
 #'user/inc2


Terrific, thanks very much!

Anand


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



Request for code examples: definline and 'full' macro syntax

2009-01-21 Thread Anand Patil

Hi all,

Does anyone have, or know where I can find, simple working examples
showing the use of:

- definline
- defmacro with all the fields, (defmacro name doc-string? attr-map?
([params*] body) + attr-map?)
  I get doc-string, but don't understand:
  - attr-map
  - (...) + attr-map
  - the precise meaning of params* ... does it just mean that there
are a variable number of them? Does it mean the same thing in clojure
as in the docstrig?

Many thanks,
Anand
--~--~-~--~~~---~--~~
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
-~--~~~~--~~--~--~---



Re: How to make function that derefs vars and refs?

2009-01-19 Thread Anand Patil

On Jan 19, 1:05 am, Stuart Sierra the.stuart.sie...@gmail.com wrote:
 On Jan 18, 6:56 pm, Anand Patil anand.prabhakar.pa...@gmail.com
 wrote:

  Would it make any sense to make @ polymorphic so that @x return x's
  value when x is a var rather than raising an error?

 Actually, it already is:

 user (def x 5)
 #'user/x
 user (deref (var x))
 5
 user @(var x)
 5

 @x is just shorthand for (deref x), which resolves to (deref 5), which
 doesn't make sense.

Stuart,

Sorry, I was not being clear. Why not just let (deref 5) return 5? I
would consider that syntactic sugar, as it would make it easier to
deref a mixed vector of refs, constants, agents and atoms without
keeping track of which indices correspond to (ref, agent, atom)s and
which to constants.

Thanks,
Anand


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



Re: How to make function that derefs vars and refs?

2009-01-19 Thread Anand Patil

On Jan 19, 1:25 pm, Chouser chou...@gmail.com wrote:
 On Mon, Jan 19, 2009 at 4:07 AM, Anand Patil

 anand.prabhakar.pa...@gmail.com wrote:

  Sorry, I was not being clear. Why not just let (deref 5) return 5? I
  would consider that syntactic sugar, as it would make it easier to
  deref a mixed vector of refs, constants, agents and atoms without
  keeping track of which indices correspond to (ref, agent, atom)s and
  which to constants.

 You can do this yourself quite easily:

 (defn my-deref [x] (if (instance? clojure.lang.IRef x) @x x))

 (my-deref 5)  == 5
 (my-deref (var filter))  == #core$filter__3586
 clojure.core$filter__3...@1e1be92
 (my-deref filter)  == #core$filter__3586 clojure.core$filter__3...@1e1be92
 (my-deref (agent 99))  == 99

 I don't know if the builtin 'deref' should do this -- it seems like it
 might make things more confusing rather then less.

 --Chouser

Thanks Chouser, I'll take your word for it  use a specialized
function.

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



Re: How to make function that derefs vars and refs?

2009-01-18 Thread Anand Patil

Timothy, Stephen and Stuart,

Thanks for three very informative and understandable responses! It's
very encouraging to see that such support is available when
approaching a new language. I look forward to further exploration of
Clojure.

The var/value/symbol relationship continues to be a bit slippery for
me but I think I get it. The compiler's differing behaviors when
presented with vars vs. identities makes sense now that I think about
it. Thanks also for the class-checking syntax, which will come in very
handy.

Would it make any sense to make @ polymorphic so that @x return x's
value when x is a var rather than raising an error?

Anand

On Jan 18, 3:21 pm, Stuart Sierra the.stuart.sie...@gmail.com wrote:
 Hi Anand,

 You don't normally need to dereference vars because the compiler does
 it for you.

     user (def x 5)
     #'user/x

 This creates a var bound to the symbol x. But now, whenever you type
 x the compiler will automatically look up the var and return its
 value.

     user x
     5

 So when you type (var? x) it's resolved to (var? 5).  You're asking
 is 5 a var? and the answer is no. If you want to get at the var
 object itself, you can use the special form (var x)

     user (var x)
     #'user/x

 Note the #' prefix -- that means you're looking at a var object and
 not the symbol user/x.

     user (var? (var x))
     true
     user (var-get (var x))
     5

 I think deref worked on vars in early versions of Clojure, but it
 doesn't now.

 If you're just getting started with Clojure, you can probably ignore
 vars.  You will rarely have any need to work with vars directly unless
 you're doing some complicated metaprogramming.

 -Stuart Sierra

 On Jan 18, 5:11 am, anand.prabhakar.patil

 anand.prabhakar.pa...@gmail.com wrote:
  Hi all,
  I'm new to Java, Lisp and Clojure, so please be patient. I'm trying to make
  a function that behaves as follows: (my-deref x) returns x if x is a var, or
  @x if x is a ref. However none of the obvious options seem to be working.

  - First, it seems from the api documentation that @x will work fine even if
  x is a var. I don't understand the following:

  user= (def x 5)
  #'user/x
  user= @x
  java.lang.IncompatibleClassChangeError (NO_SOURCE_FILE:0)
  user= (var? x)
  false

  or

  user= (def x)
  #'user/x
  user= (var? x)
  false

  Why isn't x a var?

  - Second, I remember having seen a ref? function analogous to var? in the
  online documentation, but it doesn't seem to actualy exist:

  user= (ref? x)
  java.lang.Exception: Unable to resolve symbol: ref? in this context
  (NO_SOURCE_FILE:13)

  Thanks in advance,
  Anand
--~--~-~--~~~---~--~~
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
-~--~~~~--~~--~--~---