Re: lazy-seq and somewhat greedy apply

2016-06-02 Thread Andy L
> 1- concat is defined to have 4 different arities: 0-arg, 1-arg, 2-arg,
> 3+args. In order to figure out which arity to use, apply has to realize at
> least as many elements as the minimum number of args required by the
> largest arity, which in this case is 3
> 2- apply has a small bug that causes it to realize one element more than
> necessary, in this case making it realize 4 elements rather than 3, here's
> a ticket with a patch fixing that issue:
> http://dev.clojure.org/jira/browse/CLJ-1583
>
>
Thx for the explanation. In my original code, I have a "lazy" sequence of a
size determined by specified in the content and the entire thing read of
I/O without a way of telling that I/O is closed. "read" function hangs and
blocks the code if performed too many times.

I redesigned my code to avoid that combination.

Best,
Andy

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


lazy-seq and somewhat greedy apply

2016-06-02 Thread Andy L
Hi,

I have a riddle I am not sure how to solve:
```
user=> (defn just-a-demo-seq[] (println "in just-a-demo-seq") [1 2 3 4 5 6
7 8 9])
#'user/just-a-demo-seq
user=> (def do-not-print-it (apply concat (repeatedly just-a-demo-seq)))
in just-a-demo-seq
in just-a-demo-seq
in just-a-demo-seq
in just-a-demo-seq
#'user/do-not-print-it
```

Question is why `just-a-demo-seq` is invoked 4 times.

We spent some time trying to answer the question to the point of analyzing
RT.java and core.clj and pretty much ruled out `concat`. It seems that
`apply` os somewhat greedy exercising too many elements of the lazy
sequence.

Any insight?

Thanks,
Andy

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


changes in logging in 1.8?

2016-03-10 Thread Andy L
Hi,

I noticed that after upgrade to Clojure  1.8.0 (from 1.7.0) a weird
occurrence of logging, even during uberjar generation which looks like
this, using lein 2.5.3:

$ lein uberjar
Compiling core
2016-03-10 22:11:23.030:INFO::main: Logging initialized @964ms

I believe that actual log is pegged from here
https://github.com/eclipse/jetty.project/blob/master/jetty-util/src/main/java/org/eclipse/jetty/util/log/Log.java#L186
, which gniazdo depend on.

I spend some time trying to better understand the underlying cause but
failed to do so. My questions are:
 1) why client code would be executed during uberjar generation (provided
my assumption is valid)?
 2) what changed in 1.8 to cause that?

Thanks in advance,
Andy


= sources 
$ cat project.clj src/core.clj
(defproject tmp "0.1.0-SNAPSHOT"
  :dependencies [[org.clojure/clojure "1.8.0"] [stylefruits/gniazdo
"0.4.1"]]
  :profiles {:uberjar {:aot :all}})
(ns core
  (:require [gniazdo.core :as ws]))

-- 
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: lazy-seq and threads

2015-09-16 Thread Andy L
Gerrit,

Yes, I do compare apples to oranges, but my orange looks like a nice
Macintosh apple when run in a single thread :-). What I do not expect is
that lack of symmetry in a multiple thread situation and weird JVM CPU
spikes.

WRT to encoding - thanks for the hint - I removed ASCII one from Java
version and it did not make any difference. I also run your version with
lazy-seq replaced with an explicit loop/recur and this weird effect is
gone, making Clojure version performing relatively as well as in a single
thread. Interesting data point. Still lazy-seq does not cause it when
reading file without compression though, as it performs almost as fast as
Java version in a multi threaded context.

Thanks,
Andy


On Wed, Sep 16, 2015 at 2:14 AM, Gerrit Jansen van Vuuren <
gerrit...@gmail.com> wrote:

> one more thing although its unrelated to the performance differences seen:
>
> The Character encoding specified in the Java code is US-ASCII while the
> clojure reader uses UTF-8. Byte to Character encoding can make huge
> differences in text processing apps see
> http://java-performance.info/charset-encoding-decoding-java-78/.
>
> If you know the encoding or can control what it should be use "ISO-8859-1" the
> JDK is optimized for this encoding as it gives a one to one byte copy match.
>
> --
> 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: lazy-seq and threads

