Re: Using an atom for a caching map

2014-09-01 Thread Thomas Heller
As much as I like Clojure and atoms, I do not think they are a good fit for 
caching. Not only is it impossible to address the concurrency issues 
related to multiple threads loading the same object, but you also have to 
do expiration and size management yourself. Immutability doesn't help much 
for caching either. There is core.cache that does some bits but I probably 
would recommend using something like CacheBuilder from the guava libs:

See
https://code.google.com/p/guava-libraries/
http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/cache/CacheBuilder.html

Its Java but the Clojure<->Java interop is so good that it doesn't matter 
much.

On Saturday, August 30, 2014 7:27:05 AM UTC+2, 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-09-01 Thread Colin Fleming
Hi Beau,

I've not used the STM stuff at all, but my understanding is that dosync is
intended for co-ordinated updates to refs, and has no effect on atoms. It's
really intended for co-ordinating updates to multiple refs rather than as a
synchronisation primitive on a single entity. I might be wrong though, as I
say I've never used it.

Cheers,
Colin


On 31 August 2014 00:58, Beau Fabry  wrote:

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

-- 
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-09-01 Thread Colin Fleming
Hi Marcus,

That's an interesting approach. My first reaction was that the update is
still not atomic, since you have:

(when-not (contains? @cache k)
  (swap! cache assoc k (calc-value* k)))

Which I thought could cause different clients to see different values
depending on the race condition there. But since in theory calc-value*
should always return the same value for the same key, at worst you'll just
end up swapping the same value in unnecessarily. I'd need to think a bit
about the implications of using a memoised function in an atom update to
convince myself, but it's a neat idea - thanks!

Cheers,
Colin



On 31 August 2014 04:25, Marcus Magnusson  wrote:

> 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  wrote:
>>
>>>  On 30 August 2014 06:26, Colin Fleming  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
>>>
>>> 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 options, visit https://groups.google.com/d/optout.


Re: Using an atom for a caching map

2014-09-01 Thread Colin Fleming
Hi Thomas,

Normally I'd agree with you, but in my case it actually works quite well
since I don't need to expire or worry about sizing. This is for caching
objects on IntelliJ parse tree elements, and the element with its cached
values is thrown away every time the document is parsed, so these are
pretty transient caches. In this particular case the calculation isn't too
heavyweight either so recalculating it in the unlikely event of contention
isn't a big deal. In fact, this discussion and the related thinking has
made me realise that my original solution was actually sufficient for my
somewhat strange use case, which is nice :-). For more typical server side
caching, I agree that Guava would be a great solution.

Cheers,
Colin


On 1 September 2014 20:54, Thomas Heller  wrote:

> As much as I like Clojure and atoms, I do not think they are a good fit
> for caching. Not only is it impossible to address the concurrency issues
> related to multiple threads loading the same object, but you also have to
> do expiration and size management yourself. Immutability doesn't help much
> for caching either. There is core.cache that does some bits but I probably
> would recommend using something like CacheBuilder from the guava libs:
>
> See
> https://code.google.com/p/guava-libraries/
>
> http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/cache/CacheBuilder.html
>
> Its Java but the Clojure<->Java interop is so good that it doesn't matter
> much.
>
> On Saturday, August 30, 2014 7:27:05 AM UTC+2, 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.
>

-- 
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-09-01 Thread Thomas Heller
Hey Colin,

That doesn't mean guava wouldn't be a nice solution here still. Just 
.invalidateAll to purge it. Might even use softValues to let the gc decide 
to remove some entries when running low on memory. Emulating a mutable 
thing in clojure with an atom is not always better than using the mutable 
thing in the first place. ;)

But there are other issues to think about in regards to shipping Cursive 
with Guava. So if it works in plain Clojure its proably good enough.

Just my 2 cents,
/thomas



On Monday, September 1, 2014 11:21:11 AM UTC+2, Colin Fleming wrote:
>
> Hi Thomas,
>
> Normally I'd agree with you, but in my case it actually works quite well 
> since I don't need to expire or worry about sizing. This is for caching 
> objects on IntelliJ parse tree elements, and the element with its cached 
> values is thrown away every time the document is parsed, so these are 
> pretty transient caches. In this particular case the calculation isn't too 
> heavyweight either so recalculating it in the unlikely event of contention 
> isn't a big deal. In fact, this discussion and the related thinking has 
> made me realise that my original solution was actually sufficient for my 
> somewhat strange use case, which is nice :-). For more typical server side 
> caching, I agree that Guava would be a great solution.
>
> Cheers,
> Colin
>
>
> On 1 September 2014 20:54, Thomas Heller > 
> wrote:
>
>> As much as I like Clojure and atoms, I do not think they are a good fit 
>> for caching. Not only is it impossible to address the concurrency issues 
>> related to multiple threads loading the same object, but you also have to 
>> do expiration and size management yourself. Immutability doesn't help much 
>> for caching either. There is core.cache that does some bits but I probably 
>> would recommend using something like CacheBuilder from the guava libs:
>>
>> See
>> https://code.google.com/p/guava-libraries/
>>
>> http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/cache/CacheBuilder.html
>>
>> Its Java but the Clojure<->Java interop is so good that it doesn't matter 
>> much.
>>
>> On Saturday, August 30, 2014 7:27:05 AM UTC+2, 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 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: Using an atom for a caching map

2014-09-01 Thread Beau Fabry
Indeed you're right, I was confused. The dosync call was a naive attempt to 
avoid the CAS operation you were worried about earlier. I suppose another 
option would be to use compare-and-set! with a lazy seq.

