Re: Using an atom for a caching map

2014-08-30 Thread Eldar Gabdullin
Something like the following would be fine for me

(def cache (atom {}))
 
(defn lookup [cache k]
  (let [v (get @cache k ::nil)]
(if (= v ::nil)
  (let [v (calc-value k)]
(swap! cache assoc k v)
v)
  v)))
 
(let [value (lookup cache k)]
  ; use value and @cache here
  )


суббота, 30 августа 2014 г., 9:27:05 UTC+4 пользователь Colin Fleming 
написал:

 Hi all,

 I want to use a map to cache values based on a key. I'm planning to use an 
 atom for this. My basic operation is give me the value for this key - if 
 the value exists in the map then that value should be returned, otherwise a 
 new value should be calculated, inserted in the map and then returned. My 
 plan is to implement something like the following:


 (defn ensure [cache key]  (if (contains? cache key)cache(assoc cache 
 key (calc-value key(let [value (get (swap! cache ensure key) key)]  ... 
 do my thing with value ...)


 So 'ensure' ensures that the cache contains the value for key, the swap! 
 operation returns the cache with the value and then I get it out. This 
 works but feels a little clumsy, is there a better way to do this?

 Also, looking at the Atom source code, I see that this will cause a CAS 
 operation even if the value returned from swap! is identical to the 
 original value. It seems like a reasonable optimisation would be to check 
 if the values are identical and not update if so - is there a reason this 
 might not be a good idea?

 Thanks,
 Colin


-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Using an atom for a caching map

2014-08-30 Thread Colin Fleming
True, but only if you don't mind possibly calculating the value more than
once since the update is not atomic.


On 30 August 2014 18:31, Eldar Gabdullin eldar...@gmail.com wrote:

 Something like the following would be fine for me

 (def cache (atom {}))

 (defn lookup [cache k]
   (let [v (get @cache k ::nil)]
 (if (= v ::nil)
   (let [v (calc-value k)]
 (swap! cache assoc k v)
 v)
   v)))

 (let [value (lookup cache k)]
   ; use value and @cache here
   )


 суббота, 30 августа 2014 г., 9:27:05 UTC+4 пользователь Colin Fleming
 написал:

 Hi all,

 I want to use a map to cache values based on a key. I'm planning to use
 an atom for this. My basic operation is give me the value for this key -
 if the value exists in the map then that value should be returned,
 otherwise a new value should be calculated, inserted in the map and then
 returned. My plan is to implement something like the following:


 (defn ensure [cache key]  (if (contains? cache key)cache(assoc cache 
 key (calc-value key(let [value (get (swap! cache ensure key) key)]  ... 
 do my thing with value ...)


 So 'ensure' ensures that the cache contains the value for key, the swap!
 operation returns the cache with the value and then I get it out. This
 works but feels a little clumsy, is there a better way to do this?

 Also, looking at the Atom source code, I see that this will cause a CAS
 operation even if the value returned from swap! is identical to the
 original value. It seems like a reasonable optimisation would be to check
 if the values are identical and not update if so - is there a reason this
 might not be a good idea?

 Thanks,
 Colin

  --
 You received this message because you are subscribed to the Google
 Groups Clojure group.
 To post to this group, send email to clojure@googlegroups.com
 Note that posts from new members are moderated - please be patient with
 your first post.
 To unsubscribe from this group, send email to
 clojure+unsubscr...@googlegroups.com
 For more options, visit this group at
 http://groups.google.com/group/clojure?hl=en
 ---
 You received this message because you are subscribed to the Google Groups
 Clojure group.
 To unsubscribe from this group and stop receiving emails from it, send an
 email to clojure+unsubscr...@googlegroups.com.
 For more options, visit https://groups.google.com/d/optout.


-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Using an atom for a caching map

2014-08-30 Thread Eldar Gabdullin
Snippet you showed before is also not an atomic. If you want strictly to 
avoid recomputations you need something more elaborate.
May be this

(def cache (atom {}))
 
(defn unwrap [v]
  (if-let [a (get v ::atom)]
@a
v))
 
(defn compute [cache k]
  (let [p {::atom (atom nil)}
c (swap! cache assoc k p)
val (get c k)]
(when (identical? val p)
  (swap! (::atom p) (fn [_] (calc-value k)))
  (swap! cache assoc k @(::atom p)))
(unwrap val)))
 
(defn lookup [cache k]
  (let [v (get @cache k ::nil)]
(if (= v ::nil)
  (compute cache k)
  (unwrap v

  

суббота, 30 августа 2014 г., 11:18:51 UTC+4 пользователь Colin Fleming 
написал:

 True, but only if you don't mind possibly calculating the value more than 
 once since the update is not atomic.


 On 30 August 2014 18:31, Eldar Gabdullin elda...@gmail.com javascript: 
 wrote:

 Something like the following would be fine for me

 (def cache (atom {}))
  
 (defn lookup [cache k]

   (let [v (get @cache k ::nil)]

 (if (= v ::nil)

   (let [v (calc-value k)]

 (swap! cache assoc k v)

 v)
   v)))
  
 (let [value (lookup cache k)]

   ; use value and @cache here
   )


 суббота, 30 августа 2014 г., 9:27:05 UTC+4 пользователь Colin Fleming 
 написал:

 Hi all,

 I want to use a map to cache values based on a key. I'm planning to use 
 an atom for this. My basic operation is give me the value for this key - 
 if the value exists in the map then that value should be returned, 
 otherwise a new value should be calculated, inserted in the map and then 
 returned. My plan is to implement something like the following:


 (defn ensure [cache key]  (if (contains? cache key)cache(assoc 
 cache key (calc-value key(let [value (get (swap! cache ensure key) 
 key)]  ... do my thing with value ...)


 So 'ensure' ensures that the cache contains the value for key, the swap! 
 operation returns the cache with the value and then I get it out. This 
 works but feels a little clumsy, is there a better way to do this?

 Also, looking at the Atom source code, I see that this will cause a CAS 
 operation even if the value returned from swap! is identical to the 
 original value. It seems like a reasonable optimisation would be to check 
 if the values are identical and not update if so - is there a reason this 
 might not be a good idea?

 Thanks,
 Colin

  -- 
 You received this message because you are subscribed to the Google
 Groups Clojure group.
 To post to this group, send email to clo...@googlegroups.com 
 javascript:
 Note that posts from new members are moderated - please be patient with 
 your first post.
 To unsubscribe from this group, send email to
 clojure+u...@googlegroups.com javascript:
 For more options, visit this group at
 http://groups.google.com/group/clojure?hl=en
 --- 
 You received this message because you are subscribed to the Google Groups 
 Clojure group.
 To unsubscribe from this group and stop receiving emails from it, send an 
 email to clojure+u...@googlegroups.com javascript:.
 For more options, visit https://groups.google.com/d/optout.




-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Using an atom for a caching map

2014-08-30 Thread Ray Miller
On 30 August 2014 06:26, Colin Fleming colin.mailingl...@gmail.com wrote:

 I want to use a map to cache values based on a key. I'm planning to use an
 atom for this. My basic operation is give me the value for this key - if
 the value exists in the map then that value should be returned, otherwise a
 new value should be calculated, inserted in the map and then returned. My
 plan is to implement something like the following:


 (defn ensure [cache key]
   (if (contains? cache key)
 cache
 (assoc cache key (calc-value key

 (let [value (get (swap! cache ensure key) key)]
   ... do my thing with value ...)

Why not just use memoize?

(def calc-value (memoize (fn [key] ...))

If you need more control over the cache, check out core.memoize (which
builds on top of core.cache).

Ray.

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Using an atom for a caching map

2014-08-30 Thread Eldar Gabdullin
Oh, forget to wait for value in unwrap. Here is a better version 

(defn unwrap [v]
  (if-let [p (get v ::promise)]
@p
v))
 
(defn compute [cache k]
  (let [p {::promise (promise)}
c (swap! cache assoc k p)
val (get c k)]
(when (identical? val p)
  (let [result (calc-value k)]
(deliver (::promise p) result)
(swap! cache assoc k result))
  (unwrap val
 
(defn lookup [cache k]
  (let [v (get @cache k ::nil)]
(if (= v ::nil)
  (compute cache k)
  (unwrap v



суббота, 30 августа 2014 г., 11:54:59 UTC+4 пользователь Eldar Gabdullin 
написал:

 Snippet you showed before is also not an atomic. If you want strictly to 
 avoid recomputations you need something more elaborate.
 May be this

 (def cache (atom {}))
  
 (defn unwrap [v]
   (if-let [a (get v ::atom)]
 @a
 v))
  
 (defn compute [cache k]
   (let [p {::atom (atom nil)}
 c (swap! cache assoc k p)
 val (get c k)]
 (when (identical? val p)
   (swap! (::atom p) (fn [_] (calc-value k)))
   (swap! cache assoc k @(::atom p)))
 (unwrap val)))
  
 (defn lookup [cache k]
   (let [v (get @cache k ::nil)]
 (if (= v ::nil)
   (compute cache k)
   (unwrap v

   

 суббота, 30 августа 2014 г., 11:18:51 UTC+4 пользователь Colin Fleming 
 написал:

 True, but only if you don't mind possibly calculating the value more than 
 once since the update is not atomic.


 On 30 August 2014 18:31, Eldar Gabdullin elda...@gmail.com wrote:

 Something like the following would be fine for me

 (def cache (atom {}))
  
 (defn lookup [cache k]

   (let [v (get @cache k ::nil)]

 (if (= v ::nil)

   (let [v (calc-value k)]

 (swap! cache assoc k v)

 v)
   v)))
  
 (let [value (lookup cache k)]

   ; use value and @cache here
   )


 суббота, 30 августа 2014 г., 9:27:05 UTC+4 пользователь Colin Fleming 
 написал:

 Hi all,

 I want to use a map to cache values based on a key. I'm planning to use 
 an atom for this. My basic operation is give me the value for this key - 
 if the value exists in the map then that value should be returned, 
 otherwise a new value should be calculated, inserted in the map and then 
 returned. My plan is to implement something like the following:


 (defn ensure [cache key]  (if (contains? cache key)cache(assoc 
 cache key (calc-value key(let [value (get (swap! cache ensure key) 
 key)]  ... do my thing with value ...)


 So 'ensure' ensures that the cache contains the value for key, the 
 swap! operation returns the cache with the value and then I get it out. 
 This works but feels a little clumsy, is there a better way to do this?

 Also, looking at the Atom source code, I see that this will cause a CAS 
 operation even if the value returned from swap! is identical to the 
 original value. It seems like a reasonable optimisation would be to check 
 if the values are identical and not update if so - is there a reason this 
 might not be a good idea?

 Thanks,
 Colin

  -- 
 You received this message because you are subscribed to the Google
 Groups Clojure group.
 To post to this group, send email to clo...@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+u...@googlegroups.com
 For more options, visit this group at
 http://groups.google.com/group/clojure?hl=en
 --- 
 You received this message because you are subscribed to the Google 
 Groups Clojure group.
 To unsubscribe from this group and stop receiving emails from it, send 
 an email to clojure+u...@googlegroups.com.
 For more options, visit https://groups.google.com/d/optout.




-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: How can I add meta to an object that doesn't implement IObj?

2014-08-30 Thread François Rey

On 30/08/14 05:15, Atamert Ölçgen wrote:

Obviously I can't.

But I need to add this capability to an object. During testing I 
attach meta to this object that contains an atom. Then I pass this 
object to other functions, known in runtime. I can't use a dynamic var 
because all this happens within a mock function that may be retried 
and run in different threads.
In my case I used a list, e.g. (list obj), and used destructuring on the 
other side when needed, e.g. [obj :as wobj].


I have seen this: 
http://stackoverflow.com/questions/20724219/simplest-possible-clojure-object-that-can-accept-a-primitive-and-metadata 
but can't deref it since I can't change the functions that will use it 
later. If I wrap this object I need to be able to delegate all of its 
functionality to the original object.
I don't think there's a quick solution without changing the contract. 
Whatever solution is chosen you need to keep in mind how this will 
affect things like equality, hashing, and instanceof?

Perhaps these links could be a start:
https://groups.google.com/forum/#!topic/clojure/9zCGdW_Q7o8 
https://groups.google.com/forum/#%21topic/clojure/9zCGdW_Q7o8

http://stackoverflow.com/questions/9086926/create-a-proxy-for-an-specific-instance-of-an-object-in-clojure
Also, if the meta data is just for you own use, then you might want to 
store it yourself in a map with weak references, or just use WeakHashMap 
http://docs.oracle.com/javase/7/docs/api/java/util/WeakHashMap.html 
directly. But then you'll be stateful...


--
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups Clojure group.

To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: How can I add meta to an object that doesn't implement IObj?

2014-08-30 Thread Atamert Ölçgen
Hi François,

Thanks for the links.

I can't really pass a list since the first function is expecting the object
I am passing, then it calls some other functions that were supposed to
extract the meta. The problem is, functions that are called later can be
executed in a different thread.



On Sat, Aug 30, 2014 at 4:29 PM, François Rey fmj...@gmail.com wrote:

  On 30/08/14 05:15, Atamert Ölçgen wrote:

  Obviously I can't.

  But I need to add this capability to an object. During testing I attach
 meta to this object that contains an atom. Then I pass this object to other
 functions, known in runtime. I can't use a dynamic var because all this
 happens within a mock function that may be retried and run in different
 threads.

 In my case I used a list, e.g. (list obj), and used destructuring on the
 other side when needed, e.g. [obj :as wobj].


  I have seen this:
 http://stackoverflow.com/questions/20724219/simplest-possible-clojure-object-that-can-accept-a-primitive-and-metadata
 but can't deref it since I can't change the functions that will use it
 later. If I wrap this object I need to be able to delegate all of its
 functionality to the original object.

 I don't think there's a quick solution without changing the contract.
 Whatever solution is chosen you need to keep in mind how this will affect
 things like equality, hashing, and instanceof?
 Perhaps these links could be a start:
 https://groups.google.com/forum/#!topic/clojure/9zCGdW_Q7o8

 http://stackoverflow.com/questions/9086926/create-a-proxy-for-an-specific-instance-of-an-object-in-clojure
 Also, if the meta data is just for you own use, then you might want to
 store it yourself in a map with weak references, or just use WeakHashMap
 http://docs.oracle.com/javase/7/docs/api/java/util/WeakHashMap.html
 directly. But then you'll be stateful...

 --
 You received this message because you are subscribed to the Google
 Groups Clojure group.
 To post to this group, send email to clojure@googlegroups.com
 Note that posts from new members are moderated - please be patient with
 your first post.
 To unsubscribe from this group, send email to
 clojure+unsubscr...@googlegroups.com
 For more options, visit this group at
 http://groups.google.com/group/clojure?hl=en
 ---
 You received this message because you are subscribed to the Google Groups
 Clojure group.
 To unsubscribe from this group and stop receiving emails from it, send an
 email to clojure+unsubscr...@googlegroups.com.
 For more options, visit https://groups.google.com/d/optout.




-- 
Kind Regards,
Atamert Ölçgen

-+-
--+
+++

www.muhuk.com

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: How can I add meta to an object that doesn't implement IObj?

2014-08-30 Thread Alex Baranosky
The only way to do this is to wrap the object in something that implements
IObj. But at that point you might as well wrap it in a regular hashmap and
just wrap it in real data.


On Sat, Aug 30, 2014 at 1:54 AM, Atamert Ölçgen mu...@muhuk.com wrote:

 Hi François,

 Thanks for the links.

 I can't really pass a list since the first function is expecting the
 object I am passing, then it calls some other functions that were supposed
 to extract the meta. The problem is, functions that are called later can be
 executed in a different thread.



 On Sat, Aug 30, 2014 at 4:29 PM, François Rey fmj...@gmail.com wrote:

  On 30/08/14 05:15, Atamert Ölçgen wrote:

  Obviously I can't.

  But I need to add this capability to an object. During testing I attach
 meta to this object that contains an atom. Then I pass this object to other
 functions, known in runtime. I can't use a dynamic var because all this
 happens within a mock function that may be retried and run in different
 threads.

 In my case I used a list, e.g. (list obj), and used destructuring on the
 other side when needed, e.g. [obj :as wobj].


  I have seen this:
 http://stackoverflow.com/questions/20724219/simplest-possible-clojure-object-that-can-accept-a-primitive-and-metadata
 but can't deref it since I can't change the functions that will use it
 later. If I wrap this object I need to be able to delegate all of its
 functionality to the original object.

 I don't think there's a quick solution without changing the contract.
 Whatever solution is chosen you need to keep in mind how this will affect
 things like equality, hashing, and instanceof?
 Perhaps these links could be a start:
 https://groups.google.com/forum/#!topic/clojure/9zCGdW_Q7o8

 http://stackoverflow.com/questions/9086926/create-a-proxy-for-an-specific-instance-of-an-object-in-clojure
 Also, if the meta data is just for you own use, then you might want to
 store it yourself in a map with weak references, or just use WeakHashMap
 http://docs.oracle.com/javase/7/docs/api/java/util/WeakHashMap.html
 directly. But then you'll be stateful...

 --
 You received this message because you are subscribed to the Google
 Groups Clojure group.
 To post to this group, send email to clojure@googlegroups.com
 Note that posts from new members are moderated - please be patient with
 your first post.
 To unsubscribe from this group, send email to
 clojure+unsubscr...@googlegroups.com
 For more options, visit this group at
 http://groups.google.com/group/clojure?hl=en
 ---
 You received this message because you are subscribed to the Google Groups
 Clojure group.
 To unsubscribe from this group and stop receiving emails from it, send an
 email to clojure+unsubscr...@googlegroups.com.
 For more options, visit https://groups.google.com/d/optout.




 --
 Kind Regards,
 Atamert Ölçgen

 -+-
 --+
 +++

 www.muhuk.com

 --
 You received this message because you are subscribed to the Google
 Groups Clojure group.
 To post to this group, send email to clojure@googlegroups.com
 Note that posts from new members are moderated - please be patient with
 your first post.
 To unsubscribe from this group, send email to
 clojure+unsubscr...@googlegroups.com
 For more options, visit this group at
 http://groups.google.com/group/clojure?hl=en
 ---
 You received this message because you are subscribed to the Google Groups
 Clojure group.
 To unsubscribe from this group and stop receiving emails from it, send an
 email to clojure+unsubscr...@googlegroups.com.
 For more options, visit https://groups.google.com/d/optout.


-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Using an atom for a caching map

2014-08-30 Thread Colin Fleming
Yes, in my case the update is atomic but doesn't strictly avoid
recomputation (since the Atom can call the calculation function many
times). I've given this some hammock time and I don't think that's a
problem. However on further investigation I do have to ensure that for each
of my keys the value that is returned is identical since it uses identity
equality semantics, so I might have to stick with my original solution.
Thanks for the input though, it's very interesting to see your solution.


On 30 August 2014 19:54, Eldar Gabdullin eldar...@gmail.com wrote:

 Snippet you showed before is also not an atomic. If you want strictly to
 avoid recomputations you need something more elaborate.
 May be this

 (def cache (atom {}))

 (defn unwrap [v]
   (if-let [a (get v ::atom)]
 @a
 v))

 (defn compute [cache k]
   (let [p {::atom (atom nil)}
 c (swap! cache assoc k p)
 val (get c k)]
 (when (identical? val p)
   (swap! (::atom p) (fn [_] (calc-value k)))
   (swap! cache assoc k @(::atom p)))
 (unwrap val)))

 (defn lookup [cache k]
   (let [v (get @cache k ::nil)]
 (if (= v ::nil)
   (compute cache k)
   (unwrap v



 суббота, 30 августа 2014 г., 11:18:51 UTC+4 пользователь Colin Fleming
 написал:

 True, but only if you don't mind possibly calculating the value more than
 once since the update is not atomic.


 On 30 August 2014 18:31, Eldar Gabdullin elda...@gmail.com wrote:

 Something like the following would be fine for me

 (def cache (atom {}))

 (defn lookup [cache k]


   (let [v (get @cache k ::nil)]


 (if (= v ::nil)


   (let [v (calc-value k)]


 (swap! cache assoc k v)


 v)
   v)))

 (let [value (lookup cache k)]


   ; use value and @cache here
   )


 суббота, 30 августа 2014 г., 9:27:05 UTC+4 пользователь Colin Fleming
 написал:

 Hi all,

 I want to use a map to cache values based on a key. I'm planning to use
 an atom for this. My basic operation is give me the value for this key -
 if the value exists in the map then that value should be returned,
 otherwise a new value should be calculated, inserted in the map and then
 returned. My plan is to implement something like the following:


 (defn ensure [cache key]  (if (contains? cache key)cache(assoc 
 cache key (calc-value key(let [value (get (swap! cache ensure key) 
 key)]  ... do my thing with value ...)


 So 'ensure' ensures that the cache contains the value for key, the
 swap! operation returns the cache with the value and then I get it out.
 This works but feels a little clumsy, is there a better way to do this?

 Also, looking at the Atom source code, I see that this will cause a CAS
 operation even if the value returned from swap! is identical to the
 original value. It seems like a reasonable optimisation would be to check
 if the values are identical and not update if so - is there a reason this
 might not be a good idea?

 Thanks,
 Colin

  --
 You received this message because you are subscribed to the Google
 Groups Clojure group.
 To post to this group, send email to clo...@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+u...@googlegroups.com

 For more options, visit this group at
 http://groups.google.com/group/clojure?hl=en
 ---
 You received this message because you are subscribed to the Google
 Groups Clojure group.
 To unsubscribe from this group and stop receiving emails from it, send
 an email to clojure+u...@googlegroups.com.

 For more options, visit https://groups.google.com/d/optout.


  --
 You received this message because you are subscribed to the Google
 Groups Clojure group.
 To post to this group, send email to clojure@googlegroups.com
 Note that posts from new members are moderated - please be patient with
 your first post.
 To unsubscribe from this group, send email to
 clojure+unsubscr...@googlegroups.com
 For more options, visit this group at
 http://groups.google.com/group/clojure?hl=en
 ---
 You received this message because you are subscribed to the Google Groups
 Clojure group.
 To unsubscribe from this group and stop receiving emails from it, send an
 email to clojure+unsubscr...@googlegroups.com.
 For more options, visit https://groups.google.com/d/optout.


-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more 

Re: Using an atom for a caching map

2014-08-30 Thread Colin Fleming
In my case I can't use memoize because I need to supply the cache map -
that in turn is stored on another object so it can be invalidated by events
outside my control.


On 30 August 2014 20:00, Ray Miller r...@1729.org.uk wrote:

 On 30 August 2014 06:26, Colin Fleming colin.mailingl...@gmail.com
 wrote:
 
  I want to use a map to cache values based on a key. I'm planning to use
 an
  atom for this. My basic operation is give me the value for this key -
 if
  the value exists in the map then that value should be returned,
 otherwise a
  new value should be calculated, inserted in the map and then returned. My
  plan is to implement something like the following:
 
 
  (defn ensure [cache key]
(if (contains? cache key)
  cache
  (assoc cache key (calc-value key
 
  (let [value (get (swap! cache ensure key) key)]
... do my thing with value ...)

 Why not just use memoize?

 (def calc-value (memoize (fn [key] ...))

 If you need more control over the cache, check out core.memoize (which
 builds on top of core.cache).

 Ray.

 --
 You received this message because you are subscribed to the Google
 Groups Clojure group.
 To post to this group, send email to clojure@googlegroups.com
 Note that posts from new members are moderated - please be patient with
 your first post.
 To unsubscribe from this group, send email to
 clojure+unsubscr...@googlegroups.com
 For more options, visit this group at
 http://groups.google.com/group/clojure?hl=en
 ---
 You received this message because you are subscribed to the Google Groups
 Clojure group.
 To unsubscribe from this group and stop receiving emails from it, send an
 email to clojure+unsubscr...@googlegroups.com.
 For more options, visit https://groups.google.com/d/optout.


-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Using an atom for a caching map

2014-08-30 Thread Eldar Gabdullin
I see...

Just in case, I'd like to point out one possible deficiency in your 
original snippet. Generally, it should be better move value calculation 
outside of swap call, thus 
reducing a chance of contention, especially when you have many threads 
asking for different keys. 

суббота, 30 августа 2014 г., 14:09:42 UTC+4 пользователь Colin Fleming 
написал:

 Yes, in my case the update is atomic but doesn't strictly avoid 
 recomputation (since the Atom can call the calculation function many 
 times). I've given this some hammock time and I don't think that's a 
 problem. However on further investigation I do have to ensure that for each 
 of my keys the value that is returned is identical since it uses identity 
 equality semantics, so I might have to stick with my original solution. 
 Thanks for the input though, it's very interesting to see your solution.


 On 30 August 2014 19:54, Eldar Gabdullin elda...@gmail.com javascript: 
 wrote:

 Snippet you showed before is also not an atomic. If you want strictly to 
 avoid recomputations you need something more elaborate.
 May be this

 (def cache (atom {}))

  
 (defn unwrap [v]
   (if-let [a (get v ::atom)]

 @a
 v))
  
 (defn compute [cache k]

   (let [p {::atom (atom nil)}

 c (swap! cache assoc k p)

 val (get c k)]
 (when (identical? val p)

   (swap! (::atom p) (fn [_] (calc-value k)))

   (swap! cache assoc k @(::atom p)))

 (unwrap val)))
  
 (defn lookup [cache k]

   (let [v (get @cache k ::nil)]

 (if (= v ::nil)

   (compute cache k)
   (unwrap v

   

 суббота, 30 августа 2014 г., 11:18:51 UTC+4 пользователь Colin Fleming 
 написал:

 True, but only if you don't mind possibly calculating the value more 
 than once since the update is not atomic.


 On 30 August 2014 18:31, Eldar Gabdullin elda...@gmail.com wrote:

 Something like the following would be fine for me

 (def cache (atom {}))
  
 (defn lookup [cache k]



   (let [v (get @cache k ::nil)]



 (if (= v ::nil)



   (let [v (calc-value k)]



 (swap! cache assoc k v)



 v)
   v)))
  
 (let [value (lookup cache k)]



   ; use value and @cache here
   )


 суббота, 30 августа 2014 г., 9:27:05 UTC+4 пользователь Colin Fleming 
 написал:

 Hi all,

 I want to use a map to cache values based on a key. I'm planning to 
 use an atom for this. My basic operation is give me the value for this 
 key - if the value exists in the map then that value should be returned, 
 otherwise a new value should be calculated, inserted in the map and then 
 returned. My plan is to implement something like the following:


 (defn ensure [cache key]  (if (contains? cache key)cache(assoc 
 cache key (calc-value key(let [value (get (swap! cache ensure key) 
 key)]  ... do my thing with value ...)


 So 'ensure' ensures that the cache contains the value for key, the 
 swap! operation returns the cache with the value and then I get it out. 
 This works but feels a little clumsy, is there a better way to do this?

 Also, looking at the Atom source code, I see that this will cause a 
 CAS operation even if the value returned from swap! is identical to the 
 original value. It seems like a reasonable optimisation would be to check 
 if the values are identical and not update if so - is there a reason this 
 might not be a good idea?

 Thanks,
 Colin

  -- 
 You received this message because you are subscribed to the Google
 Groups Clojure group.
 To post to this group, send email to clo...@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+u...@googlegroups.com

 For more options, visit this group at
 http://groups.google.com/group/clojure?hl=en
 --- 
 You received this message because you are subscribed to the Google 
 Groups Clojure group.
 To unsubscribe from this group and stop receiving emails from it, send 
 an email to clojure+u...@googlegroups.com.

 For more options, visit https://groups.google.com/d/optout.


  -- 
 You received this message because you are subscribed to the Google
 Groups Clojure group.
 To post to this group, send email to clo...@googlegroups.com 
 javascript:
 Note that posts from new members are moderated - please be patient with 
 your first post.
 To unsubscribe from this group, send email to
 clojure+u...@googlegroups.com javascript:
 For more options, visit this group at
 http://groups.google.com/group/clojure?hl=en
 --- 
 You received this message because you are subscribed to the Google Groups 
 Clojure group.
 To unsubscribe from this group and stop receiving emails from it, send an 
 email to clojure+u...@googlegroups.com javascript:.
 For more options, visit https://groups.google.com/d/optout.




-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts 

Re: How can I add meta to an object that doesn't implement IObj?

2014-08-30 Thread Francis Avila
It would probably help if you said more about the source of this 
atom-holding object. Is it a plain Java class? A deftype/defrecord? Is it 
final?


If you can control the construction of this object and its class is not 
final, you can subclass it and add an IObj implementation. (Note that most, 
maybe all clojure ways of creating classes create final classes, so this 
technique won't work.) The easiest way to subclass is with `proxy`:

(defn meta-AtomHolder [atom-value metadata]
  (proxy [AtomHolderClass clojure.lang.IObj] ;; [superclass, new interfaces]
 [atom-value] ;; constructor args
(meta [] metadata) ;; subclass method
(withMeta [newmeta] (meta-AtomHolder newmeta
= (var user/meta-AtomHolder)
(meta-AtomHolder (atom x) {})
= #AtomHolderClass$IObj$40298964 
user.proxy$AtomHolderClass$IObj$40298964@302c28cc
(meta (meta-AtomHolder (atom x) {}))
= {}
(meta (with-meta (meta-AtomHolder (atom x) {}) {:a 1}))
= {:a 1}  

If the parent class is final or you can't construct the object yourself, 
you need to delegate method calls from one instance to this object 
instance. I think this is hard-but-not-impossible in java, but I'm not sure.

(Clojurescript has `specify`, which does exactly what you want, but only 
exists because delegation between instances in javascript is trivial.)

On Friday, August 29, 2014 10:16:05 PM UTC-5, Atamert Ölçgen wrote:

 Obviously I can't.

 But I need to add this capability to an object. During testing I attach 
 meta to this object that contains an atom. Then I pass this object to other 
 functions, known in runtime. I can't use a dynamic var because all this 
 happens within a mock function that may be retried and run in different 
 threads.

 I have seen this: 
 http://stackoverflow.com/questions/20724219/simplest-possible-clojure-object-that-can-accept-a-primitive-and-metadata
  
 but can't deref it since I can't change the functions that will use it 
 later. If I wrap this object I need to be able to delegate all of its 
 functionality to the original object.

 I hope this all is not too vague. The code I'm working on is not online 
 yet. But it's for clecs (https://github.com/muhuk/clecs/), I'm adding 
 quickcheck to compare different world implementations.


 -- 
 Kind Regards,
 Atamert Ölçgen

 -+-
 --+
 +++

 www.muhuk.com
  

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Why is this an Exception ?

2014-08-30 Thread Sreeharsha Mudivarti


On Saturday, August 30, 2014 12:34:24 AM UTC+5:30, Ashton Kemerling wrote:

 Bar/baz refers to the symbol baz in the namespace bar. If you haven't 
 created and imported bar, that's an error. 


This feels too java-ish for a lisp.
Can I avoid this by some form of declaration ?


-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Using an atom for a caching map

2014-08-30 Thread Colin Fleming
I'm not sure I understand - the contention will be the same whether or not
the value is calculated in the swap! call, right? And if I calculate the
value and then pass the calculated value to swap!, that value will be
thrown away every time the cache contains an existing value for my key.



On 30 August 2014 23:13, Eldar Gabdullin eldar...@gmail.com wrote:

 I see...

 Just in case, I'd like to point out one possible deficiency in your
 original snippet. Generally, it should be better move value calculation
 outside of swap call, thus
 reducing a chance of contention, especially when you have many threads
 asking for different keys.

 суббота, 30 августа 2014 г., 14:09:42 UTC+4 пользователь Colin Fleming
 написал:

 Yes, in my case the update is atomic but doesn't strictly avoid
 recomputation (since the Atom can call the calculation function many
 times). I've given this some hammock time and I don't think that's a
 problem. However on further investigation I do have to ensure that for each
 of my keys the value that is returned is identical since it uses identity
 equality semantics, so I might have to stick with my original solution.
 Thanks for the input though, it's very interesting to see your solution.


 On 30 August 2014 19:54, Eldar Gabdullin elda...@gmail.com wrote:

 Snippet you showed before is also not an atomic. If you want strictly to
 avoid recomputations you need something more elaborate.
 May be this

 (def cache (atom {}))



 (defn unwrap [v]
   (if-let [a (get v ::atom)]


 @a
 v))

 (defn compute [cache k]


   (let [p {::atom (atom nil)}


 c (swap! cache assoc k p)


 val (get c k)]
 (when (identical? val p)


   (swap! (::atom p) (fn [_] (calc-value k)))


   (swap! cache assoc k @(::atom p)))


 (unwrap val)))

 (defn lookup [cache k]


   (let [v (get @cache k ::nil)]


 (if (= v ::nil)


   (compute cache k)
   (unwrap v




 суббота, 30 августа 2014 г., 11:18:51 UTC+4 пользователь Colin Fleming
 написал:

 True, but only if you don't mind possibly calculating the value more
 than once since the update is not atomic.


 On 30 August 2014 18:31, Eldar Gabdullin elda...@gmail.com wrote:

 Something like the following would be fine for me

 (def cache (atom {}))

 (defn lookup [cache k]




   (let [v (get @cache k ::nil)]




 (if (= v ::nil)




   (let [v (calc-value k)]




 (swap! cache assoc k v)




 v)
   v)))

 (let [value (lookup cache k)]




   ; use value and @cache here
   )


 суббота, 30 августа 2014 г., 9:27:05 UTC+4 пользователь Colin Fleming
 написал:

 Hi all,

 I want to use a map to cache values based on a key. I'm planning to
 use an atom for this. My basic operation is give me the value for this
 key - if the value exists in the map then that value should be returned,
 otherwise a new value should be calculated, inserted in the map and then
 returned. My plan is to implement something like the following:


 (defn ensure [cache key]  (if (contains? cache key)cache(assoc 
 cache key (calc-value key(let [value (get (swap! cache ensure key) 
 key)]  ... do my thing with value ...)


 So 'ensure' ensures that the cache contains the value for key, the
 swap! operation returns the cache with the value and then I get it out.
 This works but feels a little clumsy, is there a better way to do this?

 Also, looking at the Atom source code, I see that this will cause a
 CAS operation even if the value returned from swap! is identical to the
 original value. It seems like a reasonable optimisation would be to check
 if the values are identical and not update if so - is there a reason this
 might not be a good idea?

 Thanks,
 Colin

  --
 You received this message because you are subscribed to the Google
 Groups Clojure group.
 To post to this group, send email to clo...@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+u...@googlegroups.com

 For more options, visit this group at
 http://groups.google.com/group/clojure?hl=en
 ---
 You received this message because you are subscribed to the Google
 Groups Clojure group.
 To unsubscribe from this group and stop receiving emails from it, send
 an email to clojure+u...@googlegroups.com.

 For more options, visit https://groups.google.com/d/optout.


  --
 You received this message because you are subscribed to the Google
 Groups Clojure group.
 To post to this group, send email to clo...@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+u...@googlegroups.com
 For more options, visit this group at
 http://groups.google.com/group/clojure?hl=en
 ---
 You received this message because you are subscribed to the Google
 Groups Clojure group.
 To unsubscribe from this group and stop receiving emails from it, 

Re: Using an atom for a caching map

2014-08-30 Thread Eldar Gabdullin
You are absolutely right. Sorry, for distraction. Deleted my message 
immediately after I realized that, but it turns out it managed to go 
already. 

суббота, 30 августа 2014 г., 16:25:21 UTC+4 пользователь Colin Fleming 
написал:

 I'm not sure I understand - the contention will be the same whether or not 
 the value is calculated in the swap! call, right? And if I calculate the 
 value and then pass the calculated value to swap!, that value will be 
 thrown away every time the cache contains an existing value for my key.



 On 30 August 2014 23:13, Eldar Gabdullin elda...@gmail.com javascript: 
 wrote:

 I see...

 Just in case, I'd like to point out one possible deficiency in your 
 original snippet. Generally, it should be better move value calculation 
 outside of swap call, thus 
 reducing a chance of contention, especially when you have many threads 
 asking for different keys. 

 суббота, 30 августа 2014 г., 14:09:42 UTC+4 пользователь Colin Fleming 
 написал:

 Yes, in my case the update is atomic but doesn't strictly avoid 
 recomputation (since the Atom can call the calculation function many 
 times). I've given this some hammock time and I don't think that's a 
 problem. However on further investigation I do have to ensure that for each 
 of my keys the value that is returned is identical since it uses identity 
 equality semantics, so I might have to stick with my original solution. 
 Thanks for the input though, it's very interesting to see your solution.


 On 30 August 2014 19:54, Eldar Gabdullin elda...@gmail.com wrote:

 Snippet you showed before is also not an atomic. If you want strictly 
 to avoid recomputations you need something more elaborate.
 May be this

 (def cache (atom {}))



  
 (defn unwrap [v]
   (if-let [a (get v ::atom)]



 @a
 v))
  
 (defn compute [cache k]



   (let [p {::atom (atom nil)}



 c (swap! cache assoc k p)



 val (get c k)]
 (when (identical? val p)



   (swap! (::atom p) (fn [_] (calc-value k)))



   (swap! cache assoc k @(::atom p)))



 (unwrap val)))
  
 (defn lookup [cache k]



   (let [v (get @cache k ::nil)]



 (if (= v ::nil)



   (compute cache k)
   (unwrap v



   

 суббота, 30 августа 2014 г., 11:18:51 UTC+4 пользователь Colin Fleming 
 написал:

 True, but only if you don't mind possibly calculating the value more 
 than once since the update is not atomic.


 On 30 August 2014 18:31, Eldar Gabdullin elda...@gmail.com wrote:

 Something like the following would be fine for me

 (def cache (atom {}))
  
 (defn lookup [cache k]





   (let [v (get @cache k ::nil)]





 (if (= v ::nil)





   (let [v (calc-value k)]





 (swap! cache assoc k v)





 v)
   v)))
  
 (let [value (lookup cache k)]





   ; use value and @cache here
   )


 суббота, 30 августа 2014 г., 9:27:05 UTC+4 пользователь Colin Fleming 
 написал:

 Hi all,

 I want to use a map to cache values based on a key. I'm planning to 
 use an atom for this. My basic operation is give me the value for this 
 key - if the value exists in the map then that value should be 
 returned, 
 otherwise a new value should be calculated, inserted in the map and 
 then 
 returned. My plan is to implement something like the following:


 (defn ensure [cache key]  (if (contains? cache key)cache(assoc 
 cache key (calc-value key(let [value (get (swap! cache ensure key) 
 key)]  ... do my thing with value ...)


 So 'ensure' ensures that the cache contains the value for key, the 
 swap! operation returns the cache with the value and then I get it out. 
 This works but feels a little clumsy, is there a better way to do this?

 Also, looking at the Atom source code, I see that this will cause a 
 CAS operation even if the value returned from swap! is identical to the 
 original value. It seems like a reasonable optimisation would be to 
 check 
 if the values are identical and not update if so - is there a reason 
 this 
 might not be a good idea?

 Thanks,
 Colin

  -- 
 You received this message because you are subscribed to the Google
 Groups Clojure group.
 To post to this group, send email to clo...@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+u...@googlegroups.com

 For more options, visit this group at
 http://groups.google.com/group/clojure?hl=en
 --- 
 You received this message because you are subscribed to the Google 
 Groups Clojure group.
 To unsubscribe from this group and stop receiving emails from it, 
 send an email to clojure+u...@googlegroups.com.

 For more options, visit https://groups.google.com/d/optout.


  -- 
 You received this message because you are subscribed to the Google
 Groups Clojure group.
 To post to this group, send email to clo...@googlegroups.com
 Note that posts from new members are moderated - please be patient with 
 your first post.
 

Re: How can I add meta to an object that doesn't implement IObj?

2014-08-30 Thread Gary Trakhman
Can you monkey-patch the meta function itself to draw from a map of object
to meta?

On Saturday, August 30, 2014, Francis Avila franci...@gmail.com wrote:

 It would probably help if you said more about the source of this
 atom-holding object. Is it a plain Java class? A deftype/defrecord? Is it
 final?


 If you can control the construction of this object and its class is not
 final, you can subclass it and add an IObj implementation. (Note that most,
 maybe all clojure ways of creating classes create final classes, so this
 technique won't work.) The easiest way to subclass is with `proxy`:

 (defn meta-AtomHolder [atom-value metadata]
   (proxy [AtomHolderClass clojure.lang.IObj] ;; [superclass, new
 interfaces]
  [atom-value] ;; constructor args
 (meta [] metadata) ;; subclass method
 (withMeta [newmeta] (meta-AtomHolder newmeta
 = (var user/meta-AtomHolder)
 (meta-AtomHolder (atom x) {})
 = #AtomHolderClass$IObj$40298964
 user.proxy$AtomHolderClass$IObj$40298964@302c28cc
 (meta (meta-AtomHolder (atom x) {}))
 = {}
 (meta (with-meta (meta-AtomHolder (atom x) {}) {:a 1}))
 = {:a 1}

 If the parent class is final or you can't construct the object yourself,
 you need to delegate method calls from one instance to this object
 instance. I think this is hard-but-not-impossible in java, but I'm not sure.

 (Clojurescript has `specify`, which does exactly what you want, but only
 exists because delegation between instances in javascript is trivial.)

 On Friday, August 29, 2014 10:16:05 PM UTC-5, Atamert Ölçgen wrote:

 Obviously I can't.

 But I need to add this capability to an object. During testing I attach
 meta to this object that contains an atom. Then I pass this object to other
 functions, known in runtime. I can't use a dynamic var because all this
 happens within a mock function that may be retried and run in different
 threads.

 I have seen this: http://stackoverflow.com/questions/20724219/
 simplest-possible-clojure-object-that-can-accept-a-primitive-and-metadata
 but can't deref it since I can't change the functions that will use it
 later. If I wrap this object I need to be able to delegate all of its
 functionality to the original object.

 I hope this all is not too vague. The code I'm working on is not online
 yet. But it's for clecs (https://github.com/muhuk/clecs/), I'm adding
 quickcheck to compare different world implementations.


 --
 Kind Regards,
 Atamert Ölçgen

 -+-
 --+
 +++

 www.muhuk.com

  --
 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
 javascript:_e(%7B%7D,'cvml','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
 javascript:_e(%7B%7D,'cvml','clojure%2bunsubscr...@googlegroups.com');
 For more options, visit this group at
 http://groups.google.com/group/clojure?hl=en
 ---
 You received this message because you are subscribed to the Google Groups
 Clojure group.
 To unsubscribe from this group and stop receiving emails from it, send an
 email to clojure+unsubscr...@googlegroups.com
 javascript:_e(%7B%7D,'cvml','clojure%2bunsubscr...@googlegroups.com');.
 For more options, visit https://groups.google.com/d/optout.


-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Puzzling list comp error: Don't know how to create ISeq from: clojure.lang.Keyword

2014-08-30 Thread gvim

I have a long function which produces `list-of-lists` :

((Sun 21 li 13 201.2139410)
 (Moon 11 le 21 131.3457459)
 ..)

 before entering a list comprehension (simplified for brevity):

 (defn calc ...
(let [ .
...
list-of-lists (map #(rest (first %)) results)]
(for [l list-of-lists
 plan (keyword (first l))
  deg (Integer/parseInt (second l))
  sign (signs (keyword (first (rest (rest l)
  min (Integer/parseInt (second (rest (rest l
  long (Float/parseFloat (last l))]
   {:deg deg :min min :long long})))

When I call the function I get this error:

IllegalArgumentException Don't know how to create ISeq from: 
clojure.lang.Keyword  clojure.lang.RT.seqFrom (RT.java:505)


I've tested all the bindings in the repl and they produce the desired 
data so it seems the final construction of the map is where the problem 
lies.


gvim


--
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups Clojure group.

To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Puzzling list comp error: Don't know how to create ISeq from: clojure.lang.Keyword

2014-08-30 Thread Alexey Kachayev
for macro expects each pair to be either binding-form/collection-expr or
one of known modifiers (:let, :when, :while).

Here:

plan (keyword (first l))

you give a pair of binding-form and keyword (which is really impossible to
iterate over).

If you meant let-binding for plan, dec, min and long, use :let modifier
(you can find example in documentation -
http://clojuredocs.org/clojure_core/clojure.core/for).


2014-08-30 16:47 GMT+03:00 gvim gvi...@gmail.com:

 I have a long function which produces `list-of-lists` :

 ((Sun 21 li 13 201.2139410)
  (Moon 11 le 21 131.3457459)
  ..)

  before entering a list comprehension (simplified for brevity):

  (defn calc ...
 (let [ .
 ...
 list-of-lists (map #(rest (first %)) results)]
 (for [l list-of-lists
  plan (keyword (first l))
   deg (Integer/parseInt (second l))
   sign (signs (keyword (first (rest (rest l)
   min (Integer/parseInt (second (rest (rest l
   long (Float/parseFloat (last l))]
{:deg deg :min min :long long})))

 When I call the function I get this error:

 IllegalArgumentException Don't know how to create ISeq from:
 clojure.lang.Keyword  clojure.lang.RT.seqFrom (RT.java:505)

 I've tested all the bindings in the repl and they produce the desired data
 so it seems the final construction of the map is where the problem lies.

 gvim


 --
 You received this message because you are subscribed to the Google
 Groups Clojure group.
 To post to this group, send email to clojure@googlegroups.com
 Note that posts from new members are moderated - please be patient with
 your first post.
 To unsubscribe from this group, send email to
 clojure+unsubscr...@googlegroups.com
 For more options, visit this group at
 http://groups.google.com/group/clojure?hl=en
 --- You received this message because you are subscribed to the Google
 Groups Clojure group.
 To unsubscribe from this group and stop receiving emails from it, send an
 email to clojure+unsubscr...@googlegroups.com.
 For more options, visit https://groups.google.com/d/optout.




-- 
Kind regards,
Alexey S. Kachayev,
CTO at Attendify.com
--
http://github.com/kachayev
http://twitter.com/kachayev
Skype: kachayev
Tel: +380-996692092

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Puzzling list comp error: Don't know how to create ISeq from: clojure.lang.Keyword

2014-08-30 Thread gvim

On 30/08/2014 15:07, Alexey Kachayev wrote:

for macro expects each pair to be either binding-form/collection-expr or
one of known modifiers (:let, :when, :while).

Here:

plan (keyword (first l))

you give a pair of binding-form and keyword (which is really impossible
to iterate over).

If you meant let-binding for plan, dec, min and long, use :let modifier
(you can find example in documentation -
http://clojuredocs.org/clojure_core/clojure.core/for).



Yes, of course :) I confused list comp bindings with let bindings. Thanks.

gvim

--
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups Clojure group.

To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Puzzling list comp error: Don't know how to create ISeq from: clojure.lang.Keyword

2014-08-30 Thread gvim

On 30/08/2014 15:07, Alexey Kachayev wrote:

for macro expects each pair to be either binding-form/collection-expr or
one of known modifiers (:let, :when, :while).

Here:

plan (keyword (first l))

you give a pair of binding-form and keyword (which is really impossible
to iterate over).

If you meant let-binding for plan, dec, min and long, use :let modifier
(you can find example in documentation -
http://clojuredocs.org/clojure_core/clojure.core/for).



I'm going to have to reduce the resulting list next so I thought to use 
a map version of the list comp. but ran into a similar error:


 (defn calc ...
 (let [ .
 ...
 list-of-lists (map #(rest (first %)) results)]
(- list-of-lists
(map #(let [plan (keyword (first %))
  deg (Integer/parseInt (second %))
  sign (signs (keyword (first (rest (rest %)
  min (Integer/parseInt (second (rest (rest %
  long (Float/parseFloat (last %))]
  {plan {:sign sign :deg deg :min min :long long}})))


Don't know how to create ISeq from: astro.calc$calc$fn__29869

Now I'm using a let form but the error is similar.

gvim


















2014-08-30 16:47 GMT+03:00 gvim gvi...@gmail.com
mailto:gvi...@gmail.com:

I have a long function which produces `list-of-lists` :

((Sun 21 li 13 201.2139410 tel:201.2139410)
  (Moon 11 le 21 131.3457459)
  ..)

 before entering a list comprehension (simplified for brevity):

  (defn calc ...
 (let [ .
 ...
 list-of-lists (map #(rest (first %)) results)]
 (for [l list-of-lists
  plan (keyword (first l))
   deg (Integer/parseInt (second l))
   sign (signs (keyword (first (rest (rest l)
   min (Integer/parseInt (second (rest (rest l
   long (Float/parseFloat (last l))]
{:deg deg :min min :long long})))

When I call the function I get this error:

IllegalArgumentException Don't know how to create ISeq from:
clojure.lang.Keyword  clojure.lang.RT.seqFrom (RT.java:505)

I've tested all the bindings in the repl and they produce the
desired data so it seems the final construction of the map is where
the problem lies.

gvim


--
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
mailto: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+unsubscribe@__googlegroups.com
mailto:clojure%2bunsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/__group/clojure?hl=en
http://groups.google.com/group/clojure?hl=en
--- You received this message because you are subscribed to the
Google Groups Clojure group.
To unsubscribe from this group and stop receiving emails from it,
send an email to clojure+unsubscribe@__googlegroups.com
mailto:clojure%2bunsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/__optout
https://groups.google.com/d/optout.




--
Kind regards,
Alexey S. Kachayev,
CTO at Attendify.com
--
http://github.com/kachayev
http://twitter.com/kachayev
Skype: kachayev
Tel: +380-996692092

--
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with
your first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
---
You received this message because you are subscribed to the Google
Groups Clojure group.
To unsubscribe from this group and stop receiving emails from it, send
an email to clojure+unsubscr...@googlegroups.com
mailto:clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


--
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups Clojure group.

To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Puzzling list comp error: Don't know how to create ISeq from: clojure.lang.Keyword

2014-08-30 Thread Alexey Kachayev
Thread-first macro - will insert list-of-lists as first argument for map,
which is definitely not what you expect. Use threading-last - instead.


2014-08-30 18:48 GMT+03:00 gvim gvi...@gmail.com:

 On 30/08/2014 15:07, Alexey Kachayev wrote:

 for macro expects each pair to be either binding-form/collection-expr or
 one of known modifiers (:let, :when, :while).

 Here:

 plan (keyword (first l))

 you give a pair of binding-form and keyword (which is really impossible
 to iterate over).

 If you meant let-binding for plan, dec, min and long, use :let modifier
 (you can find example in documentation -
 http://clojuredocs.org/clojure_core/clojure.core/for).


 I'm going to have to reduce the resulting list next so I thought to use a
 map version of the list comp. but ran into a similar error:


  (defn calc ...
  (let [ .
  ...
  list-of-lists (map #(rest (first %)) results)]
 (- list-of-lists
 (map #(let [plan (keyword (first %))

   deg (Integer/parseInt (second %))
   sign (signs (keyword (first (rest (rest %)
   min (Integer/parseInt (second (rest (rest %
   long (Float/parseFloat (last %))]
   {plan {:sign sign :deg deg :min min :long long}})))


 Don't know how to create ISeq from: astro.calc$calc$fn__29869

 Now I'm using a let form but the error is similar.

 gvim

















 2014-08-30 16:47 GMT+03:00 gvim gvi...@gmail.com
 mailto:gvi...@gmail.com:


 I have a long function which produces `list-of-lists` :

 ((Sun 21 li 13 201.2139410 tel:201.2139410)

   (Moon 11 le 21 131.3457459)
   ..)

  before entering a list comprehension (simplified for brevity):

   (defn calc ...
  (let [ .
  ...
  list-of-lists (map #(rest (first %)) results)]
  (for [l list-of-lists
   plan (keyword (first l))
deg (Integer/parseInt (second l))
sign (signs (keyword (first (rest (rest l)
min (Integer/parseInt (second (rest (rest l
long (Float/parseFloat (last l))]
 {:deg deg :min min :long long})))

 When I call the function I get this error:

 IllegalArgumentException Don't know how to create ISeq from:
 clojure.lang.Keyword  clojure.lang.RT.seqFrom (RT.java:505)

 I've tested all the bindings in the repl and they produce the
 desired data so it seems the final construction of the map is where
 the problem lies.

 gvim


 --
 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
 mailto: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+unsubscribe@__googlegroups.com
 mailto:clojure%2bunsubscr...@googlegroups.com

 For more options, visit this group at
 http://groups.google.com/__group/clojure?hl=en

 http://groups.google.com/group/clojure?hl=en
 --- You received this message because you are subscribed to the
 Google Groups Clojure group.
 To unsubscribe from this group and stop receiving emails from it,
 send an email to clojure+unsubscribe@__googlegroups.com
 mailto:clojure%2bunsubscr...@googlegroups.com.
 For more options, visit https://groups.google.com/d/__optout
 https://groups.google.com/d/optout.





 --
 Kind regards,
 Alexey S. Kachayev,
 CTO at Attendify.com
 --
 http://github.com/kachayev
 http://twitter.com/kachayev
 Skype: kachayev
 Tel: +380-996692092

 --
 You received this message because you are subscribed to the Google
 Groups Clojure group.
 To post to this group, send email to clojure@googlegroups.com
 Note that posts from new members are moderated - please be patient with
 your first post.
 To unsubscribe from this group, send email to
 clojure+unsubscr...@googlegroups.com
 For more options, visit this group at
 http://groups.google.com/group/clojure?hl=en
 ---
 You received this message because you are subscribed to the Google
 Groups Clojure group.
 To unsubscribe from this group and stop receiving emails from it, send
 an email to clojure+unsubscr...@googlegroups.com
 mailto:clojure+unsubscr...@googlegroups.com.

 For more options, visit https://groups.google.com/d/optout.


 --
 You received this message because you are subscribed to the Google
 Groups Clojure group.
 To post to this group, send email to clojure@googlegroups.com
 Note that posts from new members are moderated - please be patient with
 your first post.
 To unsubscribe from this group, send email to
 clojure+unsubscr...@googlegroups.com
 For more options, visit this group at
 http://groups.google.com/group/clojure?hl=en
 

Re: Puzzling list comp error: Don't know how to create ISeq from: clojure.lang.Keyword

2014-08-30 Thread gvim

On 30/08/2014 17:04, Alexey Kachayev wrote:

Thread-first macro -will insert list-of-listsas first argument for map,
which is definitely not what you expect. Use threading-last -instead.



I've never quite understood the distinction other than - does 
everything top to bottom and - does the reverse. From what you're 
saying the choice also affects which position the argument is inserted? 
If so this presents a complication in that threading through several 
functions may require the argument to be inserted in different positions?


gvim

--
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups Clojure group.

To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Using an atom for a caching map

2014-08-30 Thread Beau Fabry
I must be missing something, because this is too simple?

(defn get-maybe-cached [cache key]
  (dosync
(if-let [v (get @cache key)]
  v
  (do
(reset! cache (assoc @cache key (calculate key)))
(get @cache key)

On Saturday, August 30, 2014 3:27:05 PM UTC+10, Colin Fleming wrote:

 Hi all,

 I want to use a map to cache values based on a key. I'm planning to use an 
 atom for this. My basic operation is give me the value for this key - if 
 the value exists in the map then that value should be returned, otherwise a 
 new value should be calculated, inserted in the map and then returned. My 
 plan is to implement something like the following:


 (defn ensure [cache key]  (if (contains? cache key)cache(assoc cache 
 key (calc-value key(let [value (get (swap! cache ensure key) key)]  ... 
 do my thing with value ...)


 So 'ensure' ensures that the cache contains the value for key, the swap! 
 operation returns the cache with the value and then I get it out. This 
 works but feels a little clumsy, is there a better way to do this?

 Also, looking at the Atom source code, I see that this will cause a CAS 
 operation even if the value returned from swap! is identical to the 
 original value. It seems like a reasonable optimisation would be to check 
 if the values are identical and not update if so - is there a reason this 
 might not be a good idea?

 Thanks,
 Colin


-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Using an atom for a caching map

2014-08-30 Thread Marcus Magnusson
How about something like this? You can still keep your cache as an atom 
that you can pass around, and you avoid unnecessary recomputation through 
memoize:

(def cache (atom {}))

(def lookup
  (let [calc-value* (memoize calc-value)]
(fn [cache k]
  (when-not (contains? @cache k)
(swap! cache assoc k (calc-value* k)))
  (@cache k

Den lördagen den 30:e augusti 2014 kl. 12:11:58 UTC+2 skrev Colin Fleming:

 In my case I can't use memoize because I need to supply the cache map - 
 that in turn is stored on another object so it can be invalidated by events 
 outside my control.


 On 30 August 2014 20:00, Ray Miller r...@1729.org.uk javascript: 
 wrote:

 On 30 August 2014 06:26, Colin Fleming colin.ma...@gmail.com 
 javascript: wrote:
 
  I want to use a map to cache values based on a key. I'm planning to use 
 an
  atom for this. My basic operation is give me the value for this key - 
 if
  the value exists in the map then that value should be returned, 
 otherwise a
  new value should be calculated, inserted in the map and then returned. 
 My
  plan is to implement something like the following:
 
 
  (defn ensure [cache key]
(if (contains? cache key)
  cache
  (assoc cache key (calc-value key
 
  (let [value (get (swap! cache ensure key) key)]
... do my thing with value ...)

 Why not just use memoize?

 (def calc-value (memoize (fn [key] ...))

 If you need more control over the cache, check out core.memoize (which
 builds on top of core.cache).

 Ray.

 --
 You received this message because you are subscribed to the Google
 Groups Clojure group.
 To post to this group, send email to clo...@googlegroups.com 
 javascript:
 Note that posts from new members are moderated - please be patient with 
 your first post.
 To unsubscribe from this group, send email to
 clojure+u...@googlegroups.com javascript:
 For more options, visit this group at
 http://groups.google.com/group/clojure?hl=en
 ---
 You received this message because you are subscribed to the Google Groups 
 Clojure group.
 To unsubscribe from this group and stop receiving emails from it, send an 
 email to clojure+u...@googlegroups.com javascript:.
 For more options, visit https://groups.google.com/d/optout.




-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Why is this an Exception ?

2014-08-30 Thread Andy Fingerhut
How would another Lisp avoid giving you an error when referring to a symbol
that has no value?

If you just want your entire program in a single namespace, and don't want
to use any libraries in other namespaces, then simply don't use the /
character in your symbol names.

If you want to use the symbols in other namespaces without a namespace/
prefix in front of them, you can use a declaration like this:

(ns my.namespace.name
  (:require [other.namespace :refer :all]
 [yet.another.namespace :refer :all]))

Then you can use the names of public symbols from other.namespace and
yet.another.namespace in your code without the namespace prefix.

Andy


On Sat, Aug 30, 2014 at 1:02 AM, Sreeharsha Mudivarti msreehar...@gmail.com
 wrote:



 On Saturday, August 30, 2014 12:34:24 AM UTC+5:30, Ashton Kemerling wrote:

 Bar/baz refers to the symbol baz in the namespace bar. If you haven't
 created and imported bar, that's an error.


 This feels too java-ish for a lisp.
 Can I avoid this by some form of declaration ?


  --
 You received this message because you are subscribed to the Google
 Groups Clojure group.
 To post to this group, send email to clojure@googlegroups.com
 Note that posts from new members are moderated - please be patient with
 your first post.
 To unsubscribe from this group, send email to
 clojure+unsubscr...@googlegroups.com
 For more options, visit this group at
 http://groups.google.com/group/clojure?hl=en
 ---
 You received this message because you are subscribed to the Google Groups
 Clojure group.
 To unsubscribe from this group and stop receiving emails from it, send an
 email to clojure+unsubscr...@googlegroups.com.
 For more options, visit https://groups.google.com/d/optout.


-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Puzzling list comp error: Don't know how to create ISeq from: clojure.lang.Keyword

2014-08-30 Thread Sam Raker
`-` inserts its first argument into the second position of the next 
argument, and so on, so
(- []
 (conj 1)
 (conj 2))

Turns into
(conj (conj [] 1) 2)

`-` inserts its first argument into the LAST position of the next 
argument, and so on, so
(- 1
 (conj [2])
 (conj [3]))
 

Turns into 
(conj [3] (conj [2] 1))

I guess it is bottom to top, in a way, but I always thought that was kind 
of an artifact of the argument (re-)ordering.



On Saturday, August 30, 2014 12:19:31 PM UTC-4, g vim wrote:

 On 30/08/2014 17:04, Alexey Kachayev wrote: 
  Thread-first macro -will insert list-of-listsas first argument for map, 
  which is definitely not what you expect. Use threading-last -instead. 
  

 I've never quite understood the distinction other than - does 
 everything top to bottom and - does the reverse. From what you're 
 saying the choice also affects which position the argument is inserted? 
 If so this presents a complication in that threading through several 
 functions may require the argument to be inserted in different positions? 

 gvim 


-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Resources for intermediate/not-absolute-beginner Clojurians

2014-08-30 Thread Christopher Small
+1 for JOC. It's a fantastic book.

Chris


On Friday, August 29, 2014 6:28:25 PM UTC-7, Paul L. Snyder wrote:

 On Fri, 29 Aug 2014, Sam Raker wrote: 

  I'm just not sure what to do at this point in my Clojure learning 
  experience. I've probably written a few thousand lines of Clojure at 
 this 
  point, but I'm not sure that I'm doing things right: I don't know if 
 my 
  code is efficient, or even idiomatic. I've know next to nothing about 
 Java, 
  and Clojure is my first introduction to functional programming. There 
 are 
  so many fun, exciting, awesome-seeming things in Clojure that I want to 
  take advantage of, like reference types and futures, but I have no point 
 of 
  reference for them and feel like I'm having trouble wrapping my head 
 around 
  them. 

 It sounds like you're at the perfect moment to hit up _The Joy of 
 Clojure_. 
 The second edition came out recently, so it should be nicely current.  My 
 copy of 2e is on my in-pile, so I can't yet comment specifically on the 
 updates, but its approach is aimed directly at what you seem to be looking 
 for: why Clojure is Clojure, and what you can do about it. 

  http://joyofclojure.com/ 

 Paul 


-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Resources for intermediate/not-absolute-beginner Clojurians

2014-08-30 Thread Gary Trakhman
Eventually you'll have to come around to reading implementations. The Joy
of Clojure is a very thoughtful book, but lib authors aren't going to go
through the same amount of trouble.

Reading code gets easier and rewards faster  the more you do it.

On Saturday, August 30, 2014, Christopher Small metasoar...@gmail.com
wrote:

 +1 for JOC. It's a fantastic book.

 Chris


 On Friday, August 29, 2014 6:28:25 PM UTC-7, Paul L. Snyder wrote:

 On Fri, 29 Aug 2014, Sam Raker wrote:

  I'm just not sure what to do at this point in my Clojure learning
  experience. I've probably written a few thousand lines of Clojure at
 this
  point, but I'm not sure that I'm doing things right: I don't know if
 my
  code is efficient, or even idiomatic. I've know next to nothing about
 Java,
  and Clojure is my first introduction to functional programming. There
 are
  so many fun, exciting, awesome-seeming things in Clojure that I want to
  take advantage of, like reference types and futures, but I have no
 point of
  reference for them and feel like I'm having trouble wrapping my head
 around
  them.

 It sounds like you're at the perfect moment to hit up _The Joy of
 Clojure_.
 The second edition came out recently, so it should be nicely current.  My
 copy of 2e is on my in-pile, so I can't yet comment specifically on the
 updates, but its approach is aimed directly at what you seem to be
 looking
 for: why Clojure is Clojure, and what you can do about it.

  http://joyofclojure.com/

 Paul

  --
 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
 javascript:_e(%7B%7D,'cvml','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
 javascript:_e(%7B%7D,'cvml','clojure%2bunsubscr...@googlegroups.com');
 For more options, visit this group at
 http://groups.google.com/group/clojure?hl=en
 ---
 You received this message because you are subscribed to the Google Groups
 Clojure group.
 To unsubscribe from this group and stop receiving emails from it, send an
 email to clojure+unsubscr...@googlegroups.com
 javascript:_e(%7B%7D,'cvml','clojure%2bunsubscr...@googlegroups.com');.
 For more options, visit https://groups.google.com/d/optout.


-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Resources for intermediate/not-absolute-beginner Clojurians

2014-08-30 Thread Alex Miller
Hi Sam,

I am working on a book for Pragmatic Programmers with Ben Vandgrift called 
Clojure Applied that is target specifically at people like yourself. Our 
goal is to bridge the gap between knowing the syntax and basics of the 
language to knowing how to apply it in building applications. The first 
half of the book is in tech review now and it will likely be a beta book in 
October or November with final release in early 2015. 

I would also certainly encourage you to read code and understand the 
libraries you use (or Clojure itself) at a deeper level! 

Alex

On Friday, August 29, 2014 7:14:36 PM UTC-5, Sam Raker wrote:

 I worked my way through *Clojure Programming* (Emerick, Carper,  Grand, 
 O'Reilly), and I've started writing my own Clojure (porting over an 
 unfinished Python project that seemed amenable to the Clojure treatment.) I 
 really love the language, but I'm not sure where to go from here. 

 My other main language is Python, which I learned in school, and also 
 found a bunch of intermediate/non-introductory resources for, like the 
 awesome, short, topic-oriented monographs (for lack of a better term) by 
 Matt Harrison (e.g., 
 http://www.amazon.com/Guide-Learning-Iteration-Generators-Python-ebook/dp/B007JR4FCQ/ref=sr_1_3).
  
 These really helped me understand some of the less-obvious/less-intro parts 
 of Python, and the stuff I learned in school helped me learn what idiomatic 
 Python looked/felt like. 

 I'm just not sure what to do at this point in my Clojure learning 
 experience. I've probably written a few thousand lines of Clojure at this 
 point, but I'm not sure that I'm doing things right: I don't know if my 
 code is efficient, or even idiomatic. I've know next to nothing about Java, 
 and Clojure is my first introduction to functional programming. There are 
 so many fun, exciting, awesome-seeming things in Clojure that I want to 
 take advantage of, like reference types and futures, but I have no point of 
 reference for them and feel like I'm having trouble wrapping my head around 
 them.

 I've come to realize that I learn best from books, and while code literacy 
 is something I need to work on, read the sourcecode [for library X] isn't 
 going to help me that much, unless it's aggressively commented/documented. 
 I don't really want another intro book, since I'd rather not pay for too 
 much overlap, and while I'll happily accept recommendations for 
 application-/domain-specific books, I'm more looking for a deeper dive into 
 the language itself. 

 I'm being really difficult about this, and I'm sorry in advance. Any and 
 all suggestions are welcome. Thanks guys!


-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.