2015-09-16 Thread Andy L
Would like to confirm that adding "-XX:+UseSerialGC" cured all the
symptoms. In fact Clojure version with loop/recur runs faster than Java
now. I will update the GitHub repo with all findings later.

Again, thanks for all points and hints. I feel enriched now.

Best regards,
AndyL


On Wed, Sep 16, 2015 at 10:39 AM, Andy L <core.as...@gmail.com> wrote:

> Thanks for the confirmation. I run "jstat" on both cases and it indicates
> a lot of GC in Survivor0 bucket, specifically for "LazySeq+Gzip+2Threads" .
> New area of learning for me though. That would explain spikes and JVM
> pauses.
>
> Best regards,
> Andy
>
> On Wed, Sep 16, 2015 at 9:41 AM, Gerrit Jansen van Vuuren <
> gerrit...@gmail.com> wrote:
>
>>
>> I agree with you that the LazySeq+Gzip+2Threads combination causing a
>> spike is weird.
>>
>>
>>
>> --
>> 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: lazy-seq and threads

2015-09-16 Thread Andy L
Thanks for the confirmation. I run "jstat" on both cases and it indicates a
lot of GC in Survivor0 bucket, specifically for "LazySeq+Gzip+2Threads" .
New area of learning for me though. That would explain spikes and JVM
pauses.

Best regards,
Andy

On Wed, Sep 16, 2015 at 9:41 AM, Gerrit Jansen van Vuuren <
gerrit...@gmail.com> wrote:

>
> I agree with you that the LazySeq+Gzip+2Threads combination causing a
> spike is weird.
>
>
>
> --
> 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: lazy-seq and threads

2015-09-15 Thread Andy L
Hi,

Thanks for looking into my questions. I posted a self contained example
here https://github.com/coreasync/parallel-gzip with instructions how to
create test data as well. Also attached results below I get on my quite
decent hardware (partial 'time' results are mangled, was not sure how to
separate them). I use two separate 'lazy-seq', however I heard somewhere,
that they are not free even if no synchronization takes place, like in this
case but could be optimized out for a single thread situation. Apologies
for jumping into conclusion ... Also, I do not believe that we deal with a
significant amount of IO as those test files easily fit into O/S buffers.

Two test runs below show, that we can easily take advantage of multiple
cores. Java versions scale well. Same in the Clojure code for uncompressed
files. In all 3 cases, resulting in JVM taking a stable 200% of CPU, i.e.
occupying two cores. Also Java and Clojure time numbers are quite
consistent.

However, as soon as I add a GZIPInputStream input stream, Clojure version
start pegging 400, 500, 600% of CPU varying over time. I assumed initially,
taht effort was spend for some thread synchronization tasks as JIT was not
able to factor out due to more code involved. Interestingly enough, YourKit
shows only two threads busy interlaced with empty spaces, almost looking
like JVM being busy doing some kind of house keeping, hitting CPU really
bad. Thread dumps did not reveal anything weird, no locking contention, etc
... I tried Java 7 and 8 as well as Clojure 1.7 and 1.8 - none of make any
difference.

Understanding where that limitation comes from is quite critical, as I try
to use hardware to the best possible extend.

Thanks in advance for hints and clues ...
AndyL


# create test data
$curl -o 1 http://norvig.com/big.txt
$cat 1 1 1 1 1 1 1 1 > 2
$cat 2 2 2 2 2 2 2 2 > 3
$cat 3 3 3 3 3 3 3 3 > 4
$gzip -k 4
$lein run 4
starting...

uncompressed
Java code:
"Elapsed time: 8258.013802 msecs"
(65769984)
"Elapsed time: 8268.641987 msecs"
Clojure code:
"Elapsed time: 9117.814135 msecs"
(65769984)
"Elapsed time: 9118.270526 msecs"