(compare-and-set! cache-atom (dissoc @cache-atom k) (assoc @cache-atom k 
(lazy-seq (cons (expensive k) '()
(first (@cache-atom k))

On Monday, September 1, 2014 7:10:52 PM UTC+10, Colin Fleming wrote:
>
> Hi Beau,
>
> I've not used the STM stuff at all, but my understanding is that dosync is 
> intended for co-ordinated updates to refs, and has no effect on atoms. It's 
> really intended for co-ordinating updates to multiple refs rather than as a 
> synchronisation primitive on a single entity. I might be wrong though, as I 
> say I've never used it.
>
> Cheers,
> Colin
>
>
> On 31 August 2014 00:58, Beau Fabry > 
> wrote:
>
>> 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 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.


[ANN] Gorilla REPL 0.3.3 - inline docs, CIDER compatibility

2014-09-01 Thread Jony Hudson
Hi all,

 there's a new version of Gorilla REPL out :-) The headline feature is that 
the autocomplete UI now shows the docs for the function you're typing/lets 
you browse the docs. It's really handy! Autocomplete itself is also much 
improved, courtesy of the compliment library.

This version also adds compatibility with the latest version of CIDER, and 
a number of other smaller fixes and features (see changelog below).

I must give credit here to the CIDER team, who have done a great job of 
writing CIDER's back-end code in a way that it can be re-used by other 
editors. It must have taken some work to do that, and it's a very useful 
contribution to Clojure tooling. Gorilla now uses CIDER's back-end for 
autocompletion and documentation. Hats off to them!

>From the changelog:

## Version 0.3.3

- Look up symbol in ClojureDocs.
- Inline documentation in auto-complete.
- Much better auto-complete, thanks to compliment and cider-nrepl.
- Autoselects a free port by default.
- Upgrade to CodeMirror 4.5.
- Interoperable with Emacs/CIDER > v.0.7.0 i.e. auto-adds cider-nrepl 
middleware.
- Hopefully fix an odd intermittent dependency bug (thanks to @jococo).
- App routes now a var for easier hacking on the server (thanks to 
@ticking).
- Write out web-app port to file on startup to enable other tools to 
interoperate.
- Fix version range warning.



Jony

-- 
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: [ANN] Gorilla REPL 0.3.3 - inline docs, CIDER compatibility

2014-09-01 Thread Jony Hudson
Ohh, and there are some new docs on how to use Gorilla alongside your 
favourite editor/IDE:

http://gorilla-repl.org/editors.html


Jony

-- 
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: [ANN] Gorilla REPL 0.3.3 - inline docs, CIDER compatibility

2014-09-01 Thread Beau Fabry
Started looking into Gorilla for use at work today. Even prior to this 
release I was incredibly impressed. Amazing work everyone involved.
 

On Monday, September 1, 2014 9:12:49 PM UTC+10, Jony Hudson wrote:
>
> Ohh, and there are some new docs on how to use Gorilla alongside your 
> favourite editor/IDE:
>
> http://gorilla-repl.org/editors.html
>
>
> Jony
>

-- 
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: [ANN] Gorilla REPL 0.3.3 - inline docs, CIDER compatibility

2014-09-01 Thread Bozhidar Batsov
vim-fireplace uses cider-nrepl (when available, otherwise it will fallback to 
evaling inlined code) as well, so the Emacs rules should apply for it.
—
Cheers, 
Bozhidar

On September 1, 2014 at 2:12:53 PM, Jony Hudson (jonyepsi...@gmail.com) wrote:

Ohh, and there are some new docs on how to use Gorilla alongside your favourite 
editor/IDE:

http://gorilla-repl.org/editors.html


Jony
--
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: [ANN] Gorilla REPL 0.3.3 - inline docs, CIDER compatibility

2014-09-01 Thread Bozhidar Batsov
On September 1, 2014 at 2:11:40 PM, Jony Hudson (jonyepsi...@gmail.com) wrote:
Hi all,

 there's a new version of Gorilla REPL out :-) The headline feature is that the 
autocomplete UI now shows the docs for the function you're typing/lets you 
browse the docs. It's really handy! Autocomplete itself is also much improved, 
courtesy of the compliment library.

This version also adds compatibility with the latest version of CIDER, and a 
number of other smaller fixes and features (see changelog below).

I must give credit here to the CIDER team, who have done a great job of writing 
CIDER's back-end code in a way that it can be re-used by other editors. It must 
have taken some work to do that, and it's a very useful contribution to Clojure 
tooling. Gorilla now uses CIDER's back-end for autocompletion and 
documentation. Hats off to them!
Thanks! :-) You might also find the var-info middleware quite useful - cider 
and fireplace use it for code navigation and enhanced documentation (eldoc and 
a replacement for (doc something) that works for both Clojure(Script) and Java 
symbols).



>From the changelog:

## Version 0.3.3

- Look up symbol in ClojureDocs.
- Inline documentation in auto-complete.
- Much better auto-complete, thanks to compliment and cider-nrepl.
- Autoselects a free port by default.
- Upgrade to CodeMirror 4.5.
- Interoperable with Emacs/CIDER > v.0.7.0 i.e. auto-adds cider-nrepl 
middleware.
- Hopefully fix an odd intermittent dependency bug (thanks to @jococo).
- App routes now a var for easier hacking on the server (thanks to @ticking).
- Write out web-app port to file on startup to enable other tools to 
interoperate.
- Fix version range warning.



Jony
--
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: [ANN] Gorilla REPL 0.3.3 - inline docs, CIDER compatibility

2014-09-01 Thread Jony Hudson
On Monday, 1 September 2014 13:16:36 UTC+1, Bozhidar Batsov wrote:
 

> Thanks! :-) You might also find the var-info middleware quite useful - 
> cider and fireplace use it for code navigation and enhanced documentation 
> (eldoc and a replacement for (doc something) that works for both 
> Clojure(Script) and Java symbols).
>

Yes, I was hoping to get an eldoc style parameter-hint going in this 
release, but realised that I'll need to (at least at some basic level) 
parse the code being edited to find the enclosing form's function symbol. 
So I decided it might be better to consider that alongside other things 
that need to understand the forms, like paredit etc.


Jony 

-- 
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-09-01 Thread Marcus Magnusson
On inspecting the source for memoize, it would actually seem (to my eyes, 
someone please correct me if I'm mistaken) to be using a similar approach 
to what has been suggested earlier in the discussion, with the risk of 
re-computing values at concurrent invocations with the same arguments. So 
using memoize in this case wouldn't actually provide any benefit - 
should've double checked before posting, sorry!


Den måndagen den 1:e september 2014 kl. 11:16:00 UTC+2 skrev Colin Fleming:
>
> Hi Marcus,
>
> That's an interesting approach. My first reaction was that the update is 
> still not atomic, since you have:
>
> (when-not (contains? @cache k)
>   (swap! cache assoc k (calc-value* k)))
>
> Which I thought could cause different clients to see different values 
> depending on the race condition there. But since in theory calc-value* 
> should always return the same value for the same key, at worst you'll just 
> end up swapping the same value in unnecessarily. I'd need to think a bit 
> about the implications of using a memoised function in an atom update to 
> convince myself, but it's a neat idea - thanks!
>
> Cheers,
> Colin
>
>
>
> On 31 August 2014 04:25, Marcus Magnusson > 
> wrote:
>
>> 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  wrote:
>>>
  On 30 August 2014 06:26, Colin Fleming  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

 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, 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+unsub

[ANN] Prone: Exception/debugging middleware

2014-09-01 Thread Christian Johansen
Hi,

Prone (http://clojars.org/prone - http://github.com/magnars/prone) is a new 
middleware for Ring apps that replaces the default exception page with an 
interactive page that presents the exception, stack trace and environment 
data in a more easily understandable way. It can also debug arbitrary data, 
and has a nice little client-side data browser. It's intention is to make 
it a lot easier to find the cause of errors when working on Clojure web 
applications.

Here's a short video demoing it's use: 
https://dl.dropboxusercontent.com/u/3378230/prone-demo.mp4

Hope you find it useful!

Christian

-- 
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: Howto Load Project Namespaces in Leiningen Plugins

2014-09-01 Thread Nelson Morris
When writing lein plugins you have to think about if they should do work in
lein's vm or the project's vm. In this case, since you want to load
namespaces from the project, the work will need to be done in the project's
vm.  This is where `leiningen.core.eval/eval-in-project` is used, to spin
up the project's vm and run forms in it.

The arguments to `l.c.e/eval-in-project` will be the project map, a clojure
form representing what to run, and a clojure form designed to allow
avoidance of the gilardi scenario. The big question here becomes how to
create the first form representing what to run.

Option 1: short syntax quote form + injecting dependency into project
Example: cljx
https://github.com/lynaghk/cljx/blob/master/src/leiningen/cljx.clj#L32 and
https://github.com/lynaghk/cljx/blob/master/src/leiningen/cljx.clj#L20
Disadvantages:

1. Requires injecting a dependency into the project (could also be ok if
the working code already exists in a seperate dep, marg vs lein-marg,
ring-server vs lein-ring, etc).
2. Needs a require for the dependency's helper namespace as part of gilardi
avoidance form.

Option 2: long syntax quote form
Example: leiningen.test
https://github.com/technomancy/leiningen/blob/master/src/leiningen/test.clj#L67
Disadvantages:

1. Have to think in syntax quote vs normal evaluation.
2. Needs a require for each namespace the form uses as part of the gilardi
avoidance form (could be ok if only 1 or 2 ns used).


I generally recommend option 1 as easier to think about, and I believe it
to be more common.

As for why `l.c.e/eval-in-project` was not found, I would hazard a guess
based on limited info that it was not `require`d first.

I'll plug
https://github.com/technomancy/leiningen/blob/master/doc/PLUGINS.md#code-evaluation
and https://www.youtube.com/watch?v=uXebQ7RkhKs as containing similar
information said in different ways, in case it comes across better there.

-
Nelson Morris


On Sun, Aug 31, 2014 at 4:02 PM, Timothy Washington 
wrote:

> Ok,
>
> So I'm trying to write a leiningen plugin that takes some namespace
> arguments. Let's call it **. This is a brand new plugin, so
> everything else is empty, and this value is present: *{:eval-in-leiningen
> true}*. My problem happens when, in the context of the project
> ** is acting on, the plugin code fails. I pass in some
> project-local namespace that I want to eval (which is definitely present).
> And I get this situation:
>
> *Error*
>
> java.lang.Exception: No namespace:  found
>
>
> *Offending Code*
>
> (defn check-foreach-namespace [namespaces]
>
>
>   (let [fnss (filter #(= Fubar (type (var-get %)))
>
>  (vals *(ns-publics (symbol (first namespaces)))*))]
>
>
> (println "filtered-namespace [" fnss "]")))
>
>
> (defn myplugin [project & args]
>
>   (check-foreach-namespace args))
>
>
>
> So then, if I try to require the namespace being passed in, that too fails
> like so:
>
> *Error: *
>
> java.io.FileNotFoundException: Could not locate  on
> classpath:
>
>
> *Offending Code:*
>
> (ns leiningen.chesk
>
>   (:require [clojure.test.check :as tc]
>
> [clojure.test.check.generators :as gen]
>
> [clojure.test.check.properties :as prop]))
>
>
> (defn check-foreach-namespace [namespaces]
>
>
>
>   (let [nss (map *#(require (symbol %))* namespaces)
>
>  fnss (filter #(= clojure.test.check.generators.Generator (type
> (var-get %)))
>
>  (vals (ns-publics (symbol (first nss)]
>
>
> (println "filtered-namespace [" fnss "]")))
>
>
> (defn myplugin [project & args]
>
>   (check-foreach-namespace args))
>
>
> Looking around, I thought I had found some relevant instruction on how to
> handle this gilardi scenario
> .
> So I tried to use *eval-in-project* with and without namespace prefix,
> and with several permutations of quoting. This is the error that occurs.
>
> *Error: *
>
> clojure.lang.Compiler$CompilerException: java.lang.ClassNotFoundException:
> leiningen.core.eval
>
>
> *Offending Code: *
>
> (ns leiningen.chesk
>   (:require [clojure.test.check :as tc]
> [clojure.test.check.generators :as gen]
> [clojure.test.check.properties :as prop]))
>
> (defn check-foreach-namespace [namespaces]
>
>   (let [fnss (filter #(= clojure.test.check.generators.Generator (type
> (var-get %)))
>  (vals (ns-publics (symbol (first namespaces)]
>
> (println "filtered-namespace [" fnss "]")))
>
> (defn myplugin [project & args]
>   (*leiningen.core.eval/eval-in-project* project
>(check-foreach-namespace args)
>(map #(require (symbol %)) args)))
>
>
>
>
> So something that looks like it should be straightforward, is not working
> out as planned. I also can't quite see how other plugins are doing this.
> lein-midje seems a bit cryptic (see here
> 

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

2014-09-01 Thread adrian . medina
Sorry, I overlooked that you already ruled out all IDeref instances. 

On Sunday, August 31, 2014 10:21:39 PM UTC-4, Atamert Ölçgen wrote:

>
>
> On Mon, Sep 1, 2014 at 1:52 AM, > 
> wrote:
>
>> If you don't want to wrap the object in an atom, you can also reify an 
>> object that supports IDeref which returns your object. All reified objects 
>> support IObj out of the box. 
>>
>
> As I said earlier:
>
> ... can't deref it since I can't change the functions that will use it 
>> later.
>
>  
> And again, later:
>
> I can't really pass a list since the first function is expecting the 
>> object I am passing,
>
>
> That was why I was asking how to attach metadata.
>
>  
>
>>
>> On Sunday, August 31, 2014 4:55:58 AM UTC-4, Atamert Ölçgen wrote:
>>
>>> Hi Francis,
>>>
>>>
>>> On Sat, Aug 30, 2014 at 1:34 PM, Francis Avila  
>>> 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?

>>>
>>> It's not an atom-holding object. The only guarantee is that this object 
>>> extends one (or two) of these protocols: http://clecs.muhuk.
>>> com/api/0.2.1/clecs.world.html
>>>
>>> Other than that, it can be anything. A Java class, or a type or a 
>>> record...
>>>
>>>  
>>>


 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") {})
 => #>>> IObj$40298964@302c28cc>
 (meta (meta-AtomHolder (atom "x") {}))
 => {}
 (meta (with-meta (meta-AtomHolder (atom "x") {}) {:a 1}))
 => {:a 1}  

>>>
>>> This is really cool. So I can do (deref (meta-AtomHolder (atom "x") {})) 
>>> and it would return "x", right?
>>>
>>> I have actually managed to solve it using vars, had to move things 
>>> around a bit: https://github.com/muhuk/clecs/blob/master/src/clecs/
>>> world/check.clj#L73
>>>
>>>  
>>>
  
 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 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.

>>>
>>>
>>>
>>> -- 
>>> Kind Regards,
>>> Atamert Ölçgen
>>>
>>> -+-
>>> --+
>>> +++
>>>
>>> www.muhuk.com
>>>  
>>  -- 
>> You received this message because you are

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

2014-09-01 Thread James Reeves
I'm not sure whether this would apply in your case, but have you considered
using a WeakHashMap instead of Clojure's metadata?

- James


On 31 August 2014 09:55, Atamert Ölçgen  wrote:

> Hi Francis,
>
>
> On Sat, Aug 30, 2014 at 1:34 PM, Francis Avila 
> 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?
>>
>
> It's not an atom-holding object. The only guarantee is that this object
> extends one (or two) of these protocols:
> http://clecs.muhuk.com/api/0.2.1/clecs.world.html
>
> Other than that, it can be anything. A Java class, or a type or a record...
>
>
>
>>
>>
>> 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") {})
>> => #> user.proxy$AtomHolderClass$IObj$40298964@302c28cc>
>> (meta (meta-AtomHolder (atom "x") {}))
>> => {}
>> (meta (with-meta (meta-AtomHolder (atom "x") {}) {:a 1}))
>> => {:a 1}
>>
>
> This is really cool. So I can do (deref (meta-AtomHolder (atom "x") {}))
> and it would return "x", right?
>
> I have actually managed to solve it using vars, had to move things around
> a bit:
> https://github.com/muhuk/clecs/blob/master/src/clecs/world/check.clj#L73
>
>
>
>>
>> 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.
>>
>
>
>
> --
> 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 me

Re: [ANN] Gorilla REPL 0.3.3 - inline docs, CIDER compatibility

2014-09-01 Thread Lee Spector


On Sep 1, 2014, at 7:15 AM, Beau Fabry  wrote:

> Started looking into Gorilla for use at work today. Even prior to this 
> release I was incredibly impressed. Amazing work everyone involved.
>  

inc

The new docs feature is a thing of beauty.

 -Lee

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


New Functional Programming Job Opportunities

2014-09-01 Thread Functional Jobs
Here are some functional programming job opportunities that were posted

recently:



Senior Software Engineer (Functional) at McGraw-Hill Education

http://functionaljobs.com/jobs/8737-senior-software-engineer-functional-at-mcgraw-hill-education



Cheers,

Sean Murphy

FunctionalJobs.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: [ANN] Gorilla REPL 0.3.3 - inline docs, CIDER compatibility

2014-09-01 Thread Stuart Halloway
Hi Jony,

Is there a path for using Gorilla REPL from a maven or gradle project?

Thanks,
Stu


On Mon, Sep 1, 2014 at 7:11 AM, Jony Hudson  wrote:

> Hi all,
>
>  there's a new version of Gorilla REPL out :-) The headline feature is
> that the autocomplete UI now shows the docs for the function you're
> typing/lets you browse the docs. It's really handy! Autocomplete itself is
> also much improved, courtesy of the compliment library.
>
> This version also adds compatibility with the latest version of CIDER, and
> a number of other smaller fixes and features (see changelog below).
>
> I must give credit here to the CIDER team, who have done a great job of
> writing CIDER's back-end code in a way that it can be re-used by other
> editors. It must have taken some work to do that, and it's a very useful
> contribution to Clojure tooling. Gorilla now uses CIDER's back-end for
> autocompletion and documentation. Hats off to them!
>
> From the changelog:
>
> ## Version 0.3.3
>
> - Look up symbol in ClojureDocs.
> - Inline documentation in auto-complete.
> - Much better auto-complete, thanks to compliment and cider-nrepl.
> - Autoselects a free port by default.
> - Upgrade to CodeMirror 4.5.
> - Interoperable with Emacs/CIDER > v.0.7.0 i.e. auto-adds cider-nrepl
> middleware.
> - Hopefully fix an odd intermittent dependency bug (thanks to @jococo).
> - App routes now a var for easier hacking on the server (thanks to
> @ticking).
> - Write out web-app port to file on startup to enable other tools to
> interoperate.
> - Fix version range warning.
>
>
>
> Jony
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
> ---
> You received this message because you are subscribed to the Google Groups
> "Clojure" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to clojure+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

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


Re: clojure streams

2014-09-01 Thread Alex Miller
Yeah, will do. Core.async channels and transducers solve similar problems
today.

On Aug 31, 2014, at 2:36 PM, Andy Fingerhut 
wrote:

Found it:

"Don't worry about streams - they lost to chunked seqs. Any vestiges just
need to be removed.   -- Rich"


https://groups.google.com/forum/#!msg/clojure-dev/VcHaPv0s_90/EkGmLyzV7ZoJ

It seems like at least marking the page http://clojure.org/streams near the
top with a message that it is obsolete, and chunked seqs wont out over
streams, would be a good idea for those who come across it.

Andy


On Sun, Aug 31, 2014 at 11:50 AM, Andy Fingerhut 
wrote:

> I have a note in a list of things to do that I have been maintaining that
> says " Remove now-obsolete http://clojure.org/streams
> and any links to it (RH said in 2009 that streams lost to chunked
> sequences)".  I don't have a link handy to that email that suggested this
> change, nor to a quote by Rich Hickey from 2009 saying that streams lost to
> chunked sequences, but they are probably findable via appropriate Google
> searches.
>
> Andy
>
>
> On Fri, Aug 29, 2014 at 11:56 AM, Greg MacDonald 
> wrote:
>
>> Hi Everyone,
>>
>> Does anyone know the status of clojure streams is? I would like to try
>> them out but I can't find the svn repository mentioned on the website:
>> http://clojure.org/streams. Thx!
>>
>> -Greg
>>
>> --
>> You received this message because you are subscribed to the Google
>> Groups "Clojure" group.
>> To post to this group, send email to clojure@googlegroups.com
>> Note that posts from new members are moderated - please be patient with
>> your first post.
>> To unsubscribe from this group, send email to
>> clojure+unsubscr...@googlegroups.com
>> For more options, visit this group at
>> http://groups.google.com/group/clojure?hl=en
>> ---
>> You received this message because you are subscribed to the Google Groups
>> "Clojure" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to clojure+unsubscr...@googlegroups.com.
>> For more options, visit https://groups.google.com/d/optout.
>>
>
>

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


clojure logo copyright

2014-09-01 Thread lavokad l
Hi, I want to design my own t-shirt, cup and maybe something else putting 
on clojure logo and some words on zazzle.es web. On http://clojure.org/swag 
page there is* "Design your own custom tee shirt online at Zazzle". *

So, while it's not for commercial use is it legal to download a clojure 
logo png, upload it to zazzle, put it on the t-shirt, write some phrase and 
buy it? Or does one can use only words, and not logo? Or similar, if I 
write a blog post about some clojure's language aspect, can I add a 
clojure's logo?


-- 
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: Useless Java error messages

2014-09-01 Thread Luc Prefontaine
Where do you see a Java error here ?

I see the Clojure implementation
reporting that you are
trying to apply a numeric operator
to a null/nil value :)

I agree the JVM stack traces are not nice
and polluted by all the frames which
may/may not be relevant.

The messages are not always as clear as
this one either.

You do not have any source file
line number anywhere in the stack
trace pointing to your code ?

Luc P.

> Compiling a file in Emacs, this error:
> 
> "NullPointerException clojure.lang.Numbers.ops (Numbers.java:961)"
> 
> . leaves me clueless as to where the error occurred.
> 
> Is there hope for native Clojure debugging anytime soon as this is the 
> kind of thing which can easily drive a non-Java user like me to 
> distraction? I noticed the Elixir community had the same problem with 
> Erlang's cryptic error messages and produced their own error logging to 
> make the language attractive to non-Erlangers. This seems to me to be 
> perhaps the biggest barrier to entry with hosted languages. We can't 
> expect everyone coming to Clojure to master Java's less-than-helpful 
> error messages. Many will just give up.
> 
> 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.
> 
--
Luc Prefontaine sent by ibisMail!

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


Re: clojure logo copyright

2014-09-01 Thread Alex Miller

On Monday, September 1, 2014 6:58:59 AM UTC-5, lavokad l wrote:
>
> Hi, I want to design my own t-shirt, cup and maybe something else putting 
> on clojure logo and some words on zazzle.es web. On 
> http://clojure.org/swag page there is* "Design your own custom tee shirt 
> online at Zazzle". *
>
> So, while it's not for commercial use is it legal to download a clojure 
> logo png, upload it to zazzle, put it on the t-shirt, write some phrase and 
> buy it? Or does one can use only words, and not logo? Or similar, if I 
> write a blog post about some clojure's language aspect, can I add a 
> clojure's logo?
>

The Clojure logo is copyright Rich Hickey and he does not usually grant 
usage for purposes like this.

Alex

-- 
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: [ANN] Gorilla REPL 0.3.3 - inline docs, CIDER compatibility

2014-09-01 Thread Jony Hudson
Beau, Lee - thanks for the kind words - glad you're enjoying it!

Stu - I've no experience of running Clojure under either maven or gradle, 
but my guess is that it won't work out-of-the-box yet. Currently, Gorilla 
launches by using Leiningen to run its own server process in the classpath 
of the project. The Gorilla server starts up an nREPL server in process and 
connects to that. I've been planning to add the feature to connect to an 
external nREPL server (and also, probably, for "local" connections to 
launch the nREPL server as a separate process). It would then be 
straightforward, I'd imagine, to run an nREPL server from maven/gradle - 
which would take care of the classpath - and have maven/gradle start up the 
gorilla server and connect to nREPL.

I guess a workaroundy way to do it would be if maven/gradle can output the 
classpath for a project, then it might possibly work to run the Gorilla jar 
with the appropriate classpath. I'm not sure about this though as, in 
truth, I don't know exactly what nREPL does when it starts up!


Jony

On Monday, 1 September 2014 17:33:50 UTC+1, stuart@gmail.com wrote:
>
> Hi Jony,
>
> Is there a path for using Gorilla REPL from a maven or gradle project?
>
> Thanks,
> Stu
>
>
>

-- 
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-09-01 Thread Alex Baranosky
I believe you can replace:
(when-not (contains? @cache k)
  (swap! cache assoc k (calc-value* k

with:
(swap! cache (fn [cache']
   (if (contains? cache' k)
 cache'
 (assoc cache' k (calc-value* k)

Note: I haven't run this code


On Mon, Sep 1, 2014 at 2:20 AM, Colin Fleming 
wrote:

> Hi Thomas,
>
> Normally I'd agree with you, but in my case it actually works quite well
> since I don't need to expire or worry about sizing. This is for caching
> objects on IntelliJ parse tree elements, and the element with its cached
> values is thrown away every time the document is parsed, so these are
> pretty transient caches. In this particular case the calculation isn't too
> heavyweight either so recalculating it in the unlikely event of contention
> isn't a big deal. In fact, this discussion and the related thinking has
> made me realise that my original solution was actually sufficient for my
> somewhat strange use case, which is nice :-). For more typical server side
> caching, I agree that Guava would be a great solution.
>
> Cheers,
> Colin
>
>
> On 1 September 2014 20:54, Thomas Heller  wrote:
>
>> As much as I like Clojure and atoms, I do not think they are a good fit
>> for caching. Not only is it impossible to address the concurrency issues
>> related to multiple threads loading the same object, but you also have to
>> do expiration and size management yourself. Immutability doesn't help much
>> for caching either. There is core.cache that does some bits but I probably
>> would recommend using something like CacheBuilder from the guava libs:
>>
>> See
>> https://code.google.com/p/guava-libraries/
>>
>> http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/cache/CacheBuilder.html
>>
>> Its Java but the Clojure<->Java interop is so good that it doesn't matter
>> much.
>>
>> On Saturday, August 30, 2014 7:27:05 AM UTC+2, 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.
>>
>
>  --
> 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/

Re: [ANN] Gorilla REPL 0.3.3 - inline docs, CIDER compatibility

2014-09-01 Thread Stuart Halloway
Hi Jony,

A feature allowing connection to an external nREPL server would be great,
and totally usable by anyone who can make a CLASSPATH.  Having to install a
particular build system (whether gradle, lein, or maven) in order to use a
tool is a non-starter for 90% of the projects I am involved with.

Regards,
Stu


On Mon, Sep 1, 2014 at 12:55 PM, Jony Hudson  wrote:

> Beau, Lee - thanks for the kind words - glad you're enjoying it!
>
> Stu - I've no experience of running Clojure under either maven or gradle,
> but my guess is that it won't work out-of-the-box yet. Currently, Gorilla
> launches by using Leiningen to run its own server process in the classpath
> of the project. The Gorilla server starts up an nREPL server in process and
> connects to that. I've been planning to add the feature to connect to an
> external nREPL server (and also, probably, for "local" connections to
> launch the nREPL server as a separate process). It would then be
> straightforward, I'd imagine, to run an nREPL server from maven/gradle -
> which would take care of the classpath - and have maven/gradle start up the
> gorilla server and connect to nREPL.
>
> I guess a workaroundy way to do it would be if maven/gradle can output the
> classpath for a project, then it might possibly work to run the Gorilla jar
> with the appropriate classpath. I'm not sure about this though as, in
> truth, I don't know exactly what nREPL does when it starts up!
>
>
> Jony
>
>
> On Monday, 1 September 2014 17:33:50 UTC+1, stuart@gmail.com wrote:
>>
>> Hi Jony,
>>
>> Is there a path for using Gorilla REPL from a maven or gradle project?
>>
>> Thanks,
>> Stu
>>
>>
>>  --
> 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-09-01 Thread Marcus Magnusson
I reckon if that worked, there would be no need for memoize anyway, but I 
don't think swap! will allow for it. I'm far from an expert on swap! or 
atoms, but several swap!s may be run simultaneously on a single atom (and 
swap! may re-run the swapping function if the atom has been changed since 
the swapping function was invoked). In other words, if two swap!s are 
invoked at about the same time for the same key (which is not currently in 
the cache), both invocations may be given the same value of the cache at 
that moment, which will lead to the value being re-calculated in both 
invocations - and even if calc-value is memoized, the same thing may occur 
in the memoized function.

As I said, I'm far from an expert, so I wrote a small test that shows that 
calc-value may indeed be called more than once (core.async here is simply 
to ensure that each invocation of calc-value is printed on its own line):


(def out-ch (chan 100))

(go-loop []
  (println ( (dotimes [_ 1000]
 (future (lookup cache (rand-int 20
11
12
16
1
nil
6
15
17
18
14
2
5
19
10
0
7
*9*
*4*
*4*
*13*
*9*
*13*


Den måndagen den 1:e september 2014 kl. 21:32:01 UTC+2 skrev Alex Baranosky:
>
> I believe you can replace:
> (when-not (contains? @cache k)
>   (swap! cache assoc k (calc-value* k
>
> with:
> (swap! cache (fn [cache']
>(if (contains? cache' k)
>  cache'
>  (assoc cache' k (calc-value* k)
>
> Note: I haven't run this code
>
>
> On Mon, Sep 1, 2014 at 2:20 AM, Colin Fleming  > wrote:
>
>> Hi Thomas,
>>
>> Normally I'd agree with you, but in my case it actually works quite well 
>> since I don't need to expire or worry about sizing. This is for caching 
>> objects on IntelliJ parse tree elements, and the element with its cached 
>> values is thrown away every time the document is parsed, so these are 
>> pretty transient caches. In this particular case the calculation isn't too 
>> heavyweight either so recalculating it in the unlikely event of contention 
>> isn't a big deal. In fact, this discussion and the related thinking has 
>> made me realise that my original solution was actually sufficient for my 
>> somewhat strange use case, which is nice :-). For more typical server side 
>> caching, I agree that Guava would be a great solution.
>>
>> Cheers,
>> Colin
>>
>>
>> On 1 September 2014 20:54, Thomas Heller 
>> > wrote:
>>
>>> As much as I like Clojure and atoms, I do not think they are a good fit 
>>> for caching. Not only is it impossible to address the concurrency issues 
>>> related to multiple threads loading the same object, but you also have to 
>>> do expiration and size management yourself. Immutability doesn't help much 
>>> for caching either. There is core.cache that does some bits but I probably 
>>> would recommend using something like CacheBuilder from the guava libs:
>>>
>>> See
>>> https://code.google.com/p/guava-libraries/
>>>
>>> http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/cache/CacheBuilder.html
>>>
>>> Its Java but the Clojure<->Java interop is so good that it doesn't 
>>> matter much.
>>>
>>> On Saturday, August 30, 2014 7:27:05 AM UTC+2, 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 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.

Re: [ANN] Gorilla REPL 0.3.3 - inline docs, CIDER compatibility

2014-09-01 Thread Stuart Halloway
And now, answering part of my own question.  It appears the following
almost "just works" from a maven project that references gorilla:

  (require '[gorilla-repl.core :as gorilla])
  (gorilla/run-gorilla-server {:port 8990})

The only problem is that gorilla's declaration of its own dependencies
appears incomplete.  When I try to run the snippet above, I fail for lack
of org.clojure/tools.nrepl and clojure-complete.  Adding them as explicit
dependencies in my own project fixes the problem.  My quick guess is that
these two libs need to be added to gorilla's own dependencies.  (One
wonders why it works inside of lein...)

Stu



On Mon, Sep 1, 2014 at 12:55 PM, Jony Hudson  wrote:

> Beau, Lee - thanks for the kind words - glad you're enjoying it!
>
> Stu - I've no experience of running Clojure under either maven or gradle,
> but my guess is that it won't work out-of-the-box yet. Currently, Gorilla
> launches by using Leiningen to run its own server process in the classpath
> of the project. The Gorilla server starts up an nREPL server in process and
> connects to that. I've been planning to add the feature to connect to an
> external nREPL server (and also, probably, for "local" connections to
> launch the nREPL server as a separate process). It would then be
> straightforward, I'd imagine, to run an nREPL server from maven/gradle -
> which would take care of the classpath - and have maven/gradle start up the
> gorilla server and connect to nREPL.
>
> I guess a workaroundy way to do it would be if maven/gradle can output the
> classpath for a project, then it might possibly work to run the Gorilla jar
> with the appropriate classpath. I'm not sure about this though as, in
> truth, I don't know exactly what nREPL does when it starts up!
>
>
> Jony
>
>
> On Monday, 1 September 2014 17:33:50 UTC+1, stuart@gmail.com wrote:
>>
>> Hi Jony,
>>
>> Is there a path for using Gorilla REPL from a maven or gradle project?
>>
>> Thanks,
>> Stu
>>
>>
>>  --
> 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: [ANN] Gorilla REPL 0.3.3 - inline docs, CIDER compatibility

2014-09-01 Thread Gary Trakhman
It works inside of lein because lein adds REPL-y to the classpath of the
project, which adds clojure-complete.  Cider used to be coupled to this
before we gutted it.


On Mon, Sep 1, 2014 at 4:56 PM, Stuart Halloway 
wrote:

> And now, answering part of my own question.  It appears the following
> almost "just works" from a maven project that references gorilla:
>
>   (require '[gorilla-repl.core :as gorilla])
>   (gorilla/run-gorilla-server {:port 8990})
>
> The only problem is that gorilla's declaration of its own dependencies
> appears incomplete.  When I try to run the snippet above, I fail for lack
> of org.clojure/tools.nrepl and clojure-complete.  Adding them as explicit
> dependencies in my own project fixes the problem.  My quick guess is that
> these two libs need to be added to gorilla's own dependencies.  (One
> wonders why it works inside of lein...)
>
> Stu
>
>
>
> On Mon, Sep 1, 2014 at 12:55 PM, Jony Hudson 
> wrote:
>
>> Beau, Lee - thanks for the kind words - glad you're enjoying it!
>>
>> Stu - I've no experience of running Clojure under either maven or gradle,
>> but my guess is that it won't work out-of-the-box yet. Currently, Gorilla
>> launches by using Leiningen to run its own server process in the classpath
>> of the project. The Gorilla server starts up an nREPL server in process and
>> connects to that. I've been planning to add the feature to connect to an
>> external nREPL server (and also, probably, for "local" connections to
>> launch the nREPL server as a separate process). It would then be
>> straightforward, I'd imagine, to run an nREPL server from maven/gradle -
>> which would take care of the classpath - and have maven/gradle start up the
>> gorilla server and connect to nREPL.
>>
>> I guess a workaroundy way to do it would be if maven/gradle can output
>> the classpath for a project, then it might possibly work to run the Gorilla
>> jar with the appropriate classpath. I'm not sure about this though as, in
>> truth, I don't know exactly what nREPL does when it starts up!
>>
>>
>> Jony
>>
>>
>> On Monday, 1 September 2014 17:33:50 UTC+1, stuart@gmail.com wrote:
>>>
>>> Hi Jony,
>>>
>>> Is there a path for using Gorilla REPL from a maven or gradle project?
>>>
>>> Thanks,
>>> Stu
>>>
>>>
>>>  --
>> 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.
>

-- 
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: [ANN] Gorilla REPL 0.3.3 - inline docs, CIDER compatibility

2014-09-01 Thread Jony Hudson
Ahh, nice, yes that's a simple way to do it if you can manage to add the 
code somewhere.

Regarding the dependencies - Leiningen adds both of the dependencies you 
list. I did declare them explicitly at one point, but I recall having some 
odd error, so I decided to take them back out rather than debug it! It's 
possibly related to this, but like I say I didn't put any time into 
investigating it, so could be a red 
herring: https://github.com/technomancy/leiningen/issues/1569


Jony


On Monday, 1 September 2014 21:57:07 UTC+1, stuart@gmail.com wrote:
>
> And now, answering part of my own question.  It appears the following 
> almost "just works" from a maven project that references gorilla:
>
>   (require '[gorilla-repl.core :as gorilla])
>   (gorilla/run-gorilla-server {:port 8990})
>
> The only problem is that gorilla's declaration of its own dependencies 
> appears incomplete.  When I try to run the snippet above, I fail for lack 
> of org.clojure/tools.nrepl and clojure-complete.  Adding them as explicit 
> dependencies in my own project fixes the problem.  My quick guess is that 
> these two libs need to be added to gorilla's own dependencies.  (One 
> wonders why it works inside of lein...)
>
> Stu
>
>

-- 
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: [ANN] Gorilla REPL 0.3.3 - inline docs, CIDER compatibility

2014-09-01 Thread Stuart Halloway
Hi Jony,

I sent you a pull request.  I believe adding those items is correct and
necessary for producing a usable JAR, and that the build works so long as
you have a recent version of leiningen.

Stu


On Mon, Sep 1, 2014 at 5:04 PM, Jony Hudson  wrote:

> Ahh, nice, yes that's a simple way to do it if you can manage to add the
> code somewhere.
>
> Regarding the dependencies - Leiningen adds both of the dependencies you
> list. I did declare them explicitly at one point, but I recall having some
> odd error, so I decided to take them back out rather than debug it! It's
> possibly related to this, but like I say I didn't put any time into
> investigating it, so could be a red herring:
> https://github.com/technomancy/leiningen/issues/1569
>
>
> Jony
>
>
> On Monday, 1 September 2014 21:57:07 UTC+1, stuart@gmail.com wrote:
>>
>> And now, answering part of my own question.  It appears the following
>> almost "just works" from a maven project that references gorilla:
>>
>>   (require '[gorilla-repl.core :as gorilla])
>>   (gorilla/run-gorilla-server {:port 8990})
>>
>> The only problem is that gorilla's declaration of its own dependencies
>> appears incomplete.  When I try to run the snippet above, I fail for lack
>> of org.clojure/tools.nrepl and clojure-complete.  Adding them as explicit
>> dependencies in my own project fixes the problem.  My quick guess is that
>> these two libs need to be added to gorilla's own dependencies.  (One
>> wonders why it works inside of lein...)
>>
>> Stu
>>
>>  --
> 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-09-01 Thread Marcus Magnusson
Huh, I gave it some more thought - of course, the reason why memoize won't 
help us here is that there is no synchronization between simultaneous 
invocations with the same set of arguments. This is typically not a problem 
if the underlying function is fast, but in our case it would be neat with 
an alternative. I got the idea of writing a channel-based version of 
memoize, which will ensure that invoking the memoized function 
simultaneously with the same arguments will only call the underlying 
function once. Below is a quick implementation with one obvious drawback 
(and probably tons of bugs and points of improvement!), namely that if the 
underlying function is costly, and we invoke the memoized function with a 
bunch of different non-cached set of arguments, then calculating the values 
will be done one-by-one. This could be fixed for example by having 
handle-ch delegate to another channel, where we have one channel per set of 
arguments - I'll leave that for someone else, or for when I've had some 
sleep and realized what a bad idea it was...  :) Note that I haven't worked 
much with core.async, and that there is probably a much more 
straightforward solution (for example the one given by Thomas Heller), so 
please let me know of any issues with this:


(defn synced-memoize [f]
  (let [mem (atom {})
handle-ch (chan)]
(go-loop []
  (let [[args ret-ch] (! ret-ch (if-let [e (find @mem args)]
 (val e)
 (let [ret (apply f args)]
   (swap! mem assoc args ret)
   ret)))
(recur)))
(fn [& args]
  (if-let [e (find @mem args)]
(val e)
(let [ret (chan)]
  (>!! handle-ch [args ret])
  (
> I reckon if that worked, there would be no need for memoize anyway, but I 
> don't think swap! will allow for it. I'm far from an expert on swap! or 
> atoms, but several swap!s may be run simultaneously on a single atom (and 
> swap! may re-run the swapping function if the atom has been changed since 
> the swapping function was invoked). In other words, if two swap!s are 
> invoked at about the same time for the same key (which is not currently in 
> the cache), both invocations may be given the same value of the cache at 
> that moment, which will lead to the value being re-calculated in both 
> invocations - and even if calc-value is memoized, the same thing may occur 
> in the memoized function.
>
> As I said, I'm far from an expert, so I wrote a small test that shows that 
> calc-value may indeed be called more than once (core.async here is simply 
> to ensure that each invocation of calc-value is printed on its own line):
>
>
> (def out-ch (chan 100))
>
> (go-loop []
>   (println (   (recur))
>
> (defn calc-value [x]
>   (put! out-ch x)
>   (* x x))
>
> (def cache (atom {}))
>
> (def lookup
>   (let [calc-value* (memoize calc-value)]
> (fn [cache key]
>   ((swap! cache (fn [cache']
>   (if (contains? cache' key)
> cache'
> (assoc cache' key (calc-value* key)
> key
>
>
> => (dotimes [_ 1000]
>  (future (lookup cache (rand-int 20
> 11
> 12
> 16
> 1
> nil
> 6
> 15
> 17
> 18
> 14
> 2
> 5
> 19
> 10
> 0
> 7
> *9*
> *4*
> *4*
> *13*
> *9*
> *13*
>
>
> Den måndagen den 1:e september 2014 kl. 21:32:01 UTC+2 skrev Alex 
> Baranosky:
>>
>> I believe you can replace:
>> (when-not (contains? @cache k)
>>   (swap! cache assoc k (calc-value* k
>>
>> with:
>> (swap! cache (fn [cache']
>>(if (contains? cache' k)
>>  cache'
>>  (assoc cache' k (calc-value* k)
>>
>> Note: I haven't run this code
>>
>>
>> On Mon, Sep 1, 2014 at 2:20 AM, Colin Fleming  
>> wrote:
>>
>>> Hi Thomas,
>>>
>>> Normally I'd agree with you, but in my case it actually works quite well 
>>> since I don't need to expire or worry about sizing. This is for caching 
>>> objects on IntelliJ parse tree elements, and the element with its cached 
>>> values is thrown away every time the document is parsed, so these are 
>>> pretty transient caches. In this particular case the calculation isn't too 
>>> heavyweight either so recalculating it in the unlikely event of contention 
>>> isn't a big deal. In fact, this discussion and the related thinking has 
>>> made me realise that my original solution was actually sufficient for my 
>>> somewhat strange use case, which is nice :-). For more typical server side 
>>> caching, I agree that Guava would be a great solution.
>>>
>>> Cheers,
>>> Colin
>>>
>>>
>>> On 1 September 2014 20:54, Thomas Heller  wrote:
>>>
 As much as I like Clojure and atoms, I do not think they are a good fit 
 for caching. Not only is it impossible to address the concurrency issues 
 related to multiple threads loading the same object, but you also have to 
 do expiration and size management yourself. Immutability doesn't help much 
 for cac

Re: Useless Java error messages

2014-09-01 Thread gvim

On 01/09/2014 17:50, Luc Prefontaine wrote:

Where do you see a Java error here ?

I see the Clojure implementation
reporting that you are
trying to apply a numeric operator
to a null/nil value :)

I agree the JVM stack traces are not nice
and polluted by all the frames which
may/may not be relevant.

The messages are not always as clear as
this one either.

You do not have any source file
line number anywhere in the stack
trace pointing to your code ?

Luc P.



Sorry, I was a bit trigger-happy with this one. Turns out it was Emacs 
cider truncating the stack trace to a single line. Someone on IRC 
pointed me to `(pst)` within Emacs cider which displays the full stack 
trace.


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: Useless Java error messages

2014-09-01 Thread Softaddicts
Ah ! Emacs, an old friend that I should eventually revisit after 30 years...
Long time no see :)

Luc P.

> On 01/09/2014 17:50, Luc Prefontaine wrote:
> > Where do you see a Java error here ?
> >
> > I see the Clojure implementation
> > reporting that you are
> > trying to apply a numeric operator
> > to a null/nil value :)
> >
> > I agree the JVM stack traces are not nice
> > and polluted by all the frames which
> > may/may not be relevant.
> >
> > The messages are not always as clear as
> > this one either.
> >
> > You do not have any source file
> > line number anywhere in the stack
> > trace pointing to your code ?
> >
> > Luc P.
> >
> 
> Sorry, I was a bit trigger-happy with this one. Turns out it was Emacs 
> cider truncating the stack trace to a single line. Someone on IRC 
> pointed me to `(pst)` within Emacs cider which displays the full stack 
> trace.
> 
> 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.
> 
--
Softaddicts sent by ibisMail from my ipad!

-- 
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-09-01 Thread Marcus Magnusson
Forget about sleep, there's work to be done! I realized that the drawback I 
mentioned with my solution, where concurrent calls to the memoized function 
with different sets of arguments would be handled one-by-one, could easily 
be resolved by having the cache inside synced-memoize store futures for 
calculating the value, rather than the value itself - some small changes 
and everything should hopefully work well (don't ask me about overhead, 
though!)


(defn synced-memoize [f]
  (let [mem (atom {})
handle-ch (chan)]
(go-loop []
  (let [[args ret-ch] (! ret-ch (if-let [e (find @mem args)]
 (val e)
 (let [ret (future (apply f args))]
   (swap! mem assoc args ret)
   ret)))
(recur)))
(fn [& args]
  (if-let [e (find @mem args)]
(deref (val e))
(let [ret (chan)]
  (>!! handle-ch [args ret])
  (deref (
> Huh, I gave it some more thought - of course, the reason why memoize won't 
> help us here is that there is no synchronization between simultaneous 
> invocations with the same set of arguments. This is typically not a problem 
> if the underlying function is fast, but in our case it would be neat with 
> an alternative. I got the idea of writing a channel-based version of 
> memoize, which will ensure that invoking the memoized function 
> simultaneously with the same arguments will only call the underlying 
> function once. Below is a quick implementation with one obvious drawback 
> (and probably tons of bugs and points of improvement!), namely that if the 
> underlying function is costly, and we invoke the memoized function with a 
> bunch of different non-cached set of arguments, then calculating the values 
> will be done one-by-one. This could be fixed for example by having 
> handle-ch delegate to another channel, where we have one channel per set of 
> arguments - I'll leave that for someone else, or for when I've had some 
> sleep and realized what a bad idea it was...  :) Note that I haven't worked 
> much with core.async, and that there is probably a much more 
> straightforward solution (for example the one given by Thomas Heller), so 
> please let me know of any issues with this:
>
>
> (defn synced-memoize [f]
>   (let [mem (atom {})
> handle-ch (chan)]
> (go-loop []
>   (let [[args ret-ch] ( (>! ret-ch (if-let [e (find @mem args)]
>  (val e)
>  (let [ret (apply f args)]
>(swap! mem assoc args ret)
>ret)))
> (recur)))
> (fn [& args]
>   (if-let [e (find @mem args)]
> (val e)
> (let [ret (chan)]
>   (>!! handle-ch [args ret])
>   (
> (def lookup
>   (let [calc-value* (synced-memoize calc-value)]
> (fn [cache key]
>   (if (contains? @cache key)
> (@cache key)
> (swap! cache assoc key (calc-value* key))
>
>
>
> Den måndagen den 1:e september 2014 kl. 22:35:56 UTC+2 skrev Marcus 
> Magnusson:
>>
>> I reckon if that worked, there would be no need for memoize anyway, but I 
>> don't think swap! will allow for it. I'm far from an expert on swap! or 
>> atoms, but several swap!s may be run simultaneously on a single atom (and 
>> swap! may re-run the swapping function if the atom has been changed since 
>> the swapping function was invoked). In other words, if two swap!s are 
>> invoked at about the same time for the same key (which is not currently in 
>> the cache), both invocations may be given the same value of the cache at 
>> that moment, which will lead to the value being re-calculated in both 
>> invocations - and even if calc-value is memoized, the same thing may occur 
>> in the memoized function.
>>
>> As I said, I'm far from an expert, so I wrote a small test that shows 
>> that calc-value may indeed be called more than once (core.async here is 
>> simply to ensure that each invocation of calc-value is printed on its own 
>> line):
>>
>>
>> (def out-ch (chan 100))
>>
>> (go-loop []
>>   (println (>   (recur))
>>
>> (defn calc-value [x]
>>   (put! out-ch x)
>>   (* x x))
>>
>> (def cache (atom {}))
>>
>> (def lookup
>>   (let [calc-value* (memoize calc-value)]
>> (fn [cache key]
>>   ((swap! cache (fn [cache']
>>   (if (contains? cache' key)
>> cache'
>> (assoc cache' key (calc-value* key)
>> key
>>
>>
>> => (dotimes [_ 1000]
>>  (future (lookup cache (rand-int 20
>> 11
>> 12
>> 16
>> 1
>> nil
>> 6
>> 15
>> 17
>> 18
>> 14
>> 2
>> 5
>> 19
>> 10
>> 0
>> 7
>> *9*
>> *4*
>> *4*
>> *13*
>> *9*
>> *13*
>>
>>
>> Den måndagen den 1:e september 2014 kl. 21:32:01 UTC+2 skrev Alex 
>> Baranosky:
>>>
>>> I believe you can replace:
>>> (when-not (contains? @cache k)
>>>   (swap! cache assoc k (calc-value* k
>>>
>>> with:
>>> (swap! cache (fn [cache']
>>>(if (co

Re: Useless Java error messages

2014-09-01 Thread Beau Fabry
The pretty-errors leiningen plugin might be worth a look

On Tuesday, September 2, 2014 7:58:31 AM UTC+10, g vim wrote:
>
> On 01/09/2014 17:50, Luc Prefontaine wrote: 
> > Where do you see a Java error here ? 
> > 
> > I see the Clojure implementation 
> > reporting that you are 
> > trying to apply a numeric operator 
> > to a null/nil value :) 
> > 
> > I agree the JVM stack traces are not nice 
> > and polluted by all the frames which 
> > may/may not be relevant. 
> > 
> > The messages are not always as clear as 
> > this one either. 
> > 
> > You do not have any source file 
> > line number anywhere in the stack 
> > trace pointing to your code ? 
> > 
> > Luc P. 
> > 
>
> Sorry, I was a bit trigger-happy with this one. Turns out it was Emacs 
> cider truncating the stack trace to a single line. Someone on IRC 
> pointed me to `(pst)` within Emacs cider which displays the full stack 
> trace. 
>
> 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: [ANN] Gorilla REPL 0.3.3 - inline docs, CIDER compatibility

2014-09-01 Thread Beau Fabry
For what it's worth we're using Gorilla *after* leiningen. Leiningen is 
used to make an uberjar, but then we start the gorilla server in our own 
main. This is because we're running gorilla inside of our hadoop 
environment. This way we have a gorilla instance that can issue live 
cascalog queries to the cluster :-)

On Tuesday, September 2, 2014 7:26:51 AM UTC+10, stuart@gmail.com wrote:
>
> Hi Jony,
>
> I sent you a pull request.  I believe adding those items is correct and 
> necessary for producing a usable JAR, and that the build works so long as 
> you have a recent version of leiningen.
>
> Stu
>
>
> On Mon, Sep 1, 2014 at 5:04 PM, Jony Hudson  > wrote:
>
>> Ahh, nice, yes that's a simple way to do it if you can manage to add the 
>> code somewhere.
>>
>> Regarding the dependencies - Leiningen adds both of the dependencies you 
>> list. I did declare them explicitly at one point, but I recall having some 
>> odd error, so I decided to take them back out rather than debug it! It's 
>> possibly related to this, but like I say I didn't put any time into 
>> investigating it, so could be a red herring: 
>> https://github.com/technomancy/leiningen/issues/1569
>>
>>
>> Jony
>>
>>
>> On Monday, 1 September 2014 21:57:07 UTC+1, stuart@gmail.com wrote:
>>>
>>> And now, answering part of my own question.  It appears the following 
>>> almost "just works" from a maven project that references gorilla:
>>>
>>>   (require '[gorilla-repl.core :as gorilla])
>>>   (gorilla/run-gorilla-server {:port 8990})
>>>
>>> The only problem is that gorilla's declaration of its own dependencies 
>>> appears incomplete.  When I try to run the snippet above, I fail for lack 
>>> of org.clojure/tools.nrepl and clojure-complete.  Adding them as explicit 
>>> dependencies in my own project fixes the problem.  My quick guess is that 
>>> these two libs need to be added to gorilla's own dependencies.  (One 
>>> wonders why it works inside of lein...)
>>>
>>> Stu
>>>
>>>  -- 
>> 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: Useless Java error messages

2014-09-01 Thread Jason Wolfe
Looks like you figured this out, but sharing in case it helps others. 

It turns out the JVM actually has a special caching mechanism for making 
NullPointerExceptions fast (and near-impossible to debug):

http://stackoverflow.com/a/3010106

This link also has a JVM opt to stop this optimization, and mentions that 
you always get the full stack trace *once* before it's optimized away.



On Monday, September 1, 2014 7:11:00 AM UTC-7, g vim wrote:
>
> Compiling a file in Emacs, this error: 
>
> "NullPointerException clojure.lang.Numbers.ops (Numbers.java:961)" 
>
> . leaves me clueless as to where the error occurred. 
>
> Is there hope for native Clojure debugging anytime soon as this is the 
> kind of thing which can easily drive a non-Java user like me to 
> distraction? I noticed the Elixir community had the same problem with 
> Erlang's cryptic error messages and produced their own error logging to 
> make the language attractive to non-Erlangers. This seems to me to be 
> perhaps the biggest barrier to entry with hosted languages. We can't 
> expect everyone coming to Clojure to master Java's less-than-helpful 
> error messages. Many will just give up. 
>
> 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: [ANN] Prone: Exception/debugging middleware

2014-09-01 Thread Colin Fleming
I don't do any web dev myself, but Prone looks really nice -
congratulations! Great work.

Cheers,
Colin


On 2 September 2014 02:05, Christian Johansen 
wrote:

> Hi,
>
> Prone (http://clojars.org/prone - http://github.com/magnars/prone) is a
> new middleware for Ring apps that replaces the default exception page with
> an interactive page that presents the exception, stack trace and
> environment data in a more easily understandable way. It can also debug
> arbitrary data, and has a nice little client-side data browser. It's
> intention is to make it a lot easier to find the cause of errors when
> working on Clojure web applications.
>
> Here's a short video demoing it's use:
> https://dl.dropboxusercontent.com/u/3378230/prone-demo.mp4
>
> Hope you find it useful!
>
> Christian
>
> --
> 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: [ANN] Gorilla REPL 0.3.3 - inline docs, CIDER compatibility

2014-09-01 Thread Beau Fabry
Just a little bit of showing off of the previous post 
:-) http://i.imgur.com/zpfP9Ja.png

On Tuesday, September 2, 2014 9:36:50 AM UTC+10, Beau Fabry wrote:
>
> For what it's worth we're using Gorilla *after* leiningen. Leiningen is 
> used to make an uberjar, but then we start the gorilla server in our own 
> main. This is because we're running gorilla inside of our hadoop 
> environment. This way we have a gorilla instance that can issue live 
> cascalog queries to the cluster :-)
>
> On Tuesday, September 2, 2014 7:26:51 AM UTC+10, stuart@gmail.com 
> wrote:
>>
>> Hi Jony,
>>
>> I sent you a pull request.  I believe adding those items is correct and 
>> necessary for producing a usable JAR, and that the build works so long as 
>> you have a recent version of leiningen.
>>
>> Stu
>>
>>
>> On Mon, Sep 1, 2014 at 5:04 PM, Jony Hudson  wrote:
>>
>>> Ahh, nice, yes that's a simple way to do it if you can manage to add the 
>>> code somewhere.
>>>
>>> Regarding the dependencies - Leiningen adds both of the dependencies you 
>>> list. I did declare them explicitly at one point, but I recall having some 
>>> odd error, so I decided to take them back out rather than debug it! It's 
>>> possibly related to this, but like I say I didn't put any time into 
>>> investigating it, so could be a red herring: 
>>> https://github.com/technomancy/leiningen/issues/1569
>>>
>>>
>>> Jony
>>>
>>>
>>> On Monday, 1 September 2014 21:57:07 UTC+1, stuart@gmail.com wrote:

 And now, answering part of my own question.  It appears the following 
 almost "just works" from a maven project that references gorilla:

   (require '[gorilla-repl.core :as gorilla])
   (gorilla/run-gorilla-server {:port 8990})

 The only problem is that gorilla's declaration of its own dependencies 
 appears incomplete.  When I try to run the snippet above, I fail for lack 
 of org.clojure/tools.nrepl and clojure-complete.  Adding them as explicit 
 dependencies in my own project fixes the problem.  My quick guess is that 
 these two libs need to be added to gorilla's own dependencies.  (One 
 wonders why it works inside of lein...)

 Stu

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


[ANN] Constraint Programming in Clojure: clojure2minizinc -- initial release

2014-09-01 Thread Torsten Anders
Dear Clojure community,

clojure2minizinc provides an interface between state-of-the-art constraint 
solvers (via MiniZinc) and Clojure. The clojure2minizinc user models in 
Clojure constraint satisfaction or optimisation problems over Boolean, 
integer, real number, and/or set variables. clojure2minizinc translates 
them into MiniZinc, they are solved in the background by a 
FlatZinc-compatible solver, and the result is read back into Clojure. 
clojure2minizinc code can be very similar to the corresponding MiniZinc 
code, but in addition the full power of Clojure is at hand.

In the Clojure community there already exists an interest in Constraint 
Programming (and the related Logic Programming paradigm), and solvers have 
been developed for Clojure. In contrast to core.logic, clojure2minizinc 
does not support Logic Programming (e.g., it does not provide unification 
of arbitrary terms), but focusses on Constraint Programming only. Also 
unlike core.logic, clojure2minizinc does not implement any new solver from 
scratch. 

MiniZinc provides an interface to a range of existing state-of-the-art 
constraint solvers, and supports Constraint Programming in a clear more 
mature way than core.logic -- clojure2minizinc inherits its capabilities. 
MiniZinc supports several variable domains (Booleans, integers, floats, and 
set of integers), a rich set of constraints (including many global 
constraints), reified constraints (i.e., the truth value of constraints can 
in turn be constrained by logic relations such as implication or 
equivalence), and optimisation support. Perhaps most importantly, 
MiniZinc's 3rd-party solvers implement highly efficient search strategies.

This is the very first release. clojure2minizinc is far from being 
finished, but enough is already working that it might be interesting :)

For more information including installation details please visit
http://tanders.github.io/clojure2minizinc/

A tutorial is available at 
http://tanders.github.io/clojure2minizinc/tutorial.html

-- 
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: [ANN] Prone: Exception/debugging middleware

2014-09-01 Thread James Reeves
This looks rather nice. I'll certainly be trying it out.

- James


On 2 September 2014 01:06, Colin Fleming 
wrote:

> I don't do any web dev myself, but Prone looks really nice -
> congratulations! Great work.
>
> Cheers,
> Colin
>
>
> On 2 September 2014 02:05, Christian Johansen 
> wrote:
>
>> Hi,
>>
>> Prone (http://clojars.org/prone - http://github.com/magnars/prone) is a
>> new middleware for Ring apps that replaces the default exception page with
>> an interactive page that presents the exception, stack trace and
>> environment data in a more easily understandable way. It can also debug
>> arbitrary data, and has a nice little client-side data browser. It's
>> intention is to make it a lot easier to find the cause of errors when
>> working on Clojure web applications.
>>
>> Here's a short video demoing it's use:
>> https://dl.dropboxusercontent.com/u/3378230/prone-demo.mp4
>>
>> Hope you find it useful!
>>
>> Christian
>>
>> --
>> 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.
>

-- 
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: Howto Load Project Namespaces in Leiningen Plugins

2014-09-01 Thread Timothy Washington
Awesome, thanks for the feedback. That all makes sense. And yes, the work
will be done in the project's VM.

I guess what I'm missing is something more basic. If you look at lein-midje

or lein-spec
,
they're doing straightforward requires of *eval-in-project*. Yet, I'll get
an error, even for a stripped down version. So take the below example. I'm
locally installing the lein plugin, and running it from a separate project
with "*lein chesk fubar*".  Still an error loading eval-in-project. I
looked through some other leiningen projects. None of them are bundling
some leiningen core library. I'm sure it'll be a simple switch that'll make
sense, once I figure it out.

*error*

$ lein chesk bkell.domain.user-check
clojure.lang.Compiler$CompilerException: java.lang.RuntimeException: *Unable
to resolve symbol: eval-in-project in this context,
compiling:(leiningen/chesk.clj:16:3)*
 at clojure.lang.Compiler.analyze (Compiler.java:6464)
clojure.lang.Compiler.analyze (Compiler.java:6406)
clojure.lang.Compiler$InvokeExpr.parse (Compiler.java:3665)
...


*project.clj *

(defproject chesk "0.1.0-SNAPSHOT"
  :description "FIXME: write description"
  :url "http://example.com/FIXME";
  :license {:name "Eclipse Public License"
:url "http://www.eclipse.org/legal/epl-v10.html"}
  :eval-in-leiningen true)


*chesk.clj *

(ns leiningen.chesk
  (:require [leiningen.core.eval :refer [eval-in-project]]))

(defn check-foreach-namespace []
  (println "sanity check"))

(defn chesk [project & args]
  (eval-in-project project
  `(check-foreach-namespace)
  '()))



Hmm

Tim Washington
Interruptsoftware.com 



On Mon, Sep 1, 2014 at 10:27 AM, Nelson Morris 
wrote:

> When writing lein plugins you have to think about if they should do work
> in lein's vm or the project's vm. In this case, since you want to load
> namespaces from the project, the work will need to be done in the project's
> vm.  This is where `leiningen.core.eval/eval-in-project` is used, to spin
> up the project's vm and run forms in it.
>
> The arguments to `l.c.e/eval-in-project` will be the project map, a
> clojure form representing what to run, and a clojure form designed to allow
> avoidance of the gilardi scenario. The big question here becomes how to
> create the first form representing what to run.
>
> Option 1: short syntax quote form + injecting dependency into project
> Example: cljx
> https://github.com/lynaghk/cljx/blob/master/src/leiningen/cljx.clj#L32
>  and
> https://github.com/lynaghk/cljx/blob/master/src/leiningen/cljx.clj#L20
> Disadvantages:
>
> 1. Requires injecting a dependency into the project (could also be ok if
> the working code already exists in a seperate dep, marg vs lein-marg,
> ring-server vs lein-ring, etc).
> 2. Needs a require for the dependency's helper namespace as part of
> gilardi avoidance form.
>
> Option 2: long syntax quote form
> Example: leiningen.test
> https://github.com/technomancy/leiningen/blob/master/src/leiningen/test.clj#L67
> Disadvantages:
>
> 1. Have to think in syntax quote vs normal evaluation.
> 2. Needs a require for each namespace the form uses as part of the gilardi
> avoidance form (could be ok if only 1 or 2 ns used).
>
>
> I generally recommend option 1 as easier to think about, and I believe it
> to be more common.
>
> As for why `l.c.e/eval-in-project` was not found, I would hazard a guess
> based on limited info that it was not `require`d first.
>
> I'll plug
> https://github.com/technomancy/leiningen/blob/master/doc/PLUGINS.md#code-evaluation
> and https://www.youtube.com/watch?v=uXebQ7RkhKs as containing similar
> information said in different ways, in case it comes across better there.
>
> -
> Nelson Morris
>
>
> On Sun, Aug 31, 2014 at 4:02 PM, Timothy Washington 
> wrote:
>
>> Ok,
>>
>> So I'm trying to write a leiningen plugin that takes some namespace
>> arguments. Let's call it **. This is a brand new plugin, so
>> everything else is empty, and this value is present: *{:eval-in-leiningen
>> true}*. My problem happens when, in the context of the project
>> ** is acting on, the plugin code fails. I pass in some
>> project-local namespace that I want to eval (which is definitely present).
>> And I get this situation:
>>
>> *Error*
>>
>> java.lang.Exception: No namespace:  found
>>
>>
>> *Offending Code*
>>
>> (defn check-foreach-namespace [namespaces]
>>
>>
>>   (let [fnss (filter #(= Fubar (type (var-get %)))
>>
>>  (vals *(ns-publics (symbol (first namespaces)))*))]
>>
>>
>> (println "filtered-namespace [" fnss "]")))
>>
>>
>> (defn myplugin [project & args]
>>
>>   (check-foreach-namespace args))
>>
>>
>>
>> So then, if I try to require the namespace being passed in, that too
>> fails like so:
>>
>> *Error: *
>>
>> ja

Re: Howto Load Project Namespaces in Leiningen Plugins

2014-09-01 Thread Timothy Washington
Or (ignoring the previous) getting even more basic...

*$ tree*

.
|-- LICENSE
|-- pom.xml
|-- project.clj
|-- README.md
`-- src
`-- leiningen
`-- zzz.clj



*$ cat src/leiningen/zzz.clj *

(ns leiningen.zzz
  (:require [leiningen.core.eval :refer [eval-in-project]]))

(defn zz [] (println "Hi!"))
(defn zzz [project & args]
  (eval-in-project project
   `(zz)
   '(require 'leiningen.zzz)))



*$ lein zzz*

Exception in thread "main" java.io.FileNotFoundException: Could not locate
leiningen/zzz__init.class or leiningen/zzz.clj on classpath: ,
compiling:(/tmp/form-init8179496390342821964.clj:1:4)
at clojure.lang.Compiler.load(Compiler.java:7142)
...
at clojure.main.main(main.java:37)
Caused by: java.io.FileNotFoundException: Could not locate
leiningen/zzz__init.class or leiningen/zzz.clj on classpath:
at clojure.lang.RT.load(RT.java:443)
...
at clojure.lang.Compiler.load(Compiler.java:7130)
... 11 more
Subprocess failed



Tim Washington
Interruptsoftware.com 



On Mon, Sep 1, 2014 at 10:58 PM, Timothy Washington 
wrote:

> Awesome, thanks for the feedback. That all makes sense. And yes, the work
> will be done in the project's VM.
>
> I guess what I'm missing is something more basic. If you look at
> lein-midje
> 
> or lein-spec
> ,
> they're doing straightforward requires of *eval-in-project*. Yet, I'll
> get an error, even for a stripped down version. So take the below example.
> I'm locally installing the lein plugin, and running it from a separate
> project with "*lein chesk fubar*".  Still an error loading
> eval-in-project. I looked through some other leiningen projects. None of
> them are bundling some leiningen core library. I'm sure it'll be a simple
> switch that'll make sense, once I figure it out.
>
> *error*
>
> $ lein chesk bkell.domain.user-check
> clojure.lang.Compiler$CompilerException: java.lang.RuntimeException: *Unable
> to resolve symbol: eval-in-project in this context,
> compiling:(leiningen/chesk.clj:16:3)*
>  at clojure.lang.Compiler.analyze (Compiler.java:6464)
> clojure.lang.Compiler.analyze (Compiler.java:6406)
> clojure.lang.Compiler$InvokeExpr.parse (Compiler.java:3665)
> ...
>
>
> *project.clj *
>
> (defproject chesk "0.1.0-SNAPSHOT"
>   :description "FIXME: write description"
>   :url "http://example.com/FIXME";
>   :license {:name "Eclipse Public License"
> :url "http://www.eclipse.org/legal/epl-v10.html"}
>   :eval-in-leiningen true)
>
>
> *chesk.clj *
>
> (ns leiningen.chesk
>   (:require [leiningen.core.eval :refer [eval-in-project]]))
>
> (defn check-foreach-namespace []
>   (println "sanity check"))
>
> (defn chesk [project & args]
>   (eval-in-project project
>   `(check-foreach-namespace)
>   '()))
>
>
>
> Hmm
>
> Tim Washington
> Interruptsoftware.com 
>
>
>
> On Mon, Sep 1, 2014 at 10:27 AM, Nelson Morris 
> wrote:
>
>> When writing lein plugins you have to think about if they should do work
>> in lein's vm or the project's vm. In this case, since you want to load
>> namespaces from the project, the work will need to be done in the project's
>> vm.  This is where `leiningen.core.eval/eval-in-project` is used, to spin
>> up the project's vm and run forms in it.
>>
>> The arguments to `l.c.e/eval-in-project` will be the project map, a
>> clojure form representing what to run, and a clojure form designed to allow
>> avoidance of the gilardi scenario. The big question here becomes how to
>> create the first form representing what to run.
>>
>> Option 1: short syntax quote form + injecting dependency into project
>> Example: cljx
>> https://github.com/lynaghk/cljx/blob/master/src/leiningen/cljx.clj#L32
>>  and
>> https://github.com/lynaghk/cljx/blob/master/src/leiningen/cljx.clj#L20
>> Disadvantages:
>>
>> 1. Requires injecting a dependency into the project (could also be ok if
>> the working code already exists in a seperate dep, marg vs lein-marg,
>> ring-server vs lein-ring, etc).
>> 2. Needs a require for the dependency's helper namespace as part of
>> gilardi avoidance form.
>>
>> Option 2: long syntax quote form
>> Example: leiningen.test
>> https://github.com/technomancy/leiningen/blob/master/src/leiningen/test.clj#L67
>> Disadvantages:
>>
>> 1. Have to think in syntax quote vs normal evaluation.
>> 2. Needs a require for each namespace the form uses as part of the
>> gilardi avoidance form (could be ok if only 1 or 2 ns used).
>>
>>
>> I generally recommend option 1 as easier to think about, and I believe it
>> to be more common.
>>
>> As for why `l.c.e/eval-in-project` was not found, I would hazard a guess
>> based on limited info that it was not `require`d first.
>>
>> I'll plug

Re: Howto Load Project Namespaces in Leiningen Plugins

2014-09-01 Thread Timothy Washington
Ok, I figured it out... :) Something in my "*~/.lein/profiles.clj*" was
screwing things up. It was one of the repl-options, because when I turned
those off, things just started to work. Hope this helps someone in future.

#_:repl-options #_{:nrepl-middleware
 [ritz.nrepl.middleware.javadoc/wrap-javadoc
  ritz.nrepl.middleware.simple-complete/wrap-simple-complete
  inspector.middleware/wrap-inspect]}}



Tim Washington
Interruptsoftware.com 


On Mon, Sep 1, 2014 at 11:17 PM, Timothy Washington 
wrote:

> Or (ignoring the previous) getting even more basic...
>
>

-- 
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: [ANN] Prone: Exception/debugging middleware

2014-09-01 Thread Kurt Schrader
Outstanding work! 




Just plugged it locally and used it to debug a particularly hairy issue on my 
side. This is super useful.




-Kurt

On Mon, Sep 1, 2014 at 10:48 PM, James Reeves 
wrote:

> This looks rather nice. I'll certainly be trying it out.
> - James
> On 2 September 2014 01:06, Colin Fleming 
> wrote:
>> I don't do any web dev myself, but Prone looks really nice -
>> congratulations! Great work.
>>
>> Cheers,
>> Colin
>>
>>
>> On 2 September 2014 02:05, Christian Johansen 
>> wrote:
>>
>>> Hi,
>>>
>>> Prone (http://clojars.org/prone - http://github.com/magnars/prone) is a
>>> new middleware for Ring apps that replaces the default exception page with
>>> an interactive page that presents the exception, stack trace and
>>> environment data in a more easily understandable way. It can also debug
>>> arbitrary data, and has a nice little client-side data browser. It's
>>> intention is to make it a lot easier to find the cause of errors when
>>> working on Clojure web applications.
>>>
>>> Here's a short video demoing it's use:
>>> https://dl.dropboxusercontent.com/u/3378230/prone-demo.mp4
>>>
>>> Hope you find it useful!
>>>
>>> Christian
>>>
>>> --
>>> 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.
>>
> -- 
> 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: [ANN] Prone: Exception/debugging middleware

2014-09-01 Thread László Török
Fantastic!


2014-09-02 5:35 GMT+01:00 Kurt Schrader :

> Outstanding work!
>
> Just plugged it locally and used it to debug a particularly hairy issue on
> my side. This is super useful.
>
> -Kurt
>
>
> On Mon, Sep 1, 2014 at 10:48 PM, James Reeves 
> wrote:
>
>> This looks rather nice. I'll certainly be trying it out.
>>
>> - James
>>
>>
>> On 2 September 2014 01:06, Colin Fleming 
>> wrote:
>>
>>>  I don't do any web dev myself, but Prone looks really nice -
>>> congratulations! Great work.
>>>
>>> Cheers,
>>> Colin
>>>
>>>
>>> On 2 September 2014 02:05, Christian Johansen 
>>> wrote:
>>>
 Hi,

 Prone (http://clojars.org/prone - http://github.com/magnars/prone) is
 a new middleware for Ring apps that replaces the default exception page
 with an interactive page that presents the exception, stack trace and
 environment data in a more easily understandable way. It can also debug
 arbitrary data, and has a nice little client-side data browser. It's
 intention is to make it a lot easier to find the cause of errors when
 working on Clojure web applications.

 Here's a short video demoing it's use:
 https://dl.dropboxusercontent.com/u/3378230/prone-demo.mp4

 Hope you find it useful!

 Christian

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



-- 
László Török
Checkout Lollyrewards.com  - Giving credit,
getting credit.

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