compressed
Java code:
"Elapsed time: 21522.20167 msecs"
(65769984)
"Elapsed time: 21522.663463 msecs"
Clojure code:
"Elapsed time: 21573.585966 msecs"
(65769984)
"Elapsed time: 21574.013417 msecs"
...finished
$ lein run 4 4
starting...

uncompressed
Java code:
""EEllaappsseedd  ttiimmee::  77226688..0857983348 msec1s "m
secs"
(65769984 65769984)
"Elapsed time: 7280.09169 msecs"
Clojure code:
""EEllaappsseedd  ttiimmee::  9911..113308627362  mmsseeccss""

(65769984 65769984)
"Elapsed time: 9177.644745 msecs"

compressed
Java code:
"Elapsed time: 22324.81872 msecs"
"Elapsed time: 23122.111874 msecs"
(65769984 65769984)
"Elapsed time: 23122.511818 msecs"
Clojure code:
"Elapsed time: 75968.051536 msecs"
"Elapsed time: 76018.787437 msecs"
(65769984 65769984)
"Elapsed time: 76019.215303 msecs"
...finished

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


lazy-seq and threads

2015-09-14 Thread Andy L
Hi,

I would like ask for some advise with regards to kind of unusual
interaction between lazy-seq and threads. I have a code opening some big
compressed text files and processing them line by line. The code reduced to
a viable example would look like that:

  (with-open [i (-> "mybigfile.gz" clojure.java.io/input-stream
java.util.zip.GZIPInputStream. clojure.java.io/reader)] (count (line-seq
i)))

where for the sake of visualization, the processing is replaced by a simple
counting.

In a single thread situation, everything works very well, with performance
numbers close to Java (or even equal with "-XX:MaxInlineLevel=16").
However, once I run it in threads, either native Java Thread or future,
instead of nice effect parallel processing, things are even slower from as
they would be run sequentially. Interestingly enough, JVM pegs at 500-600%
of CPU (I have 8 cores). I was not sure what was the reason, and in order
to rule out some basics assumptions, I created a Java equivalent. It runs
at 200% CPU and scales above 4 cores - which is exactly what I want, and
matches gzip behavior. (I can run almost 6 "gunzip -c mybigfile.gz | wc -l"
which all taking 100% CPU each).

Next logical step was to look into Clojure sources. What I am finding out,
is that lazy-seq is synchronized:
https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/LazySeq.java
. From what I understand, JIT optimizes the single thread case and removes
"synchronized" guards, however as soon as other threads come into play I am
forced to pay price for synchronization, which causes the performance
degradation*.

Interestingly enough, JIT optimizes a version without GZIPInputStream and
am getting same results as with Java with multiple threads. I have to run
it with "-XX:MaxInlineLevel=16" though. With a default
"-XX:MaxInlineLevel=9", JIT does not kick in and performance is not there.
There is probably another switch in JVM which would help hinting JIT
better, however I am not convinces that this is a right direction.

I really like semantics of line-seq, however without that "synchronized"
part, as in my context there is no way that two threads touch same seq.

I would like ask for some advise, what would be my options here. The last
resort is to write handling code in Java, but I really want to avoid this.

Best,
Andy

*My analysis might be wrong of course.

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


changing default clojure.pprint/*print-right-margin*

2015-01-06 Thread Andy L
Hi,

Is it possible to change default value of
clojure.pprint/*print-right-margin* var and alikes in one place. I use
pprint in many places and would like to avoid wrapping it with binding in
every case.

Thanks,
Andy

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

2014-12-20 Thread Andy L
Hi,

I realized recently that cohesive pretty formatting LISP programs is a very
difficult problem to solve in the first place due to its homoiconicity.
There could be some nice approximations but the devil is in the details.
That all made me so grateful for what we have and I stopped complaining :-)
...

Ideally, I wish that `clojure-mode` adapts to the style of given project
and helps to format my changes accordingly. Again, probably not so easy to
do either.

Best regards,
Andy

-- 
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: atoms, memoize, future-s and CAS

2014-12-20 Thread Andy L
Hi,

Thanks for all suggestions. It all encouraged me to deep dive into atom-s
code which turns out to be a simple wrapper over Java
java.util.concurrent.atomic.AtomicReference which essentially is a
spinlock. Knowing how it works under the hood makes so easier
to use it ...

Below piece (hopefully correct) let me update map atomically:
(defn cond-assoc!
  [atomic-map key val]
  (loop []
(let [candidate (if (contains? @atomic-map key) @atomic-map (assoc
@atomic-map key val))]
  (if (compare-and-set! atomic-map @atomic-map candidate)
candidate
(recur)


I also learned that using future (or essentially Java threads) is so poor
approach to scalability. derefing memoized delay of my function wrapped
with future worked well to some point. After pushing it a bit with more
concurrent tasks, my JVM started freezing under pressure of to many
threads. I ended up with my custom hybrid of a queued future-s. I have also
a version done in core.async - I will try to write it up in a separate
piece at some point ..

Best regards,
Andy

-- 
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: atoms, memoize, future-s and CAS

2014-12-08 Thread Andy L


 Most of the cache implementations in core.cache have no side-effects. They
 simply return a new cache rather than overwriting the old one. The memoize
 library places the cache in an atom, so it's guaranteed to change
 atomically.



I tried to read the cache code (btw an excellent exercise) , and I think I
understand how persistent data structure/atom is employed here in case we
deal with side effects free functions.


 You could write this as a function. There's nothing in there that requires
 a macro.

 (defn when-map-future-swap! [a k f]
   (locking a
 (when-not (contains? @a k)
   (swap! a assoc k nil)
   (future (swap! a assoc k (f k))


I realized that later too ...

But I'd personally just use a delay rather than locking for this purpose.


It is not that I like locking at all. However I still fail to see, how in a
multithreaded context memoize/cache prevents executing a given function
more than once (which I want to avoid at any cost here) since cache lookup
and swap! does not seem to be atomic :
https://github.com/clojure/core.cache/blob/master/src/main/clojure/clojure/core/cache.clj#L52
.

Best regards,
Andy

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


atoms, memoize, future-s and CAS

2014-12-06 Thread Andy L
Hi,

Here is the situation. There is a function f retrieving some data from
various sources (including reading files, a lot of io, e.g. map-reduce)
expected by design to return the same result for given input. Results of
f invocation from parallely running futures are stored in an atom wrapped
map and everything works just fine.

With a small exception when f invocations with the same arguments
overlap  - the same expensive io is kicked off 2 or more time s. Not a
tragedy, but still very unpleasant and wasteful. The expectation would be
that a subsequent f call would just bail without doing anything while
initial invocation assoc new data into an atom,

The first intuition was to use memoize, however I do not think its
semantics fit well into this case, since the result is a side-effect on
an atom as opposed to return value.

The easiest solution, is to create another atom with a map of the arguments
into a state. If some other future is already there working hard on the
problem, we simply bail. However, that leads to another problem.

compare-and-set! just operates on atoms as wholes, which is fine for
unstructured data, but  falls short for things somewhat more complex,
like here.

While updating an atom in this context is trivial:

user= (def a (atom {}))
user= (swap! a assoc [arg1 arg2] :PENDING)
{[arg1 arg2] resultA}

I would like to link the condition and future together somehow like that:

user= (when ((complement contains?) @a [arg1 arg3]) (swap! a assoc
[arg1 arg3] :PENDING ))

That obviously will not work, unless I wrap it with locking, which is not
necessarily a nice thing to do. I also tried to use refs here, however they
do not fit well here either and the solution is not as nice as it could be.

After that long introduction, I would like ask for some insight  Thanks
in advance ...


Best,
Andy

-- 
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: atoms, memoize, future-s and CAS

2014-12-06 Thread Andy L
 (defn memoized [f]
   (comp deref (memoize (fn [ args] (delay (apply f args)


Thanks for looking into that. This indeed would solve a semantics problem
of memoize, as it returns a value now. However, it seems that
clojure.core.memoize,
or rather  clojure.core.cache memoize is based of, is not thread safe.

It uses ConcurrentHashMap's put under the hood, instead of atomic
putIfAbsent. I might be completely wrong here though.

Cheers,
Andy

-- 
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: atoms, memoize, future-s and CAS

2014-12-06 Thread Andy L
 The SoftCache uses a ConcurrentHashMap, but that caching option isn't used
 in core.memoize. Are you building a custom memoizer?


WRT ConcurrentHashMap, it was an incorrect conclusion on my part. In any
case, I fail to see thread safety in the cache implementation, but again
I could be wrong. Or it might not be needed for 99.99% cache use cases.
Also, at that point I would like to avoid to defcache my own version.


So I ended up with this (this is my first LISP macro ever, so please be
gentle :-) :

(defmacro when-map-future-swap! [a k f]
  `(locking ~a
 (when (not (contains? @~a ~k))
   (swap! ~a assoc ~k nil)
   (future (swap! ~a assoc  ~k (~f ~k)))
   )
 )
  )

Which seems to do what I need:

user= (defn f[k] (Thread/sleep 3000) k)
#'user/f
user= (when-map-future-swap! a arg f)
#core$future_call$reify__6320@a7f0cb9: :pending
user= a
#Atom@71d68915: {arg nil}
user= (Thread/sleep 4000)
nil
user= a
#Atom@71d68915: {arg arg}


Andy

-- 
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: atoms, memoize, future-s and CAS

2014-12-06 Thread Andy L
or even better (using future themselves as a marker in the atom):

(defmacro map-future-swap! [a k f]
  `(locking ~a
 (when (not (contains? @~a ~k))
   (swap! ~a assoc ~k (future (swap! ~a assoc  ~k (~f ~k
   )
 )
  )

-- 
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: a nicer way to write 1 - 2 + 3 - 4 ... +/- n

2014-11-17 Thread Andy L
Thanks for all the ideas. I like cyclefn the most, a bit of investment
resulting in super clean output.

Andy

On Sat, Nov 15, 2014 at 9:35 AM, Ben Wolfson wolf...@gmail.com wrote:

 or

 (defn enumerate [xs] (map vector (range) xs))

 (defn altsum [n] (reduce (fn [acc [i f]] (f acc (inc i)))
  0
 (take n (enumerate (cycle [+ -])



 On Fri, Nov 14, 2014 at 3:41 PM, Andrew Oberstar ajobers...@gmail.com
 wrote:

 How about this?

 (defn cyclefn
   [ fs]
   (let [fcycle (cycle fs)
 rem-fs (atom fcycle)]
 (fn [ args]
   (let [f (first @rem-fs)]
 (swap! rem-fs rest)
 (apply f args)

 (reduce (cyclefn + -) (range 1 100))

 cyclefn could be used to cycle through any set of functions you want and
 the result used as if it was a normal function.


 Andy

 On Fri, Nov 14, 2014 at 7:16 AM, Henrik Lundahl henrik.lund...@gmail.com
  wrote:

 How about this?  :-)

 (defn altsum [n] (/ (if (odd? n) (+ 1 n) (- n)) 2))

 --
 Henrik


 On Fri, Nov 14, 2014 at 1:48 PM, Gary Verhaegen 
 gary.verhae...@gmail.com wrote:

 What about cheating a bit?

 (interleave
   (iterate #(+ % 2) 1)
   (iterate #(- % 2) -2))

 Then take n, reduce +, or whatever else you might want to do with the
 series.

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




 --
 Ben Wolfson
 Human kind has used its intelligence to vary the flavour of drinks, which
 may be sweet, aromatic, fermented or spirit-based. ... Family and social
 life also offer numerous other occasions to consume drinks for pleasure.
 [Larousse, Drink entry]

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

map function generator

2014-11-17 Thread Andy L
Hi,

This is another puzzle/exercise based on a very practical need. I could not
find a built in function, hoping something like colfn already exists.
Otherwise I wonder about an idiomatic solution. This is self-explanatory
code:

user= (require '[clojure.algo.generic.functor :as fu])
user= (require '[me.raynes.fs :as fs])

user= (defn colfn[col] (fn [a] (fu/fmap #(% a) col)))

user= (map (colfn [fs/directory?,identity]) (filter fs/directory?(set
(fs/list-dir .
([true src] [true target] [true .git])

user= (map (colfn {:is-dir fs/directory?, :dir identity}) (filter
fs/directory?(set (fs/list-dir .
({:is-dir true, :dir src} {:is-dir true, :dir target} {:is-dir true,
:dir .git})


My question is, if something like colfn already exists? The idea is to
generate a function of a sequence (vector, list, map) of functions which
would used in e.g. map.

Best,
Andy

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


a nicer way to write 1 - 2 + 3 - 4 ... +/- n

2014-11-13 Thread Andy L
Hi,

All I was able to come up with was this

(defn altsum[n] (reduce + (map * (range 1 (inc n))  (interpose -1 (repeat
1)

... works quite well, however I was wondering if there is more idiomatic
way to write that.

Thanks,
Andy

-- 
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: a nicer way to write 1 - 2 + 3 - 4 ... +/- n

2014-11-13 Thread Andy L
On Thu, Nov 13, 2014 at 6:36 PM, Dave Ray dave...@gmail.com wrote:

 How about:

 (- (map * (cycle [1 -1]) (range 1 n))
  (reduce +))



Thx - I did not know cycle before. I think this is it, although I prefer
nesting over threading. This is another I was thinking about:

-- 
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: a nicer way to write 1 - 2 + 3 - 4 ... +/- n

2014-11-13 Thread Andy L
(reduce + (map * (mapcat (fn[_] [1 -1]) (repeat nil)) (range 1 n)))

not the best pattern for this case, but possibly useful to generate
alternated values ...

A.

-- 
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: a nicer way to write 1 - 2 + 3 - 4 ... +/- n

2014-11-13 Thread Andy L
On Thu, Nov 13, 2014 at 7:23 PM, Robert Levy r.p.l...@gmail.com wrote:

 You don't need this for numbers over 900 right?


I see what you mean. But no, I just practice and try to capture patterns.
So, going after your example I got following:

(reduce + (map applyv (cycle [+ -]) (range 1 10)))

where something like applyv perhaps exists,
(defn applyv [f a] (f v)) - but I am not sure how to find it.

A.

-- 
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: [ClojureScript] 2014 State of Clojure ClojureScript Survey ends Oct 17th

2014-10-19 Thread Andy L
I tried to go to those links and getting This form is currently private
and cannot be viewed by the public.

Thx,
Andy

On Sun, Oct 19, 2014 at 6:38 AM, Alex Miller a...@puredanger.com wrote:

 I hope to have something including the raw results published early this
 week but depends how long it takes to make a report.

 Alex

 On Sunday, October 19, 2014 5:47:21 AM UTC-5, Gary Verhaegen wrote:
  Yes, they do. Probably within two weeks from now, according to the
 original announcement. No hard deadline though.
 
  On Sunday, 19 October 2014, Yehonathan Sharvit vie...@gmail.com wrote:
  On Tuesday, 14 October 2014 16:21:13 UTC+3, Alex Miller  wrote:
 
   Just a reminder that this Friday is the last day to complete the 2014
 State of Clojure  ClojureScript surveys:
 
  
 
  
 
  
 http://blog.cognitect.com/blog/2014/10/3/2014-state-of-clojure-clojurescript-survey
 
  
 
  
 
  
 
   So far 1110 people have filled out the State of Clojure survey and 544
 people have filled out the State of ClojureScript. If you haven't filled
 out the surveys yet, we would love for your answers to be included. The raw
 data and some analysis will be posted next week.
 
  
 
  
 
   Alex
 
 
 
  Do you intend to publish the resutls?
 
 
 
  --
 
  Note that posts from new members are moderated - please be patient with
 your first post.
 
  ---
 
  You received this message because you are subscribed to the Google
 Groups ClojureScript group.
 
  To unsubscribe from this group and stop receiving emails from it, send
 an email to clojurescript+unsubscr...@googlegroups.com.
 
  To post to this group, send email to clojurescr...@googlegroups.com.
 
  Visit this group at http://groups.google.com/group/clojurescript.

 --
 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: [ClojureScript] 2014 State of Clojure ClojureScript Survey ends Oct 17th

2014-10-19 Thread Andy L
I confused dates :-( , nm

On Sun, Oct 19, 2014 at 11:43 AM, Andy L core.as...@gmail.com wrote:

 I tried to go to those links and getting This form is currently private
 and cannot be viewed by the public.

 Thx,
 Andy

 On Sun, Oct 19, 2014 at 6:38 AM, Alex Miller a...@puredanger.com wrote:

 I hope to have something including the raw results published early this
 week but depends how long it takes to make a report.

 Alex

 On Sunday, October 19, 2014 5:47:21 AM UTC-5, Gary Verhaegen wrote:
  Yes, they do. Probably within two weeks from now, according to the
 original announcement. No hard deadline though.
 
  On Sunday, 19 October 2014, Yehonathan Sharvit vie...@gmail.com
 wrote:
  On Tuesday, 14 October 2014 16:21:13 UTC+3, Alex Miller  wrote:
 
   Just a reminder that this Friday is the last day to complete the 2014
 State of Clojure  ClojureScript surveys:
 
  
 
  
 
  
 http://blog.cognitect.com/blog/2014/10/3/2014-state-of-clojure-clojurescript-survey
 
  
 
  
 
  
 
   So far 1110 people have filled out the State of Clojure survey and
 544 people have filled out the State of ClojureScript. If you haven't
 filled out the surveys yet, we would love for your answers to be included.
 The raw data and some analysis will be posted next week.
 
  
 
  
 
   Alex
 
 
 
  Do you intend to publish the resutls?
 
 
 
  --
 
  Note that posts from new members are moderated - please be patient with
 your first post.
 
  ---
 
  You received this message because you are subscribed to the Google
 Groups ClojureScript group.
 
  To unsubscribe from this group and stop receiving emails from it, send
 an email to clojurescript+unsubscr...@googlegroups.com.
 
  To post to this group, send email to clojurescr...@googlegroups.com.
 
  Visit this group at http://groups.google.com/group/clojurescript.

 --
 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: (Request) Rich Hickey's EuroClojure 2014 slides

2014-09-13 Thread Andy L
Thank you. BTW, I really liked Clojure/West video editing style.

Andy

On Fri, Sep 12, 2014 at 8:55 AM, John Gabriele jmg3...@gmail.com wrote:

 A format I particularly like is when there's simply one video file where:

   * the main portion of the window shows the slides,
   * a small thumbnail-size portion shows the speaker, and
   * the remaining rectangle shows static details such as the name of the
 talk, name of speaker, subject, and date.

 As in this style: 
 https://skillsmatter.com/skillscasts/3445-functional-web.

 -- John



 On Thursday, September 11, 2014 10:33:41 AM UTC-4, Alex Miller wrote:

 Usually Rich doesn't release his slides as he prefers for them to be
 consumed in the context of the talk.

 On Thursday, September 11, 2014 8:44:47 AM UTC-5, Leon Grapenthin wrote:

 Hi,
  I am looking for the slides of this talk because one can't see them in
 the video:

 http://vimeo.com/100518968

 Thanks,
  Leon.




  --
 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: why String is not a collection (of Character)

2012-06-07 Thread Andy L

On 06/07/2012 09:22 PM, Ambrose Bonnaire-Sergeant wrote:

Every Seqable is not Sequential.

(sequential? {:a 1}) = false


Is there a simple test for sequable?

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