Re: Help with Liberator POST route

2015-02-18 Thread Andy-
Without having tested it: I think you're "curl -d" format is wrong. It's 
not semicolon separated:
http://superuser.com/questions/149329/what-is-the-curl-command-line-syntax-to-do-a-post-request

HTH

On Wednesday, February 18, 2015 at 7:09:19 AM UTC-5, g vim wrote:
>
> I have a Liberator app which works with this: 
>
> (defresource user [day month year hour min region location] 
>:available-media-types ["application/json"] 
>:handle-ok (generate-string (clc/calc day month year hour min 0 (str 
> region "/" location 
>
> (defroutes app-routes 
>(GET "/user/:day/:month/:year/:hour/:min/:region/:location" [day 
> month year hour min region location] 
> (user (Integer/parseInt day) (Integer/parseInt month) 
> (Integer/parseInt year) (Integer/parseInt hour) (Integer/parseInt min) 
> region location)) 
>
>  but doesn't work with POST: 
>
> (defroutes app-routes 
>(POST "/user" [day month year hour min region location] 
> (user (Integer/parseInt day) (Integer/parseInt month) 
> (Integer/parseInt year) (Integer/parseInt hour) (Integer/parseInt min) 
> region location)) 
>
>
> Testing with with: 
>
> curl -d 
> "day=10;month=8;year=1970;hour=13;minute=45;region=Europe;location=London" 
> http://localhost:3000/user 
>
>  returns an error with the first parameter truncated: 
>
> java.lang.NumberFormatException For input string: 
> "14;month=10;year=1960;hour=13;minute=44;region=Europe;location=London" 
>
> What am I doing wrong and why is the POST data truncated in the error 
> message? 
>
> 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: partition-when

2015-03-05 Thread Andy-
Tried myself and my first transducer for fun:

(defn partition-when
  [f]
  (fn [rf]
(let [a (java.util.ArrayList.)
  fval (volatile! false)]
  (fn
([] (rf))
([result]
   (let [result (if (.isEmpty a)
  result
  (let [v (vec (.toArray a))]
;;clear first!
(.clear a)
(unreduced (rf result v]
 (rf result)))
([result input]
(if-not (and (f input)  @fval)
   (do
 (vreset! fval true)
 (.add a input)
 result)
   (let [v (vec (.toArray a))]
 (.clear a)
 (let [ret (rf result v)]
   (when-not (reduced? ret)
 (.add a input))
   ret

(into [] (partition-when
  #(.startsWith % ">>"))
  [">> 1" ">> 2" "22" ">> 3"])


Based on partition-by (on master branch). Would be interesting how fast it 
is compared to the other implementations.

Any comments appreciated.

Cheers


On Tuesday, March 3, 2015 at 2:46:29 PM UTC-5, Frank wrote:
>
> Hi all,
>
> for some tests I need a function which starts a new partition each time a 
> predicate returns true, for instance:
>
> (partition-when
>   (fn [s] (.startsWith s ">>"))
>   [">> 1" "2" "3" ">> 4" "5" "6"])
> :=> [[">> 1" "2" "3"] [">> 4" "5" "6"]]
>
> Since I haven't found a built-in function, I copied, pasted, and modified 
> the core function partition-by:
>
> (defn partition-when
>   [f coll]
>   (lazy-seq
>(when-let [s (seq coll)]
>  (let [fst (first s)
>run (cons fst (take-while #(not (f %)) (next s)))]
>(cons run (partition-when f (seq (drop (count run) s
>
> Is there a better (more idiomatic) way to achieve the same result?
>
> Thank you in advance.
>
> Frank
>

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


Re: how do you re-load a clojure library?

2015-03-29 Thread Andy-
Off topic for this list but I'm sure helpful to some:

On Windows: You can see open file handles with MS's Process Explorer.

On Linux: There is `lsof`, or if you like interactive: The popular `htop` 
utility allows you to press `l` to see all open ports, files and cwd of a 
process.

This quickly allows you to figure out where the .jar's are actually loaded 
from.

Both are very good to know in general.
HTH

On Sunday, March 29, 2015 at 10:11:18 AM UTC-4, Dan Campbell wrote:
>
>
>
> There it is, in Windows, at c:\Users\DC\.m2\repository, will try that, 
> thanks Juvenn.
>
>
>
>
>
> On Sunday, March 29, 2015 at 8:08:22 AM UTC-4, juvenn wrote:
>>
>>  Hi Dan, 
>>
>> All jars files are kept at `~/.m2/repositories` on *nix, as far as I 
>> know. So you can just find and delete them over there. The next time you 
>> run a lein task, it will re-download it.
>>
>> Best,
>> -- 
>> Juvenn Woo
>> Sent with Sparrow 
>>
>> On Sunday, 29 March, 2015 at 7:43 pm, Dan Campbell wrote:
>>
>>
>> If you wanted to sort of 'clean out' a clojar or any contrib, korma or 
>> core.async or whatever, how would you do that?
>>
>> In other words, if you wanted a specific library to be re-downloaded and 
>> deployed (i.e., refreshed) on your desktop, what command would you run?  Or 
>> what folders would you clean out?
>>
>>
>>  -- 
>> 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: [ANN] Clojure 1.7.0-beta1 released

2015-04-13 Thread Andy-
Why not just change the `?' to `_'? ?
So:
#?(:cljs (def unrelated-1 nil))
then
#_(:cljs (def unrelated-1 nil))

Even saved a character :)


On Monday, April 13, 2015 at 3:38:01 PM UTC-4, whodidthis wrote:
>
>
>
> On Monday, April 13, 2015 at 4:48:28 PM UTC+3, Alex Miller wrote:
>>
>> I think what you're seeing here makes sense.
>>
>> On Sunday, April 12, 2015 at 3:39:15 PM UTC-5, whodidthis wrote:
>>>
>>> Are there any thoughts on code like this:
>>>
>>> #_
>>>
>>
>> This says to ignore the next read form
>>  
>>
>>> #?(:cljs (def unrelated-1 nil))
>>>
>>
>> This evaluates to *nothing*, ie nothing is read, so it is not ignored by 
>> the #_.
>>  
>>
>>> #?(:cljs (def unrelated-2 nil))
>>> #?(:cljs (def unrelated-3 nil))
>>>
>>
>> These also read as *nothing*.
>>  
>>
>>> #?(:clj (def n 10))
>>>
>>
>> This *is* read, but ignored per the prior #_ 
>>
>> #?(:clj (defn num [] n))
>>> ; compile on clj =>RuntimeException: Unable to resolve symbol: n
>>>
>>
>> And then this makes sense.
>>  
>>
>>>
>>> I guess it's fine if it continues to work that way but I can imagine it 
>>> being a little surprising from time to time heh
>>>
>>
>> Conditional reading is definitely something to be careful about - I think 
>> in this case you are combining two types of conditional reading so be 
>> doubly careful. :) 
>>
>> To get the effect you want in this, using #_ *inside* the reader 
>> conditional would work:
>>
>> #?(:cljs #_(def unrelated-1 nil))
>>
>
> Sorry, back to this stuff again. I tried using discard inside but 
>
> #?(:clj #_'whatever)
>
> just throws
>
> CompilerException java.lang.RuntimeException: read-cond starting on line 
> 32 requires an even number of forms"
>
> when compiling on clojure.
>
> Would be nice to have a way to ignore reader conditional forms or the 
> thingie things inside but there does not seem to be an easy way.
>

-- 
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: Performance of defmulti in both ClojureScript and Clojure

2015-04-27 Thread Andy-
Looks like they're pretty slow compared to a simple case:

http://jsperf.com/cljs-multimethods

https://github.com/rauhs/cljs-perf


On Saturday, April 25, 2015 at 10:33:18 AM UTC-4, Timur wrote:
>
> Hi everyone,
>
> There are situations where I want to dispatch functions using based on 
> their certain properties. I can also use case statements instead but it 
> looks more coupled and more change is required if I want to add new types. 
>
> What I want to ask is if I need to avoid using multi-methods for 
> performance reasons? I read somewhere that they are not really fast but the 
> posts were old and the performance might have been improved in between. 
> Should I favor case and cond branches instead of defmulti when I need 
> performance? 
>
> Thanks for your help!!!
>
> Regards.
>
> Timur
>

-- 
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: Performance of defmulti in both ClojureScript and Clojure

2015-04-27 Thread Andy-
You're right. I didn't check it enough. I did check out the source (and 
btw, was very impressed with the result) but it looks like the function 
call ended up doing nothing. I just put in a side effect and I got the 
following results:

"[a :one], (multi-test), 100 runs, 2933 msecs"
"[a :one], (fn-test), 100 runs, 500 msecs"

Much more reasonable and I'm willing to pay for that for using multimethods.

I removed the jsperf and updated the repo. Sorry for spreading FUD.

Cheers

On Monday, April 27, 2015 at 10:07:07 AM UTC-4, David Nolen wrote:
>
> A quick glance at your benchmarking setup, it's not clear that you are 
> benchmarking what you think you are benchmarking, and jsperf is not a 
> suitable benchmarking harness (irrespective of it's popularity). 
> Benchmarking is hard, benchmarking JavaScript is harder, and benchmarking 
> JavaScript that went through Google Closure is even more challenging than 
> that. It's for this reason we have our own simple benchmarking suite that 
> we run in the project repo itself against 4 JavaScript engines (V8, 
> JavaScriptCore, SpiderMonkey, Nashorn) at the command line.
>
> For people that want to see accurate benchmarking information posted to 
> some public location, this is a great place to get involved contributing to 
> ClojureScript without needing to dig into the compiler.
>
> My earlier points about the general performance expectations of 
> multimethods in ClojureScript still stands :)
>
> David
>
> On Mon, Apr 27, 2015 at 9:44 AM, Andy- > 
> wrote:
>
>> Looks like they're pretty slow compared to a simple case:
>>
>> http://jsperf.com/cljs-multimethods
>>
>> https://github.com/rauhs/cljs-perf
>>
>>
>> On Saturday, April 25, 2015 at 10:33:18 AM UTC-4, Timur wrote:
>>>
>>> Hi everyone,
>>>
>>> There are situations where I want to dispatch functions using based on 
>>> their certain properties. I can also use case statements instead but it 
>>> looks more coupled and more change is required if I want to add new types. 
>>>
>>> What I want to ask is if I need to avoid using multi-methods for 
>>> performance reasons? I read somewhere that they are not really fast but the 
>>> posts were old and the performance might have been improved in between. 
>>> Should I favor case and cond branches instead of defmulti when I need 
>>> performance? 
>>>
>>> Thanks for your help!!!
>>>
>>> Regards.
>>>
>>> Timur
>>>
>>  -- 
>> 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: Metadata loss. What am I doing wrong?

2015-05-05 Thread Andy-
In addition to James comment: IMO clojure.org/metadata should be clearer 
about this. It's mentioned more clearly on the reader page:
http://clojure.org/reader#The%20Reader--Macro%20characters
"The metadata reader macro first reads the metadata and attaches it to the 
next form read (see with-meta 
 
to 
attach meta to an object):"

Stress on *next form read*.

On Tuesday, May 5, 2015 at 2:31:40 PM UTC-4, Andrey Antukh wrote:
>
> Hi!
>
> I have some trouble with clojure metadata / reader and I do not know if 
> I'm doing something wrong.
>
> I have this code:
>
> (defn some-func [])
>
> (def func ^:abc some-func)
>
> (assert (= (meta func) {:abc true}))
>
> (def data [[:bar (with-meta some-func {:abc true})]
>[:baz ^:abc some-func]])
>
> (assert (= (meta (get-in data [0 1])) {:abc true}))
> (assert (= (meta (get-in data [1 1])) {:abc true}))
>
> It fails in the first assert and in the last (if I comment the first one 
> obviously). I do not understand why that form of metadata does not works
> as I expect (http://clojure.org/metadata)
>
> Thank you very much.
>
> Regards.
> Andrey
>
> -- 
> Andrey Antukh - Андрей Антух - > / <
> ni...@niwi.be >
> http://www.niwi.be 
> https://github.com/niwibe
>  

-- 
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: Metadata loss. What am I doing wrong?

2015-05-05 Thread Andy-
Frankly, I would've (meta ^:abc 'some-symbol) expected to work. Maybe 
somebody else can weigh in on why this one is a no-go.

On Tuesday, May 5, 2015 at 5:01:19 PM UTC-4, Andrey Antukh wrote:
>
> Thanks to both for the responses, but I stil not clearly understand.
>
> The documentation says very clearly that:
>
> In addition to with-meta, there are a number of reader macros (The Reader: 
> Macro Characters) for applying metadata to the expression following it:
> ^{:doc "How obj works!"} obj - Sets the metadata of obj to the provided 
> map.
> Equivalent to (with-meta obj {:doc "How obj works!"})
>
>
> (def foo ^:abc [1 2 3]) -> (meta foo) -> {:abc true}
> (def foo ^:abc some-func) -> (meta foo) -> nil
> (def foo ^:abc 'some-symbol) -> (meta foo) -> nil (In clojure programming 
> book uses example attaching metadata using the reader to the symbol, but 
> seems it not works as expected)
>
> Is a little bit confusing. The metadata documentation says clearly that 
> are equivalent, but are not equivalent.
>
>
> Thank you very much again.
>
> Regards.
> Andrey
>
> 2015-05-05 21:49 GMT+02:00 Andy- >:
>
>> In addition to James comment: IMO clojure.org/metadata should be clearer 
>> about this. It's mentioned more clearly on the reader page:
>> http://clojure.org/reader#The%20Reader--Macro%20characters
>> "The metadata reader macro first reads the metadata and attaches it to 
>> the next form read (see with-meta 
>> <http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/with-meta>
>>  to 
>> attach meta to an object):"
>>
>> Stress on *next form read*.
>>
>> On Tuesday, May 5, 2015 at 2:31:40 PM UTC-4, Andrey Antukh wrote:
>>>
>>> Hi!
>>>
>>> I have some trouble with clojure metadata / reader and I do not know if 
>>> I'm doing something wrong.
>>>
>>> I have this code:
>>>
>>> (defn some-func [])
>>>
>>> (def func ^:abc some-func)
>>>
>>> (assert (= (meta func) {:abc true}))
>>>
>>> (def data [[:bar (with-meta some-func {:abc true})]
>>>[:baz ^:abc some-func]])
>>>
>>> (assert (= (meta (get-in data [0 1])) {:abc true}))
>>> (assert (= (meta (get-in data [1 1])) {:abc true}))
>>>
>>> It fails in the first assert and in the last (if I comment the first one 
>>> obviously). I do not understand why that form of metadata does not works
>>> as I expect (http://clojure.org/metadata)
>>>
>>> Thank you very much.
>>>
>>> Regards.
>>> Andrey
>>>
>>> -- 
>>> Andrey Antukh - Андрей Антух -  / <
>>> ni...@niwi.be>
>>> http://www.niwi.be <http://www.niwi.be/page/about/>
>>> https://github.com/niwibe
>>>  
>>
>
>
> -- 
> Andrey Antukh - Андрей Антух - > / <
> ni...@niwi.be >
> http://www.niwi.be <http://www.niwi.be/page/about/>
> https://github.com/niwibe
>  

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


Opinion on take-while for stateful transducers

2015-05-09 Thread Andy-
Hi *,

I first needed a transducer that stopped when the first non-distinct item 
is seen. Thus changing distinct slightly to:

(defn take-while-distinct
  "Just like clojure.core/distinct but terminating as soon as one duplicate  
element is seen."
  []
   (fn [rf]
 (let [seen (volatile! #{})]
   (fn
 ([] (rf))  ;; init arity
 ([result] (rf result)) ;; completion arity
 ([result input];; reduction arity
   (if (contains? @seen input)
 (reduced result);; !! difference to distinct
 (do (vswap! seen conj input)
 (rf result input


I figured this can be generalized to also work with dedup and possibly 
other stateful transducers (after all if they aren't stateful then I can 
just use take-while) so that I can do something like this:
(into [] (take-while-xf (distinct)) [1 2 3,,, 1 4 32 42])
(into [] (take-while-xf (dedupe)) [1 2 3 1 4 32,,, 32 42 292 23])

The comma marks where the transducers stops (after consuming one more 
input).

I came up with this (non-working) implementation:

(defn take-while-xf-buggy
  "Takes a transducer and returns a transducer that will immediately finish (ie 
 call (reduced)) when the transducer did not call the reducing function and  
just returned the result. Only really useful with stateful transducers."
  [xf]
  (fn [rf]
(let [td (xf rf)]
  (fn
([] (rf))
([result] (rf result))
([result input]
 (let [x (td result input)]
   (if (= x result)
 (reduced x)
 x)))


This doesn't work. I believe because the reducing function bashes the 
transient in place and the comparison always yields true and thus stops 
after one input element.

I then ended up with something hacky that does seem to work however:

(defn take-while-xf
  "Takes a transducer and returns a transducer that will immediately finish (ie 
 call (reduced)) when the transducer did not call the reducing function and  
just returned the result. Only really useful with stateful transducers.  
Otherwise you'd use take-while."
  [xf]
  (fn [rf]
(let [td (xf (fn ;; custom reducing function to avoid calls to rf
   ([] [])
   ([x] [x])
   ([r i] i)))]
  (fn
([] (rf))
([result] (rf result))
([result input]
 (let [x (td result input)]
   (if (= x input)
 (rf result input)
 (reduced result
;; or equivalently:(defn take-while-xf'
  [xf]
  (let [td (xf (fn
 ([] [])
 ([x] x)
 ([r i] i)))]
(take-while #(= % (td nil %)


Is this a good idea and rock solid implementation? I'm a little worried 
this breaks down for corner cases (and this would be no fun to debug).

Or am abusing transducers here? What would be a good way to implement this? 
Possibly even further up the chain?

Thanks for reading,
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: Opinion on take-while for stateful transducers

2015-05-12 Thread Andy-
Thanks for the reply. I do like this. I think it's actually more elegant. 
Definitely going into my toolbox. One thing I dislike is that I still have 
to re-implement the logic of the already existing (performant & tested) 
transducers.
Also, I could also add a 4th parameter: 'terminate-early?' but that's then 
already 4 parameters to remember... I'll have to see what way is best once 
I implement more transducers with your or my (hacky) method.

Cheers

On Monday, May 11, 2015 at 1:34:31 PM UTC-4, miner wrote:
>
> Not an expert, but I’ll throw out an alternative approach that might work 
> for you.  I think it’s simpler to use a transducer that calls functions 
> rather than trying to transform an existing transducer to do the cutoff. 
>
> (defn take-while-accumulating [accf init pred2] 
>(fn [rf] 
>  (let [vstate (volatile! init)] 
>(fn 
>  ([] (rf)) 
>  ([result] (rf result)) 
>  ([result input] 
>   (if (pred2 @vstate input) 
> (do (vswap! vstate accf input) 
> (rf result input)) 
> (reduced result))) 
>
> accf is like a reducing function: takes two args, state and input, and 
> returns new state of the “accumulation”.  init is the initial state of the 
> accumulation.  pred2 is a predicate taking two args, the accumulation state 
> and the new input.  The process stops when pred2 returns false. 
>
> ;; distinct 
> (into [] (take-while-accumulating conj #{} (complement contains?)) '(1 2 3 
> 4 2 5 6)) 
> ;;=> [1 2 3 4] 
>
> ;; dedupe 
> (into [] (take-while-accumulating (fn [r x] x) ::void not=) '(1 2 1 3 4 4 
> 5 6)) 
> ;;=> [1 2 1 3 4] 
>
> ;; monotonically increasing 
> (into [] (take-while-accumulating max 0 <=) '(1 2 3 4 4 1 5 6)) 
> [1 2 3 4 4] 
>
>
> Steve Miner 
> steve...@gmail.com  
>
>
>   
>
> On May 9, 2015, at 6:28 PM, Andy- > 
> wrote: 
>
> > (defn take-while-xf 
> >   
> > "Takes a transducer and returns a transducer that will immediately 
> finish (ie 
> >   call (reduced)) when the transducer did not call the reducing function 
> and 
> >   just returned the result. Only really useful with stateful 
> transducers. 
> >   Otherwise you'd use take-while." 
> > 
> > [xf] 
> > 
>
>

-- 
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: Question regarding java array

2015-06-11 Thread Andy-
On Thursday, June 11, 2015 at 5:32:02 AM UTC-4, Ritchie Cai wrote:
>
> Just wondering though, is there a faster way to load an array than this 
> way? 
> https://github.com/malloc82/imaging/blob/45475b99f564b1ac77e668e04b91cb9c01a096d7/src/imaging/dicom.clj#L138
> the data file I'm trying to read from contains text based pixel values.
>

 I'm not sure about your use case but you may want to look into HDF5 data 
format. That's what it's made for: Super fast loading of numerical data 
from disk. It can even load in parallel (many hundreds MB/s). As soon as my 
text file takes too long to load I usually just convert it first to HDF5 
and then go from there. Linux/Mac has HDF tools which can dump and import 
(h5import) your data from the command line.
It's also a very common data format.

HTH

-- 
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: Is this expected behavior with meta data?

2015-06-25 Thread Andy-
There was just this question the other day:

http://stackoverflow.com/questions/30922413/why-does-metadata-symbol-not-work

There is also a few threads a few weeks ago here on google groups about it:

https://groups.google.com/d/msg/clojure/_e7vBom2acw/0AAKTiGuzv4J

HTH


On Thursday, June 25, 2015 at 10:00:59 AM UTC-4, Sarkis Karayan wrote:
>
>
> Why doesn't this work?
> user=> (meta ^{:some-meta 123} 'n)
> nil
>
> While this works:
> user=> (meta ^{:some-meta 123} (fn [n] n))
> {:some-meta 123}
>
> And this works too:
> user=> (meta (with-meta 'n {:some-meta 123}))
> {:some-meta 123}
>
>
> Is this intended behavior?  If so, what's the reasoning?
>
> Thanks,
> Sarkis
>
>

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

2015-06-25 Thread Andy-
The sidebar on reddit is actually pretty decent:

http://www.reddit.com/r/clojure

My #1 resource for looking up docs is nowadays clojuredocs.org since it 
gives examples/comments for most of the functions.

HTH

On Thursday, June 25, 2015 at 4:59:12 AM UTC-4, Baskar Kalyanasamy wrote:
>
> hi everyone,
> can somebody send me materials for clojure. i am a 
> beginner and i also want to in which tool or software i should practice in.
> thanks in advance
>

-- 
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: Avoiding repetition while still using 'recur'

2016-06-26 Thread Andy-
To add a little variant of James Reeve's code: You can avoid the loop/recur 
by using reduce:


(defn valid-parens? [s]
  (let [opening-brackets {\( \), \[ \], \{ \}}
closing-brackets (clojure.set/map-invert opening-brackets)]
(empty?
  (reduce
(fn [stack c]
  (if (opening-brackets c)
(conj stack c)
(if-let [b (closing-brackets c)]
  (if (= (peek stack) b)
(pop stack)
(reduced [false]))
  stack)))
[]
(seq s)


HTH

On Sunday, June 26, 2016 at 4:06:27 PM UTC+2, Botond Balázs wrote:
>
> Thanks guys.
>
> Very nice and simple solution, James.
>
> On Sunday, June 26, 2016 at 3:21:56 PM UTC+2, James Reeves wrote:
>>
>> The easiest way would be to factor out the bracket matching code, since 
>> that's the only thing that changes between your different case statements. 
>> For instance:
>>
>>   (defn valid-parens? [s]
>> (let [opening-brackets {\( \), \[ \], \{ \}}
>>   closing-brackets (clojure.set/map-invert opening-brackets)]
>>   (loop [cs (seq s), stack []]
>> (if-not cs
>>   (empty? stack)
>>   (let [c (first cs), cs (next cs)]
>> (if (opening-brackets c)
>>   (recur cs (conj stack c))
>>   (if-let [b (closing-brackets c)]
>> (if (= (peek stack) b)
>>   (recur cs (pop stack))
>>   false)
>> (recur cs stack)))
>>
>> Another way you could do it is to replace your recursive call with a 
>> continuation.
>>
>> - James
>>
>> On 26 June 2016 at 13:43, Botond Balázs  wrote:
>>
>>> Hi,
>>>
>>> Here is my solution to 4clojure problem #177:
>>>
>>> Write a function that takes in a string and returns truthy if all square 
 [ ] round ( ) and curly { } brackets are properly paired and legally 
 nested, or returns falsey otherwise.

>>>
>>> (defn valid-parens?
>>>   [s]
>>>   (loop [[ch & chs] s stack []]
>>> (if (nil? ch)
>>>   (empty? stack)
>>>   (case ch
>>> (\( \[ \{) (recur chs (conj stack ch))
>>> \) (if (= (peek stack) \()
>>>  (recur chs (pop stack))
>>>  false)
>>> \] (if (= (peek stack) \[)
>>>  (recur chs (pop stack))
>>>  false)
>>> \} (if (= (peek stack) \{)
>>>  (recur chs (pop stack))
>>>  false)
>>> (recur chs stack)
>>>
>>> This works but I don't like the repetition in the case branches. But 
>>> the repeated code contains a recur call so I can't simply refactor it 
>>> into a helper function. How can I achieves something like the following, 
>>> but without consuming the stack?
>>>
>>> (defn valid-parens?
>>>   ([s]
>>>(valid-parens? s []))
>>>   ([[ch & chs] stack]
>>>(if (nil? ch)
>>>  (empty? stack)
>>>  (letfn [(match? [p]
>>>(if (= (peek stack) p)
>>>  (valid-parens? chs (pop stack))
>>>  false))]
>>>(case ch
>>>  (\( \[ \{) (valid-parens? chs (conj stack ch))
>>>  \) (match? \()
>>>  \] (match? \[)
>>>  \} (match? \{)
>>>  (valid-parens? chs stack))
>>>
>>> Thanks!
>>> Botond
>>>
>>> -- 
>>> 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: Index of an element in a vector of vectors

2016-12-07 Thread Andy-
One option is to use keep-indexed:

(first
  (keep-indexed
(fn [i xs]
  (first
(keep-indexed
  (fn [j x]
(when (= x "5")
  [i j]))
  xs)))
players))



On Wednesday, December 7, 2016 at 5:32:10 PM UTC+1, Rickesh Bedia wrote:
>
> If I have 
>
> (def players [["1" "2" "3"] ["4" "5" "6"] ["7" "8" "9"]])
>
> How would I get the index of number 5? I think it should be [1 1] but 
> don't know how to get this
>
> If it were more simple such as
>
> (def players ["1" "2" "3"])
>
> I can get the index using
>
> (.indexOf players "2") > 1
> (.indexOf players "3") > 2
>
>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
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: Index of an element in a vector of vectors

2016-12-08 Thread Andy-
In that case you can use mapv:

(mapv
  (fn [xs]
(mapv
  (fn [x]
(if (= x "5")
  "XX"
  x))
  xs))
  players)


Two notes:
1. There is room for optimization if you only want to map one element. This 
currently will just keep going. A smart implementation could bail out of 
the inner loop
2. If this is something you want to do frequently you may want to use 
different data structures (probably a map) that allow you to access 
elements fast.

If you sketch your access and transform patterns then I'm sure we can 
recommend a better way.



On Thursday, December 8, 2016 at 11:13:42 AM UTC+1, Rickesh Bedia wrote:
>
> Is there a way to generalise?
>
> I.e a function that allows you to swap any of the 1-9?
>
> On Wednesday, 7 December 2016 18:06:19 UTC, Andy- wrote:
>>
>> One option is to use keep-indexed:
>>
>> (first
>>   (keep-indexed
>> (fn [i xs]
>>   (first
>> (keep-indexed
>>   (fn [j x]
>> (when (= x "5")
>>   [i j]))
>>   xs)))
>> players))
>>
>>
>>
>> On Wednesday, December 7, 2016 at 5:32:10 PM UTC+1, Rickesh Bedia wrote:
>>>
>>> If I have 
>>>
>>> (def players [["1" "2" "3"] ["4" "5" "6"] ["7" "8" "9"]])
>>>
>>> How would I get the index of number 5? I think it should be [1 1] but 
>>> don't know how to get this
>>>
>>> If it were more simple such as
>>>
>>> (def players ["1" "2" "3"])
>>>
>>> I can get the index using
>>>
>>> (.indexOf players "2") > 1
>>> (.indexOf players "3") > 2
>>>
>>>

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


beginning to learn Clojure after imperative programming my whole life

2017-08-09 Thread Andy
This feels like a different world.

Has anyone experienced a sharp increase in their problem solving abilities 
after switching to Clojure?
I have been working my way through Living Clojure an Oreilly book. 

My curiosity got the better of me and I wondered if anyone here had some 
suggestions for resources/
particular tips/any advice for improving Clojure skills. Does anybody have 
any websites used for solving
Clojure problems? other than the most popular ones.

Wishing you the best of luck in life and coding.

best wishes fellow Clojurians,
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: Anyone mourns the loss of: tryclj.com ?

2017-12-16 Thread Andy-
You can also get a REPL with https://coderpad.io/ . It even runs Clojure 
1.9 and the editor has great VIM bindings.

If it asks you to register you can just start a new session in an incognito 
window.

HTH

On Saturday, December 16, 2017 at 4:29:23 AM UTC+1, Didier wrote:
>
> Just realized that: tryclj.com is gone.
>
> I wonder if clojure.org could come to the rescue, and add a try-me web 
> repl on it. I feel like tryclj when I first got started and became 
> interested was a great gateway.
>
> repl.it is just a little too bloated for my liking as a replacement.
>

-- 
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: Durable atom

2015-08-16 Thread Andy-
You might like some of immutant's stuff:

http://immutant.org/documentation/2.0.2/apidoc/guide-transactions.html

Even though it's called caching, it can be used as a kv-store. They do 
offer persistence and transaction.

HTH

On Sunday, August 16, 2015 at 10:59:09 AM UTC-4, Jeremy Vuillermet wrote:
>
> Hello,
>
> With the rise of Om, Reagent or re-frame for that matter, I'm using more a 
> more the single state atom pattern in my clojurescript app.
> So much so that for my current application, I've been using atoms server 
> side because my apps are split in really small app that only need to store 
> few data - things like mini multiplayer game or polls.
> At the very least, it's useful while developing so I don't have to think 
> too much about the storage layer.
>
> While looking for ways to keep my atom like interface while persisting my 
> data, I found http://avout.io/ "Distributed state for clojure" which 
> would be perfect for my use case.
> I also found things like https://github.com/alandipert/enduro : "durable 
> atom in clojure" 
> or https://github.com/torsten/zookeeper-atom 
>
> All of them does not seem active anymore and I wonder why and what's the 
> current status for those kind of thing.
>
> Are those solution not ready for production ?
> Do you eventually end up with a traditional database so nobody need that ?
>

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


Re: How can find something inside heavily nested data structure ?

2015-08-19 Thread Andy-
I have yet to evaluate it myself but this might do help you:

https://github.com/nathanmarz/specter


On Wednesday, August 19, 2015 at 10:18:06 AM UTC-4, Hussein B. wrote:
>
> Hi,
>
> I have transformed JSON response into the equivalent data structure using 
> Cheshire library.
>
> The result is a huge nested data structure , mostly vectors and maps. It 
> is actually a tree.
>
> How to find a property that is nested deep inside the tree ? For example 
> I'm search for the node that has the value zyx for property "uuid".
>
> What I'm supposed to use? Something like zipper or walk? or something 
> simpler is available?
>
> Thanks for help.
>

-- 
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: Stuart Sierra's Component: retries & restarts in production

2015-09-03 Thread Andy-
Only to answer the "retry on error" part of you question: You might like 
hara/event:
http://docs.caudate.me/hara/hara-event.html

HTH

On Wednesday, September 2, 2015 at 8:44:07 PM UTC-4, jo...@signafire.com 
wrote:
>
> TLDR: how do you use Component when the application logic involves 
> retrying failed components?
>
> Background:
> I'm writing an app that consumes events from a streaming HTTP connection 
> and writes those events to a message queue (see Code Illustration #1). It 
> seems like that could be captured easily with three components —an HTTP 
> stream, a message queue connection, and a "shoveler" that depends on the 
> other two (see Code Illustration #2)— *but* the reconnection requirements 
> complicate things…
> The HTTP connection may be closed at any time by the server; if that 
> happens, the app should persistently attempt to reconnect using an 
> exponential back-off pattern. In addition, if the app goes thirty seconds 
> without receiving any data, it should close the connection and try to 
> reconnect. (see Code Illustration #3) It's not clear to me how to best 
> express these "retry" requirements in the component lifecycle. Like, is it 
> blasphemous for a component to be calling stop and start on its injected 
> dependencies?
>
> Some possible approaches:
>
>- Throw different kinds of exceptions to indicate what should happen 
>(using namespaced keywords, perhaps?), handled by whoever calls 
>component/start on the system-map.
>- The exception provides the component and system at the time of the 
>   exception, enabling a sort of "resume" capability.
>   - I'm under the impression that relying on exceptions for control 
>   flow is an anti-pattern.
>- Create a sort of custom system implementation, one that goes beyond 
>calling start on its components in dependency order to monitor 
>failures and direct retries "appropriately".
>   - "A system is a component which knows how to start and stop other 
>   components." (from the README)
>   So the fact that we want the shoveler component to be capable of 
>   restarting the HTTP component indicates that the shoveler should 
> actually 
>   be considered a system. (right?)
>  - If the HTTP stream is *injected* into the shoveler as a 
>  dependency, how is it possible for the shoveler to stop the HTTP 
>  stream and then start it again *with* any dependencies the 
>  stream may have?
>   - Ensure that every component/Lifecycle method implementation is 
>idempotent, so that I can get good-enough "restart" semantics by just 
>calling start-system again.
>   - I know that idempotence is generally a Good Thing anyway, but 
>   using start-system as a panacea strikes me as crude.
>
>
> Code Illustrations:
>
> 1. Rough sketch of app without timeout/retry logic or component:
> (defn -main []
>   (let [mq-conn (connect-to-queue mq-config)
> {event-stream :body} (http/get endpoint {:as :stream})]
> (with-open [rdr (java.io/reader event-stream)]
>   (doseq [entity (line-seq rdr)]
> (write mq-conn entity)
>
> 2. Rough sketch of app with component but still without timeout/retry 
> logic:
> (defrecord EventStream [endpoint
> http-config
> stream]
>   component/Lifecycle
>   (start [this]
> (let [response (http/get endpoint (merge {:as :stream} http-config))]
>   (assoc this :http-response response, :stream (:body response)))
>   (stop [this]
> (.close stream)
> (-> this (dissoc :http-response) (assoc :stream nil
>
> (defrecord MessageQueue [config
>  connection]
>   component/Lifecycle
>   (start [this]
> (assoc this :connection (connect-to-queue config)))
>   (stop [this]
> (.close connection)
> (assoc this :connection nil)))
>
> (defrecord Shoveler [source sink
>  worker]
>   component/Lifecycle
>   (start [this]
> ;; To avoid blocking indefinitely, we put the processing in a future.
> (assoc this :worker (future
>  (with-open [rdr (java.io/reader (:stream source)]
>(doseq [entity (line-seq rdr)]
>  (write sink entity)
>   (stop [this]
> (future-cancel worker)
> (assoc this :worker nil)))
>
> (defn -main []
>   (-> (component/system-map :config (read-config)
> :events (map->EventStream {:endpoint endpoint
> })
> :mq-client (map->MessageQueue {})
> :shoveler (map->Shoveler {}))
>   (component/using {:events {:http-config :config}
> :mq-client {:config :config}
> :shoveler {:source :events
>:sink :mq-client}})
>   component/start))
>
> 3. Rough sketch of desired *production* behavior, not using Component:
> (defn 

Re: newbie Q: how to tweak file-seq (original: how to selectively iterate through a tree of directories) ?

2015-10-05 Thread Andy-
Try to adapt my code:

https://gist.github.com/rauhs/63054a06631c0be598d3

where you change your accept function to incorporate:

http://stackoverflow.com/questions/813710/java-1-6-determine-symbolic-links

HTH

On Saturday, October 3, 2015 at 5:14:51 PM UTC-4, hpw...@gmail.com wrote:
>
> The directory structure is
>/path/top/dir1
>/path/top/dir1/f1
>/path/top/dir1/f2
>/path/top/dir2 -> /another/path/dir2 
> --
>/another/path/dir2/g1
>/another/path/dir2/g2
>
> I tried this (following suggestion):
>
>   (for [file (file-seq dir) :while (.isFile file)] (.getPath file))
>
> It prints out a list with following items:
>   /path/top/dir1/f1
>   /path/top/dir1/f2
>   /path/top/dir2/g1
>   /path/top/dir2/g2
>
> BUT the last two items are the ones that I do NOT want.
> So, I guess I will need to tweak  file-seq so that it will NOT traverse
> /path/top/dir2  since it is a symbolic link.
>
> Is there anyway to tweak file-seq ??
>
> THanks
> HP
>
> On Saturday, October 3, 2015 at 11:59:40 AM UTC-4, Gary Verhaegen wrote:
>>
>> I'm on Windows at the moment, so I can't test, but I think you can 
>> filter on isFile: 
>>
>> (for [file (file-seq dir) 
>>   :where (.isFile file)] 
>>   (.getName file)) 
>>
>> should work, I think. 
>>
>> On 3 October 2015 at 07:36,   wrote: 
>> > Under linux, I have a tree of directories like this: 
>> > 
>> > /path/top 
>> > 
>> > /path/top/dir1  (in here there are two files f1, f2) 
>> > 
>> > /path/top/dir2 -> /another-path/dir2 (a symbolic link) 
>> > 
>> >  and under /another-path/dir2 there are two files g1, 
>> g2 
>> > 
>> > If I use below code, I would get a list of files f1, f2, and g1, g2 
>> > 
>> > (def directory (clojure.java.io/file "/path/top")) 
>> > (def files 
>> > (for [file (file-seq directory)] (.getName file))) 
>> > (files) 
>> > 
>> > BUT I want to skip traversing the directory dir2 since it is a symbolic 
>> > link. 
>> > 
>> > i.e. the list of files that I want to get is f1, f2 only. 
>> > 
>> > Could you please suggest a way to do this ? 
>> > 
>> > THanks 
>> > 
>> > HP 
>> > 
>> > -- 
>> > 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: Pattern matching on lists

2016-04-08 Thread Andy-
That's described here:

https://github.com/clojure/core.match/wiki/Basic-usage#sequential-types

Use: [([1] :seq)]


On Friday, April 8, 2016 at 2:37:37 PM UTC+2, Russell Wallace wrote:
>
> How do you do pattern matching on lists in Clojure? I've tried using 
> core.match but the examples all deal with vectors, and trying to specify a 
> list in the apparently obvious ways gets an error message about invalid 
> list syntax.
>

-- 
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: Removing duplicates from a series

2016-05-17 Thread Andy-
Hi,

dedupe is almost what you need, but you can just copy the source and modify 
it slightly:

(defn dedupe-by
  "Similar to dedupe but allows applying a function to the element by which to 
dedupe."
  ([f]
   (fn [rf]
 (let [pv (volatile! ::none)]
   (fn
 ([] (rf))
 ([result] (rf result))
 ([result input]
  (let [prior @pv
cv (f input)]
(vreset! pv cv)
(if (= prior cv)
  result
  (rf result input
  ([f coll] (sequence (dedupe-by f) coll)))


You can then just say `(dedupe-by :value xs)`.

HTH

On Tuesday, May 17, 2016 at 11:47:06 AM UTC+2, Simon Brooke wrote:
>
> I'm having trouble with writing a function
>
>1. in idiomatic clojure
>2. which doesn't blow the stack
>
> The problem is I have a time series of events e.g.
>
> ({:idhistory 78758272, :timestamp #inst 
> "2016-03-31T19:34:27.31300-00:00", :nameid 5637, :stringvalue nil, 
> :value 8000.0} 
>  {:idhistory 78756591, :timestamp #inst 
> "2016-03-31T19:33:31.69700-00:00", :nameid 5637, :stringvalue nil, 
> :value 7368.0} 
>  {:idhistory 78754249, :timestamp #inst 
> "2016-03-31T19:32:17.1-00:00", :nameid 5637, :stringvalue nil, 
> :value 6316.0} 
>  {:idhistory 78753165, :timestamp #inst 
> "2016-03-31T19:31:41.84300-00:00", :nameid 5637, :stringvalue nil, 
> :value 5263.0} 
>  {:idhistory 78751187, :timestamp #inst 
> "2016-03-31T19:30:36.21300-00:00", :nameid 5637, :stringvalue nil, 
> :value 4211.0}
>  {:idhistory 78749476, :timestamp #inst 
> "2016-03-31T19:29:41.36300-00:00", :nameid 5637, :stringvalue nil, 
> :value 3158.0} ...)
>
> which is to say, each event is a map, and each event has two critical 
> keys, :timestamp and :value. The series is sorted in descending order by 
> timestamp, i.e. most recent event first. These series are of up to millions 
> of events; the average length of the series is about half a million events. 
> However, many contain successive events at which the value does not change, 
> and where the value doesn't change I want to retain only the first event.
>
> So far what I've got is:
>
> (defn consolidate-events
>   "Return a time series like this `series`, but without those events whose 
> value is
>identical to the value of the preceding event."
>   [series]
>   (let [[car cadr & cddr] series]
> (cond
>   (empty? series) series
>   (=
> (get-value-for-event car)
> (get-value-for-event cadr)) (consolidate-events (rest series))
>   true (cons car (consolidate-events (rest series))
>
>
> Obviously, with millions of events or even merely hundreds of thousands, a 
> recursive function blows the stack. Furthermore, this one isn't even tail 
> call optimisable. I tried creating an inner function which I naively 
> thought should be tail call optimisable, but it fails 'Can only recur from 
> tail position':
>
> (defn consolidate-events
>   "Return a time series like this `series`, but without those events whose 
> value is
>   identical to the value of the preceding event."
>   [series]
>   (remove
> nil?
> (let [inner (fn [series]
>   (let [[car cadr & cddr] series]
> (if
>   (not (empty? series))
>   ;; then
>   (cons
> (if
>   (= (get-value-for-event car)
>  (get-value-for-event cadr))
>   ;; then
>   nil
>   ;; else
>   car)
> (if
>   (not (empty? series))
>   (recur (rest series)))]
> (inner series
>
>
> Test for the function is as follows:
>
> (deftest consolidate-events-test
>   (testing "consolidate-events"
> (let [s1 [{:timestamp #inst "2016-03-31T19:34:27.31300-00:00", 
> :value 8000.0}
>   {:timestamp #inst "2016-03-31T19:33:31.69700-00:00", 
> :value 7368.0}
>   {:timestamp #inst "2016-03-31T19:32:17.1-00:00", 
> :value 6316.0}
>   {:timestamp #inst "2016-03-31T19:31:41.84300-00:00", 
> :value 5263.0}
>   {:timestamp #inst "2016-03-31T19:30:36.21300-00:00", 
> :value 4211.0}
>   {:timestamp #inst "2016-03-31T19:29:41.36300-00:00", 
> :value 3158.0}]
>   s2 [{:timestamp #inst "2016-03-31T19:34:27.31300-00:00", 
> :value 8000.0}
>   {:timestamp #inst "2016-03-31T19:33:31.69700-00:00", 
> :value 7368.0}
>   {:timestamp #inst "2016-03-31T19:33:17.1-00:00", 
> :value 6316.0}
>   {:timestamp #inst "2016-03-31T19:32:27.1-00:00", 
> :value 6316.0}
>   {:timestamp #inst "2016-03-31T19:32:17.1-00:00", 
> :value 6316.0}
>   {:timestamp #inst "2016-03-31T19:31:41.84300-00:00", 
> :value 5263

Re: why my java code (call clojure from java ) run spend so much loooooog time .

2014-02-13 Thread Andy-
FYI:

http://stackoverflow.com/questions/21759848/

On Thursday, February 13, 2014 11:02:07 AM UTC-5, Xiaojun Weng wrote:
>
> I am a new clojure player,but i have wrote java code by few years.
>
> when i use emacs run my clojure code (read a big file  50M  ) , nrepl run 
> over use 30 second.
> but i use lein uberjar  clojure to jar .and i use it jar in eclipse , this 
> jar import in a embeded jetty when it started,   
> some time it would  outofmemory  or wait looog time. more than 30 minutes.
>
> some one tell me why. please. 
>

-- 
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/groups/opt_out.


Re: [ANN] Clojure 1.6.0-beta1

2014-02-15 Thread Andy-
inline
On Saturday, February 15, 2014 12:41:52 AM UTC-5, Mars0i wrote:
>
> Could someone clarify for me why "some?" as a name for not nil makes sense 
> at all in the first place?  Not criticizing.  I just don't understand what 
> existence or there being some of something has to do with nil.  
>
> Maybe I don't understand the intent of nil.  I came to Clojure from Common 
> Lisp.  nil is a weird beast in CL, but it's also a weird beast in Clojure.
>
> Is the idea that nil is supposed to be an empty structure, and empty? and 
> seq are too general?  But unlike nil in Common Lisp, nil in Clojure is not 
> an empty structure, even though (empty? nil) is true.  [], (), (lazy-seq), 
> #{}, and {} are empty structures.  Am I misunderstanding?
>

I *think* the idea to name it *some* is since nil often means "no value" 
(as already said by puzzler). This is also how Scala and F# name it:
http://en.wikipedia.org/wiki/Option_type

And the (some-> ..) macro has existed for a while which works the same so I 
think it makes a lot of sense to call it some? instead of non-nil?.

HTH

-- 
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/groups/opt_out.


Re: Looking for advice to fine tune a simple function

2014-02-16 Thread Andy-
I'm also very new to clojure but this is how I'd do it:

(def hr-zones {
   [0 100] :low
   [101 120] :fat-burn
   [121 140] :aerobic
   [141 160] :anaerobic
   [161 333] :max})

(defn hr->zone [hr]
  (some (fn [x]
(and (<= (first (key x)) hr (second (key x)))
 (val x)))
hr-zones))


This method does have some disadvantages however (you have to make sure the 
boundaries are correct and it doesn't handle floating points like 140.4).

Whenever you see yourself repeating code (like the 3-4 if's you have) then 
you have to take a step back and maybe change your data structure so that 
your algorithm is easier.

Mathematically speaking you're really quantizing your data (aka applying a 
piecewise constant function). So you could even take another step back and 
make it more general. So find a data structure that represents the function 
(ie the intervals and the function value for each interval) and then you 
could come up with a function like "quantize" or "mk-piecewise-const-fn" 
that returns a function. So you could then do:

(let [myfn (mk-piecewise-const-fn [[100 :zone-1] [120 :zone-2] ...] ]
   myzone (myfn 142)]

and you have a general function  which you can now use with a much wider 
range of problems (not just specific to your hr->zone conversion).

But I'm too lazy to come up with a implementation for mk-piecewise-const-fn 
:)

HTH


On Sunday, February 16, 2014 5:31:46 PM UTC-5, Laurent Droin wrote:
>
> Hi,
>
> Disclaimer - I am completely new to Clojure. I just implemented my very 
> first (simple) program, letting me find out, from a GPX file, how much time 
> is spent in the various heart rate zones. Now that it's working, I'm 
> reviewing the code and trying to use best practices. From what I have read 
> so far, there are many ways in Clojure to do the same thing and for a 
> newbie, it's not always obvious to get a good grasp on what is the best way 
> to  code a feature.
> As a developer, and even though I love how concise Clojure programs can 
> be, I am very concerned with readability and ease of maintenance so I would 
> like to keep functions as short and tight as possible, but not to the point 
> where it becomes hard to understand what it does.
>
> Here is a function that I came up with that takes  a bpm (heart beats per 
> minute) value, as well as a sequence of 4 values that represent the 
> boundaries defining the 5 different heart rate zones for a particular 
> person.
> The function needs to finds out in what heart zone the bpm value falls 
> into and return that zone (as a keyword - I later use that keyword in a 
> map).
>
> If you're an experienced Clojure developer, what would you have done 
> differently (and why) ?
>
> *(defn hr-zone*
> *  "Return the HR zone as a keyword according to the bpm value."*
> *  [bpm [max-zone-1 max-zone-2 max-zone-3 max-zone-4]] *
> *  (cond *
> *(<= bpm max-zone-1) :hr-zone-1*
> *(and (< max-zone-1 bpm) (>= max-zone-2 bpm)) :hr-zone-2 *
> *(and (< max-zone-2 bpm) (>= max-zone-3 bpm)) :hr-zone-3 *
> *(and (< max-zone-3 bpm) (>= max-zone-4 bpm)) :hr-zone-4 *
> *(< max-zone-4 bpm) :hr-zone-5))*
>
> FYI, here is how I call this function in the REPL:
> (def my-hr-zones-defs [120 150 165 180])
>
> (hr-zone 115 my-hr-zones-defs)
> (hr-zone 133 my-hr-zones-defs)
> (hr-zone 161 my-hr-zones-defs)
> (hr-zone 175 my-hr-zones-defs)
> (hr-zone 192 my-hr-zones-refs)
>
> Questions I have:
> Would that make sense to consider (and maybe enforce) that the sequence 
> received as parameter is sorted? If this was the case, I would assume I 
> could avoid the "and" calls- assuming that all the conditions in the cone 
> form are evaluated in order. 
> Assuming that I need to test bpm against the two boundaries of each range, 
> would there be a better way to do this:
> *(and (< max-zone-1 bpm) (>= max-zone-2 bpm))*
> ?
> Maybe this would work, but is it preferable?
> *(< max-zone-1 bpm (dec **max-zone-2**))*
>
> *Thanks in advance for the advice.*
>
> *Laurent. *
>
>

-- 
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/groups/opt_out.


Re: Looking for advice to fine tune a simple function

2014-02-16 Thread Andy-
I realized I could use that at some of my code so I wrote it. Not sure if 
it's the best possible implementation but here it is:

(defn quantizer
  "Returns a function that quantizes input data which when called with 'x' 
returns:   o <1st val> if-Inf < x <= <1st bound>   o <2st val> if <1st 
bound> < x <= <2st bound>   o ...   o  if  < x <=o >max if x >  where m is a vector of vectors where 
the first element specifies the boundary and   the second element the value 
which to return. Example:   (def points->grade (quantizer [[40 :F] [60 :D] 
[80 :C] [90 :B]] :A))   (map points->grade [10 80 93])   ; (:F :C :A)"
  [m >max]
  (fn [x]
(if (<= x (first (first m)))
  (second (first m))
  (if (> x (first (last m)))
>max
(some 
 (fn [i] 
   (let [[[l lv] [h hv]] i]
 (and (< l x) (<= x h) hv)))
 (partition 2 1 m))


Cheers


On Sunday, February 16, 2014 6:47:51 PM UTC-5, Andy- wrote:
>
> I'm also very new to clojure but this is how I'd do it:
>
> (def hr-zones {
>[0 100] :low
>[101 120] :fat-burn
>[121 140] :aerobic
>[141 160] :anaerobic
>[161 333] :max})
>
> (defn hr->zone [hr]
>   (some (fn [x]
> (and (<= (first (key x)) hr (second (key x)))
>  (val x)))
> hr-zones))
>
>
> This method does have some disadvantages however (you have to make sure 
> the boundaries are correct and it doesn't handle floating points like 
> 140.4).
>
> Whenever you see yourself repeating code (like the 3-4 if's you have) then 
> you have to take a step back and maybe change your data structure so that 
> your algorithm is easier.
>
> Mathematically speaking you're really quantizing your data (aka applying a 
> piecewise constant function). So you could even take another step back and 
> make it more general. So find a data structure that represents the function 
> (ie the intervals and the function value for each interval) and then you 
> could come up with a function like "quantize" or "mk-piecewise-const-fn" 
> that returns a function. So you could then do:
>
> (let [myfn (mk-piecewise-const-fn [[100 :zone-1] [120 :zone-2] ...] ]
>myzone (myfn 142)]
>
> and you have a general function  which you can now use with a much wider 
> range of problems (not just specific to your hr->zone conversion).
>
> But I'm too lazy to come up with a implementation for 
> mk-piecewise-const-fn :)
>
> HTH
>
>
> On Sunday, February 16, 2014 5:31:46 PM UTC-5, Laurent Droin wrote:
>>
>> Hi,
>>
>> Disclaimer - I am completely new to Clojure. I just implemented my very 
>> first (simple) program, letting me find out, from a GPX file, how much time 
>> is spent in the various heart rate zones. Now that it's working, I'm 
>> reviewing the code and trying to use best practices. From what I have read 
>> so far, there are many ways in Clojure to do the same thing and for a 
>> newbie, it's not always obvious to get a good grasp on what is the best way 
>> to  code a feature.
>> As a developer, and even though I love how concise Clojure programs can 
>> be, I am very concerned with readability and ease of maintenance so I would 
>> like to keep functions as short and tight as possible, but not to the point 
>> where it becomes hard to understand what it does.
>>
>> Here is a function that I came up with that takes  a bpm (heart beats per 
>> minute) value, as well as a sequence of 4 values that represent the 
>> boundaries defining the 5 different heart rate zones for a particular 
>> person.
>> The function needs to finds out in what heart zone the bpm value falls 
>> into and return that zone (as a keyword - I later use that keyword in a 
>> map).
>>
>> If you're an experienced Clojure developer, what would you have done 
>> differently (and why) ?
>>
>> *(defn hr-zone*
>> *  "Return the HR zone as a keyword according to the bpm value."*
>> *  [bpm [max-zone-1 max-zone-2 max-zone-3 max-zone-4]] *
>> *  (cond *
>> *(<= bpm max-zone-1) :hr-zone-1*
>> *(and (< max-zone-1 bpm) (>= max-zone-2 bpm)) :hr-zone-2 *
>> *(and (< max-zone-2 bpm) (>= max-zone-3 bpm)) :hr-zone-3 *
>> *(and (< max-zone-3 bpm) (>= max-zone-4 bpm)) :hr-zone-4 *
>> *(< max-zone-4 bpm) :hr-zone-5))*
>>
>> FYI, here is how I call this function in the REPL:
>> (def my-hr-zones-defs [120 150 165 180])
>>
>> (hr-zone 115 my-hr-zones-defs)
>> (hr-zone 133 my-hr-

Re: Latex style file for formatting/coloring clojure code?

2014-02-16 Thread Andy-
On Sunday, February 16, 2014 6:05:24 PM UTC-5, puzzler wrote:
>
> I am unable to find a style file that supports clojure code in LaTeX.  Can 
> anyone point me in the right direction?
>
Pygments can output LaTeX. (There is also minted)

HTH 

-- 
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/groups/opt_out.


Re: Looking for advice to fine tune a simple function

2014-02-17 Thread Andy-
On Sunday, February 16, 2014 11:19:58 PM UTC-5, Bruno Kim Medeiros Cesar 
wrote:
>
> (BTW, Andy, how do you format your code so prettily?)
>
I usually just paste it into pygments.org and then paste it back into 
google groups (which accepts the generated HTML).

Cheers 

-- 
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/groups/opt_out.


Re: Looking for advice to fine tune a simple function

2014-02-17 Thread Andy-
On Monday, February 17, 2014 6:43:18 PM UTC-5, Laurent Droin wrote:
>
>
> (def inf Long/MAX_VALUE)
> (defn quantize
>   [x markers values]
>   (let 
> [f (partial (fn([%1 %2 %3] (cond (<= %1 %2) %3))) x)]
> (first (filter #(not (nil? %))(map f (conj markers inf) values)
>
>
The reason I didn't go with Long/MAX_VALUE is that it breaks down for 
 arbitrary precision and bigints which is a no-no for me.

There is many many ways this function could look. Mine is just one example. 
For instance many clojurist's would probably prefer to call it like this:

(quantize 0 :small 5 :med :10 :large :huge).

I didn't go through your code. But many people don't like to overuse 
anonymous functions especially if you use 3 parameters (what is %1, %2 %3?, 
if they had a name it'd be clearer). But this is just style so it's very 
subjective.

Cheers

-- 
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/groups/opt_out.


Re: The Application Context Pattern

2009-02-27 Thread Andy Chambers

2009/2/27 Marko Kocić :
>
> Interesting approach, nice explained.
>
> Does anyone have similar example using one of the cells
> implementations?
> What would be pros/cons between this and cells approach?

The cells implementations I've seen posted to this list (in fact pretty much all
cells reimplementations) haven't yet approached the sophistication of
kenny-cells.

It's like editors.  Everyone reckons they can make one better than emacs (or
vi) but underestimate the man-hours that have gone into them over the years
and end up with something that maybe looks as good (or better) superficially
but when you delve into the details, just doesn't cut the mustard.

I'd love to see some kind of clojure-cells but it's still a long way off.

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from this group, send email to 
clojure+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: Clojure performance tests and clojure a little slower than Java

2009-07-29 Thread Andy Fingerhut

I have added a script that uses the Java version of the benchmark
programs to generate the large files that were in the distribution
file I gave a link to earlier, so it is much smaller.  I've also
published it on github and added a COPYING file that makes the
licenses more explicit (revised BSD for everything, some copyright by
me, the rest by the owner of the benchmark web site).  You can get it
here:

git://github.com/jafingerhut/clojure-benchmarks.git

Again, submissions for new benchmark programs, or improvements to
existing ones, are welcome.

Thanks,
Andy


On Jul 28, 8:52 am, AndyF  wrote:
> Anybody is welcome to take the Clojure sources and do what they will
> with them -- publish the original or modified code under their own
> license, sell it, etc.
>
> For the Perl, Common Lisp, Haskell, etc. sources, those are published
> under this license.  It isn't my code.
>
> http://shootout.alioth.debian.org/u32q/miscfile.php?file=license&titl...
>
> Andy
>
> On Jul 28, 5:09 am, Berlin Brown  wrote:
>
> > Thanks AndyF, do you mind if I use some of your examples and put my
> > own spin on them.  I was curious and want to run my own tests and see
> > if I get similar output?
>
> > On Jul 28, 12:03 am, ataggart  wrote:
>
> > > On Jul 27, 10:06 am, BerlinBrown  wrote:
>
> > > > So far I have found that clojure is about
> > > > 5-10 times as slow as comparable code in Clojure.
>
> > > I infer you mean clojure execution times are about 5-10 times longer
> > > than in java.  It depends on what you're doing, but that sounds
> > > plausible.
>
> > > Here's are some slides of a comparison between a number of JVM
> > > languages:
>
> > >http://www.slideshare.net/michael.galpin/performance-comparisons-of-d...
>
> > > Note that in the "reversible" section, he has a loop in the clojure
> > > code with unnecessary Integer object creation which ends up doubling
> > > the execution time.

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



Good memory profilers (program or human)?

2009-07-30 Thread Andy Fingerhut

I'm gradually adding a few more Clojure benchmark programs to my
repository here:

git://github.com/jafingerhut/clojure-benchmarks.git

The one I wrote for the "reverse-complement" benchmark is here:

http://github.com/jafingerhut/clojure-benchmarks/blob/4ab4f41c6f963445e1e0973a668ac64939be1c7f/rcomp/revcomp.clj-4.clj

revcomp.clj-4.clj is the best I've got so far, but it runs out of
memory on the full size benchmark.

If you clone the repository, and successfully run the init.sh script
to generate the big input and expected output files, the file rcomp/
long-input.txt contains 3 DNA sequences in FASTA format. The first is
50,000,000 characters long, the second is 75,000,000 characters long,
and the third is 125,000,000 characters long. Each needs to be
reversed, have each character replaced with a different one, and
printed out, so we need to store each of the strings one at a time,
but it is acceptable to deallocate/garbage-collect the previous one
when starting on the next. I think my code should be doing that, but I
don't know how to verify that.

I've read that a Java String takes 2 bytes per character, plus about
38 bytes of overhead per string. That is about 250 Mbytes for the
longest one. I also read in a seq of lines, and these long strings are
split into lines with 60 characters (plus a newline) each. Thus the
string's data needs to be stored at least twice temporarily -- once
for the many 60-character strings, plus the final long one.  Also, the
Java StringBuilder that Clojure's (str ...) function uses probably
needs to be copied and reallocated periodically as it outgrows its
current allocation. So I could imagine needing about 3 * 250 Mbytes
temporarily, but that doesn't explain why my 1536 Mbytes of JVM memory
are being exhausted.

It would be possible to improve things by not creating all of the
separate strings, one for each line, and then concatenating them
together. But first I'd like to explain why it is using so much,
because I must be missing something.

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



Re: Good memory profilers (program or human)?

2009-07-31 Thread Andy Fingerhut

I thought I'd follow up my own question with some programs that I
should have already known about for memory profiling, which were
already installed on my Mac as part of the standard Java installation
from Apple (who are just passing them on from Sun, I'm sure), but I
didn't know about them:

jconsole -- Good for seeing how fast a java process is allocating
memory, and garbage collecting.

jmap -- Good for a quick summary of the above, or with the "-histo"
option, a much more detailed list of what kinds of objects are taking
up the most memory.

I also learned that Clojure's cons and lazy cons structures take up 48
bytes per element (at least on a Mac with 'java -client' and java
1.6.0_), which gets significant when your program has sequences
of several millions of elements about.

I've updated my github repo with a pretty decent version of the
reverse-complement benchmark in Clojure.  It isn't as sequence-y as it
could be, but the more sequence-y version generates and collects
garbage so fast that it really slows things down significantly.  Same
lesson from other flavors of Lisp, I guess -- you can write the
straightforward easy-to-write-and-test-and-understand code that conses
a lot (i.e. allocates memory quickly that typically becomes garbage
quite soon), or you can write the more loopy code that doesn't, but
typically starts to merge many things that you'd otherwise prefer to
separate into different functions.  Just compare revcomp.clj-5.clj and
revcomp.clj-6.clj in my git repo for an example.

The nice thing is that when you don't need the "uglier" code, Clojure
and other Lisps usually let you write code much more concisely than
lower level languages.  Get it working first, then optimize it.  Since
I'm comparing run times of the Clojure programs versus those submitted
to the language shootout benchmark web site, some of which appear
quite contorted in order to gain performance, I wanted to do some
optimizations that you wouldn't necessarily want to do otherwise.

git://github.com/jafingerhut/clojure-benchmarks.git

You can see my latest run time results here.  I've got 4 benchmarks
written in Clojure so far, with my current versions being 6x, 8x, 12x,
and 15x more CPU time than the Java programs submitted to the language
shootout benchmark web site.

http://github.com/jafingerhut/clojure-benchmarks/blob/20d21bc169d52ca52d6a8281536838662c54e854/RESULTS

I could make some of these significantly closer in speed to the Java
versions, but I suspect that they will start looking more and more
like the Java versions if I do, except with Clojure syntax for Java
calls.  I'm happy to be proved wrong on that, if someone finds better
Clojure versions than I've got.

Thanks,
Andy


On Jul 30, 11:00 am, Andy Fingerhut 
wrote:
> I'm gradually adding a few more Clojure benchmark programs to my
> repository here:
>
> git://github.com/jafingerhut/clojure-benchmarks.git
>
> The one I wrote for the "reverse-complement" benchmark is here:
>
> http://github.com/jafingerhut/clojure-benchmarks/blob/4ab4f41c6f96344...
>
> revcomp.clj-4.clj is the best I've got so far, but it runs out of
> memory on the full size benchmark.
>
> If you clone the repository, and successfully run the init.sh script
> to generate the big input and expected output files, the file rcomp/
> long-input.txt contains 3 DNA sequences in FASTA format. The first is
> 50,000,000 characters long, the second is 75,000,000 characters long,
> and the third is 125,000,000 characters long. Each needs to be
> reversed, have each character replaced with a different one, and
> printed out, so we need to store each of the strings one at a time,
> but it is acceptable to deallocate/garbage-collect the previous one
> when starting on the next. I think my code should be doing that, but I
> don't know how to verify that.
>
> I've read that a Java String takes 2 bytes per character, plus about
> 38 bytes of overhead per string. That is about 250 Mbytes for the
> longest one. I also read in a seq of lines, and these long strings are
> split into lines with 60 characters (plus a newline) each. Thus the
> string's data needs to be stored at least twice temporarily -- once
> for the many 60-character strings, plus the final long one.  Also, the
> Java StringBuilder that Clojure's (str ...) function uses probably
> needs to be copied and reallocated periodically as it outgrows its
> current allocation. So I could imagine needing about 3 * 250 Mbytes
> temporarily, but that doesn't explain why my 1536 Mbytes of JVM memory
> are being exhausted.
>
> It would be possible to improve things by not creating all of the
> separate strings, one for each line, and then concatenating them
> together. But first I'd like to expla

Re: Transient Data Structures

2009-08-03 Thread Andy Fingerhut

I like it.  I can see significant use of these to help speed up some
of the benchmark programs I've been hacking on:

git://github.com/jafingerhut/clojure-benchmarks.git

and more importantly, that means they can be good in optimizing useful
code, too :-)

I was pondering this question "If a pure function mutates some local
data in order to produce an immutable return value, is that ok?" that
Rich posed just a day or three ago, when thinking about whether there
was a way to automatically determine whether a function is pure /
"referentially transparent" or not (at least for a useful subset of
actual Clojure code).  In particular, Clojure's str function does this
already with StringBuilder.append:

(defn str
;; doc string deleted for brevity
  ([] "")
  ([#^Object x]
   (if (nil? x) "" (. x (toString
  ([x & ys]
 ((fn [#^StringBuilder sb more]
  (if more
(recur (. sb  (append (str (first more (next more))
(str sb)))
  (new StringBuilder #^String (str x)) ys)))

Very nice to see the idea generalized to Clojure data structures, too,
and the safety nets built into it in case someone forgets to call
"persistent!" on a data structure before using it in another thread.

Thanks,
Andy


On Aug 3, 2:25 pm, Rich Hickey  wrote:
> I've been doing some work on Transient Data Structures. You can read
> about them here:
>
> http://clojure.org/transients
>
> Feedback welcome,
>
> Rich

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



pmap uses more parallelism than intended due to use of "eager" map?

2009-08-04 Thread Andy Fingerhut

I was looking into the question raised in the "Question about pmap"
thread, and noticed that on my Mac and on a Linux virtual machine, a
recent git version of clojure (about 1 week old) seems to use more
parallelism in 'pmap' than its source code in core.clj would imply is
the intent.  The code there seems to imply that the desired number of
threads to run at once is 2 more than the number of available
processors.  However, when I run it, it always fires off one thread
for every element of the collection, right at the beginning,
regardless of the number of available processors.

I created my own slightly modified version of pmap, where the only
difference is that the version of 'map' used has been changed to 'my-
lazy-map', which is explicitly lazy.  See this link for the source
code of the test I was using.  Ignore modified-pmap1.  Look at
modified-pmap2.

http://github.com/jafingerhut/clojure-benchmarks/blob/0227501c6c53736db05facd647c09e1d4e9e77b3/misc/pmap-testing.clj

You can try this out on your system with a command line like this:

clj pmap-test.clj 10 1

You might need to adjust the second number to be more or less,
depending upon the speed of your machine.  It would be good to make it
take at least a couple of seconds.  The first number is the length of
the collection over which map/pmap is run, and for most obvious
results should be about 3 to 4 times the number of processors on your
machine.

I suspect that the issue is that the version of map used by pmap in
core.clj is eager, i.e. not lazy, and thus all of the called to future
are performed as soon as the last of these lines in the pmap function
is executed:

(defn pmap
  ;; doc string deleted for brevity
  ([f coll]
   (let [n (+ 2 (.. Runtime getRuntime availableProcessors))
 rets (map #(future (f %)) coll)

but I don't know yet where the implementation of map that is "active"
at that point in the source code is.  Perhaps it is implemented in
Java?

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



Re: Question about pmap

2009-08-04 Thread Andy Fingerhut

Johann:

Could it be that your CPU has a single floating-point unit shared by 4
cores on a single die, and thus only 2 floating-point units total for
all 8 of your cores?  If so, then that fact, plus the fact that each
core has its own separate ALU for integer operations, would seem to
explain the results you are seeing.  I see similar results on my 2-
core Intel Core 2 Duo when running your test.

I tried to check out that possibility by doing some searches on the
Internet about the Xeon, but couldn't quickly find a definitive
answer.  I'm hoping someone else on the group might know the answer
off the top of their head.

Andy


On Aug 4, 1:59 am, Johann Kraus  wrote:
> > My guess would be you're seeing the overhead for pmap since the
> > (inc 0.1) computation is so cheap.  From the docs for pmap:
> >   "Only useful for computationally intensive functions where the time of
> >   f dominates the coordination overhead."
>
> I don't think so, as the cheap computation (inc 0.1) is packed into
> the long running (dotimes). And it does work for using (inc 0), where
> I get a perfect linear speedup. Just by using (inc 0.1) instead of
> (inc 0) the speedup is rapidly getting down while the CPU load is next
> to the limit.
>
> > Maybe try this with something more expensive to compute?  Also, making
> > the result a function of the parameter can't hurt since there's a chance
> > the JVM may optimize away the inc of a constant as it stands.
>
> I also would expect the JVM to optimize away something, but for me it
> seems it does not, because again in case of (inc 0) everything works
> perfect.
>
> The point is:
> Why do I get a linear speedup with (inc 0) -> 8 times and not with
> (inc 0.1) -> 2 times, while the CPU load is 800% and 700%,
> respectively?
> __
> Johann

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



Re: pmap uses more parallelism than intended due to use of "eager" map?

2009-08-04 Thread Andy Fingerhut

Ugh.  A couple minutes of more careful searching and I had the
answer.  It isn't because the map used by pmap is eager, it is because
it optimizes for input collections that are chunked.

It seems worth considering modifying pmap to either:

(1) use a lazy version of map, with no optimization for chunked
collections.  That's pretty quick and easy.

or

(2) modify the pmap implementation so that even if map optimized for
chunked collections, pmap doesn't use more parallelism than intended.
That would require a more significant code change in pmap.

Thanks,
Andy


On Aug 4, 1:31 pm, Andy Fingerhut 
wrote:
> I was looking into the question raised in the "Question about pmap"
> thread, and noticed that on my Mac and on a Linux virtual machine, a
> recent git version of clojure (about 1 week old) seems to use more
> parallelism in 'pmap' than its source code in core.clj would imply is
> the intent.  The code there seems to imply that the desired number of
> threads to run at once is 2 more than the number of available
> processors.  However, when I run it, it always fires off one thread
> for every element of the collection, right at the beginning,
> regardless of the number of available processors.
>
> I created my own slightly modified version of pmap, where the only
> difference is that the version of 'map' used has been changed to 'my-
> lazy-map', which is explicitly lazy.  See this link for the source
> code of the test I was using.  Ignore modified-pmap1.  Look at
> modified-pmap2.
>
> http://github.com/jafingerhut/clojure-benchmarks/blob/0227501c6c53736...
>
> You can try this out on your system with a command line like this:
>
> clj pmap-test.clj 10 1
>
> You might need to adjust the second number to be more or less,
> depending upon the speed of your machine.  It would be good to make it
> take at least a couple of seconds.  The first number is the length of
> the collection over which map/pmap is run, and for most obvious
> results should be about 3 to 4 times the number of processors on your
> machine.
>
> I suspect that the issue is that the version of map used by pmap in
> core.clj is eager, i.e. not lazy, and thus all of the called to future
> are performed as soon as the last of these lines in the pmap function
> is executed:
>
> (defn pmap
>   ;; doc string deleted for brevity
>   ([f coll]
>    (let [n (+ 2 (.. Runtime getRuntime availableProcessors))
>          rets (map #(future (f %)) coll)
>
> but I don't know yet where the implementation of map that is "active"
> at that point in the source code is.  Perhaps it is implemented in
> Java?
>
> 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
-~--~~~~--~~--~--~---



Re: Question about pmap

2009-08-06 Thread Andy Fingerhut

On Aug 5, 6:09 am, Rich Hickey  wrote:
> On Wed, Aug 5, 2009 at 8:29 AM, Johann Kraus wrote:
>
> >> Could it be that your CPU has a single floating-point unit shared by 4
> >> cores on a single die, and thus only 2 floating-point units total for
> >> all 8 of your cores?  If so, then that fact, plus the fact that each
> >> core has its own separate ALU for integer operations, would seem to
> >> explain the results you are seeing.
>
> > Exactly, this would explain the behaviour. But unfortunately it is not
> > the case. I implemented a small example using Java (Java Threads) and
> > C (PThreads) and both times I get a linear speedup. See the attached
> > code below. The cores only share 12 MB cache, but this should be
> > enough memory for my micro-benchmark. Seeing the linear speedup in
> > Java and C, I would negate a hardware limitation.
>
> > _
> > Johann
>
>
> I looked briefly at your problem and don't see anything right off the
> bat. Do you have a profiler and could you try that out? I'm
> interested.
> Rich

I ran these tests on my iMac with 2.16 GHz Intel Core 2 Duo (2 cores)
using latest Clojure and clojure-contrib from git as of some time on
Aug 4, 2009.  The Java implementation is from Apple, version 1.6.0_13.

--
For int, there are 64 "jobs" run, each of which consists of doing
(inc 0) 1,000,000,000 times.  See pmap-batch.sh and pmap-testing.clj
for details.

http://github.com/jafingerhut/clojure-benchmarks/blob/398688c71525964ba4c2d55d0e487b7618efdc8b/misc/pmap-batch.sh

http://github.com/jafingerhut/clojure-benchmarks/blob/398688c71525964ba4c2d55d0e487b7618efdc8b/misc/pmap-testing.clj

Yes, yes, I know.  I should really use a library for command line
argument parsing to avoid so much repetitive code.  I may do that some
day.


Results for int 1 thread - jobs run sequentially

"Elapsed time: 267547.789 msecs"
real   269.22
user   268.61
sys  1.79

int 2 threads - jobs run in 2 threads using modified-pmap, which
limits the number of futures causing threads to run jobs to be at most
2 at a time.

"Elapsed time: 177428.626 msecs"
real   179.14
user   330.30
sys 15.46

Comment: Elapsed time with 2 threads is about 2/3 of elapsed time with
1 thread.  Not as good as the 1/2 as we'd like with a 2 core machine,
but better than not being faster at all.

--
For double, there are 16 "jobs" run, each of which consists of doing
(inc 0.1) 1,000,000,000 times.

double 1 thread

"Elapsed time: 258659.424 msecs"
real   263.28
user   247.29
sys 12.17

double 2 threads

"Elapsed time: 229382.68 msecs"
Dumping CPU usage by sampling running threads ... done.
real   231.05
user   380.79
sys 11.49

Comment: Elapsed time with 2 threads is about 7/8 of elapsed time with
1 thread.  Hardly any improvement at all for something that should be
"embarrassingly parallel", and the user time reported by Mac OS X's
/usr/bin/time increased by a factor of about 1.5.  That seems like way
too much overhead for thread coordination.


Here are hprof output files for the "double 1 thread" and "double 2
threads" tests:

http://github.com/jafingerhut/clojure-benchmarks/blob/51d499c2679c2d5ed42a65adcef6d9e8bc3e1aad/misc/pmap-batch-output/pmap-double-1-hprof.txt

http://github.com/jafingerhut/clojure-benchmarks/blob/51d499c2679c2d5ed42a65adcef6d9e8bc3e1aad/misc/pmap-batch-output/pmap-double-2-hprof.txt

In both cases, over 98% of the time is spent in
java.lang.Double.valueOf(double d).  See the files for the full stack
backtraces if you are curious.

I don't see any reason why that method should have any kind of
contention or worse performance when running on 2 cores vs. 1 core,
but I don't know the guts of how it is implemented.  At least in
OpenJDK all it does is "return new Double(d)", where d is the double
arg to valueOf().  Is there any reason why "new" might exhibit
contention between parallel threads?

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



Re: Question about pmap

2009-08-06 Thread Andy Fingerhut



On Aug 6, 10:00 am, Bradbev  wrote:
> On Aug 6, 3:07 am, Andy Fingerhut 
> wrote:
>
>
>
> > On Aug 5, 6:09 am, Rich Hickey  wrote:
>
> > > On Wed, Aug 5, 2009 at 8:29 AM, Johann Kraus 
> > > wrote:
>
> > > >> Could it be that your CPU has a single floating-point unit shared by 4
> > > >> cores on a single die, and thus only 2 floating-point units total for
> > > >> all 8 of your cores?  If so, then that fact, plus the fact that each
> > > >> core has its own separate ALU for integer operations, would seem to
> > > >> explain the results you are seeing.
>
> > > > Exactly, this would explain the behaviour. But unfortunately it is not
> > > > the case. I implemented a small example using Java (Java Threads) and
> > > > C (PThreads) and both times I get a linear speedup. See the attached
> > > > code below. The cores only share 12 MB cache, but this should be
> > > > enough memory for my micro-benchmark. Seeing the linear speedup in
> > > > Java and C, I would negate a hardware limitation.
>
> > > > _
> > > > Johann
>
> > > I looked briefly at your problem and don't see anything right off the
> > > bat. Do you have a profiler and could you try that out? I'm
> > > interested.
> > > Rich
>
> > I ran these tests on my iMac with 2.16 GHz Intel Core 2 Duo (2 cores)
> > using latest Clojure and clojure-contrib from git as of some time on
> > Aug 4, 2009.  The Java implementation is from Apple, version 1.6.0_13.
>
> > --
> > For int, there are 64 "jobs" run, each of which consists of doing
> > (inc 0) 1,000,000,000 times.  See pmap-batch.sh and pmap-testing.clj
> > for details.
>
> >http://github.com/jafingerhut/clojure-benchmarks/blob/398688c71525964...
>
> >http://github.com/jafingerhut/clojure-benchmarks/blob/398688c71525964...
>
> > Yes, yes, I know.  I should really use a library for command line
> > argument parsing to avoid so much repetitive code.  I may do that some
> > day.
>
> > Results for int 1 thread - jobs run sequentially
>
> > "Elapsed time: 267547.789 msecs"
> > real       269.22
> > user       268.61
> > sys          1.79
>
> > int 2 threads - jobs run in 2 threads using modified-pmap, which
> > limits the number of futures causing threads to run jobs to be at most
> > 2 at a time.
>
> > "Elapsed time: 177428.626 msecs"
> > real       179.14
> > user       330.30
> > sys         15.46
>
> > Comment: Elapsed time with 2 threads is about 2/3 of elapsed time with
> > 1 thread.  Not as good as the 1/2 as we'd like with a 2 core machine,
> > but better than not being faster at all.
>
> > --
> > For double, there are 16 "jobs" run, each of which consists of doing
> > (inc 0.1) 1,000,000,000 times.
>
> > double 1 thread
>
> > "Elapsed time: 258659.424 msecs"
> > real       263.28
> > user       247.29
> > sys         12.17
>
> > double 2 threads
>
> > "Elapsed time: 229382.68 msecs"
> > Dumping CPU usage by sampling running threads ... done.
> > real       231.05
> > user       380.79
> > sys         11.49
>
> > Comment: Elapsed time with 2 threads is about 7/8 of elapsed time with
> > 1 thread.  Hardly any improvement at all for something that should be
> > "embarrassingly parallel", and the user time reported by Mac OS X's
> > /usr/bin/time increased by a factor of about 1.5.  That seems like way
> > too much overhead for thread coordination.
>
> > Here are hprof output files for the "double 1 thread" and "double 2
> > threads" tests:
>
> >http://github.com/jafingerhut/clojure-benchmarks/blob/51d499c2679c2d5...
>
> >http://github.com/jafingerhut/clojure-benchmarks/blob/51d499c2679c2d5...
>
> > In both cases, over 98% of the time is spent in
> > java.lang.Double.valueOf(double d).  See the files for the full stack
> > backtraces if you are curious.
>
> > I don't see any reason why that method should have any kind of
> > contention or worse performance when running on 2 cores vs. 1 core,
> > but I don't know the guts of how it is implemented.  At least in
> > OpenJDK all it does is "return new Double(d)", where d is the double
> > arg to valueOf().  Is there any reason why "

Re: Transient Data Structures

2009-08-06 Thread Andy Fingerhut



On Aug 6, 4:53 am, Rich Hickey  wrote:
> On Aug 5, 10:10 pm, Luc Prefontaine 
> wrote:
>
> > I like this very much... that's the kind of clever optimizations that
> > preserves Clojure principles and
> > can yield significant performance increases. This could also help
> > dealing with performance critics
> > in these small mutable languages "benchmarks" that newbies attempt to
> > clone in Clojure.
>
> > Thank's Rich !
>
> You're welcome!
>
> And special thanks to Christophe Grand, who (quickly!) applied the
> same technique to the hash maps and contributed that yesterday. So
> now, in the master branch, vectors and hash maps support transients.
> Everyone please try them out (where appropriate :).
>
> Rich

Thank you, Christophe!  I've been wanting to try those out.

I made changes to 3 lines of my Clojure program for the k-nucleotide
benchmark, which spends most of its time in a function tally-dna-subs-
with-len that creates a hash map counting the number of times that
each of a bunch of length k strings occurs in a long string.  Source
here, if you're curious:

http://github.com/jafingerhut/clojure-benchmarks/blob/38e1f592ca3befe94a0674a5f5a43d952cd369b3/knuc/knucleotide.clj-7.clj

It went from about 19 minutes down to about 12 minutes.  Excellent
improvement for a small change to the code.  That brings it down to
about 7.7 times the run time of the Java version from the language
shootout web site.

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



Re: Clojure performance tests and clojure a little slower than Java

2009-08-06 Thread Andy Fingerhut

On Aug 6, 3:28 pm, André Thieme  wrote:
> On 27 Jul., 23:26, AndyF  wrote:
>
> Hello Andy, could you please update the following table?
>
>
>
> >         |  sbcl  |  perl  |   ghc  |  java |   clj
> > -
> > mand-   | wrong  | out of |  32.7  |  28.6  | 340.4
> > elbrot  | output | mem    |  59.3  |  54.4  | 350.5
> >         |        | (?)    |   0.8  |   0.4  |   4.7
>
> > k-nuc-  | 190.9  | 306.0  |  90.5  |  52.4  | 1677.6 (27m 57.6s)
> > leotide | 187.9  | 302.7  | 130.8  |  89.6  | 2245.1 (37m 25.1s)
> >         |   2.4  |   1.9  |   4.6  |   1.8  |   24.2 (    24.2s)
>
> When I understand you correctly, you now use Transients
> in those benchmarks, which improved their runtime behaviour.

You are correct.  I've updated that file:

http://github.com/jafingerhut/clojure-benchmarks/blob/bb9755bdeeccae84a9b09fbf34e45f6d45d4b627/RESULTS

I've attempted to always put the best Clojure program results I've
found so far on the same line with the run times for the programs in
other languages, and then sometimes I will also include the second
best Clojure results on a separate group of lines after 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
-~--~~~~--~~--~--~---



Re: Question about pmap

2009-08-06 Thread Andy Fingerhut

On Aug 6, 11:51 am, John Harrop  wrote:
> Cache misses are a possibility; try the integer version with long, so the
> size of the data is the same as with double.
> The other possibility I'd consider likely is that the JDK you were using
> implements caching in Double.valueOf(double). This could be dealt with if
> Clojure boxing directly called new Double(double). Caching in valueOf
> methods has been known to cause trouble in other situations, involving Java,
> primitive boxing, and performance. Besides the caching wrecking memory
> access-pattern locality, causing CPU cache misses, it likely involves
> acquiring and releasing a global lock on the Double cache, which will kill
> multithreaded performance particularly.

Interesting how the caching can mess performance up, especially in
multi-threaded situations.  I don't know yet how to confirm whether my
implementation uses that caching, but I did see a mention of it in
some docs for Double.valueOf(double), and didn't think about the
possibility of that introducing locking.  In this particular test, I
doubt it would increase non-locality much if at all, since we are
always providing the same value (0.1) to the method, so the cache
should have exactly 1 element in it the whole time.  But if it were
synchronized, that would definitely bring down the performance of this
particular test, or in general any test with a significant number of
float or double operations, down closer to that of a single core.

If that is the performance bottleneck in this case, is there any way
around it?  Perhaps I could try locally changing my Clojure Java
source to use new Double instead of Double.valueOf(double) and it
might actually be faster.

I'll try out some variations with different types like long and float,
and report back when I've got them.

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



combining methods

2009-08-07 Thread Andy Chambers

Hey All,

Does clojure have an equivalent of either CLOS's `call-next-method' or
java's super?

For example, given the multi-method, and the interfaces ICDISCElement
and IODMDef, where IODMDef extends ICDISCElement

(defmulti validate class)

(defmethod validate ICDISCElement [elem]
  ;;generic validation of all elements)

(defmethod validate IODMDef [def]
  ;;how can I do stuff in here then pass control to the other validate
method)


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



Re: Clojure performance tests and clojure a little slower than Java

2009-08-07 Thread Andy Fingerhut


On Aug 6, 6:49 pm, John Harrop  wrote:
> On Thu, Aug 6, 2009 at 6:57 PM, Andy Fingerhut <
>
> andy_finger...@alum.wustl.edu> wrote:
> > You are correct.  I've updated that file:
>
> >http://github.com/jafingerhut/clojure-benchmarks/blob/bb9755bdeeccae8...
>
> Could you post the Mandelbrot code you use? Because I know for a fact that
> Clojure can do FP calcs as fast as native C code, given the -server vm and a
> loop/recur with unboxed doubles, and my understanding of Mandelbrot is that
> it's just FP calcs.

Here is the root of the clojure-benchmarks github directory tree.
They are all in there:

http://github.com/jafingerhut/clojure-benchmarks/tree/master

You can get specific files by browsing the directory tree on the web
site, or if you use git, you can git clone the whole thing and have a
local copy on your computer:

git clone git://github.com/jafingerhut/clojure-benchmarks.git

It is mandelbrot/mandelbrot.clj-1.clj.  There is a
mandelbrot.clj-2.clj that is the same, except it uses my modified-pmap
to compute separate rows in parallel.  I'm still investigating reasons
why parallelism isn't getting me much bang for the buck in the
"questions about pmap" thread before worrying performance turning more
complex programs using floats/doubles in parallel.

I did go back to the archives for a discussion in early April, 2009
when others on this list were discussing how to tweak the core of the
mandelbrot code (the function "dot" in my version), and I used the
fastest of those versions I could find, but I may have missed some
opportunities for speeding it up, and I definitely welcome any and all
improved versions.  I'd recommend comparing the speed on your machine
vs. the Java version that is in the same directory as the Clojure
source.

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



Re: Test a random function

2009-08-07 Thread Andy Fingerhut

On Aug 7, 6:17 pm, Sean Devlin  wrote:
> Ok, I need some help.  I'm writing some tests for c.c.seq-utils, and I
> ran into a problem defining a test for both shuffle and rand-elt.
>
> Does anyone here have any experience writing tests for random
> functions?  Am I going to need to use serious statistics the answer
> this?
>
> Ideas?

It depends upon what you want to test.  If you want to test that rand-
elt selects an item from the seq s independently on each run, and with
equal probability for all elements, then that is effectively like
testing rand-int for the same properties, and yes, you will have to
get into some statistics to do so.

However, if you back off from testing the random part of the function,
there are some "invariants" that are always true that you could test,
such as:

(1) the value x returned by rand-elt should always be a member of the
seq s

(2) the value returned by shuffle should always have the same number
of each item as the input seq s.  That is, if you evaluate the
function 'tally' below on the input seq s and on the returned seq t,
you should always find (= (tally s) (tally t)) is true.

(defn tally [s]
  (loop [s s
 t (transient {})]
(if-let [s (seq s)]
  (let [item (first s)]
(recur (next s) (assoc! t item (inc (get t item 0)
  (persistent! t

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



Re: Clojure performance tests and clojure a little slower than Java

2009-08-07 Thread Andy Fingerhut

On Aug 7, 5:14 pm, John Harrop  wrote:
> Your core loop seems to be:
> (loop [zr (double 0.0)
>          zi (double 0.0)
>          zr2 (double 0.0)
>          zi2 (double 0.0)
>          iterations-remaining iterations-remaining]
>     (if (and (not (neg? iterations-remaining))
>              (< (+ zr2 zi2) limit-square))
>       (let [new-zi (double (+ (* (* f2 zr) zi) pi))
>             new-zr (double (+ (- zr2 zi2) pr))
>             new-zr2 (double (* new-zr new-zr))
>             new-zi2 (double (* new-zi new-zi))]
>         (recur new-zr new-zi new-zr2 new-zi2 (dec iterations-remaining)))
>
> What I suggest is
>
> (loop [zr (double 0.0)
>        zi (double 0.0)
>        i (int (inc iterations-remaining))]
>   (let [zr2 (* zr zr)
>         zi2 (* zi zi)]
>     (if (and (not (= 0 i)) (< (+ zr2 zi2 limit-square)))
>        (recur (+ (- zr2 zi2) pr) (+ (* (* f2 zr) zi) pi) (unchecked-inc i))
>        (whatever...
>
> * Same calculations
> * Less items in recur rebind
> * Counter is also primitive
>
> (untested, may need slight tweakage)

Needed unchecked-dec in place of unchecked-inc, and I used (zero? i)
instead of (= 0 i) (not sure if that makes much difference), and the
results are much better -- the time went down to a little less than
half of what it was before.

http://github.com/jafingerhut/clojure-benchmarks/blob/fe10ef25ec17b77dd03f6d1ccff4f35273764f3b/RESULTS

I also tried it with 4 parallel threads on my 2-core machine, and this
problem parallelizes significantly better than the simpler problem in
the "questions about pmap" discussion thread -- nearly half the
elapsed time, and only 6% more total CPU time for the 4-thread version
vs. the sequential version.

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



Re: Question about pmap

2009-08-08 Thread Andy Fingerhut

Johann, if you are still following this thread, could you try running
this Clojure program on your 8 core machine?

http://github.com/jafingerhut/clojure-benchmarks/blob/3e45bd8f6c3eba47f982a0f6083493a9f076d0e9/misc/pmap-testing.clj

These first set of parameters below will do 8 jobs sequentially, each
doing 10^10 (inc c)'s, where c is a double primitive.  The second will
do the 8 jobs in parallel, hopefully finishing about 8 times faster on
your machine:

java -cp  clojure.main pmap-testing.clj double2 8
100 1
java -cp  clojure.main pmap-testing.clj double2 8
100 8

If you replace double2 with double1, it should reproduce your initial
test case with (inc 0.1) in the inner loop -- the one that started
this thread about why there wasn't much speedup.


I created some Clojure and Java functions that are as similar as I
know how to make them, but frankly I don't really know whether my JVM
implementation (Apple's java 1.6.0_13) is using 'new Double', or a
cache as mentioned by John Harrop earlier in this discussion, in its
implementation of Double.valueOf(double).  I've found that the
performance is very similar to a Java program that uses 'new Double'
explicitly in its inner loop.

In the results linked below, the 'sequential' runs are for calling the
function named twice in a row, whereas the 'parallel' runs are for
having two parallel threads, on my 2 core machine, each of which calls
the named function once.  The total amount of computation in each case
should be the same, so you'd hope that the parallel case would finish
in about half the time, with about the same amount of total CPU time
being utilized.

That isn't what happens for the Java code with 'new Double' (called
NewDoubleTest), or for the Clojure code that has (inc 0.1) and calls
Double.valueOf(double) down in its implementation (called spin-
double1).  The parallel case only saves about 14% of the elapsed time
with 2 cores, and takes about 50% more total CPU time.

The more typical code that takes a single double value, initializes
it, and then adds 1 to it each time through the inner loop (Java
DoubleTest, Clojure spin-double2), is significantly faster than the
versions mentioned above.  Plus they exhibit the expected speedup from
using 2 cores instead of 1.

http://github.com/jafingerhut/clojure-benchmarks/blob/3e45bd8f6c3eba47f982a0f6083493a9f076d0e9/misc/RESULTS

I'm not sure how to determine why calling 'new Double' each time
through NewDoubleTest's inner loop causes 2 threads to perform not
much better than 1.  The best possible explanation I've heard is from
Nicolas Oury -- perhaps we are measuring the bandwidth from cache to
main memory, not raw computational ability of the processor cores.

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



Re: Clojure performance tests and clojure a little slower than Java

2009-08-09 Thread Andy Fingerhut

On Aug 8, 2:16 pm, John Harrop  wrote:
> On Sat, Aug 8, 2009 at 5:23 AM, Mark Engelberg 
> wrote:
>
>
>
> > On Fri, Aug 7, 2009 at 5:14 PM, John Harrop wrote:
> > >     (if (and (not (= 0 i)) (< (+ zr2 zi2 limit-square)))
>
> > I believe that (zero? i) is faster than (= 0 i).
>
> On primitive ints? Have you tested it?

I have, now, at your suggestion.  Here are the results on my iMac,
2.16 GHz Intel Core 2 Duo, Mac OS X 10.5.8, Java version:

% java -version
java version "1.6.0_13"
Java(TM) SE Runtime Environment (build 1.6.0_13-b03-211)
Java HotSpot(TM) 64-Bit Server VM (build 11.3-b02-83, mixed mode)

All are for the mandelbrot.clj-3.clj program here:

http://github.com/jafingerhut/clojure-benchmarks/blob/3e45bd8f6c3eba47f982a0f6083493a9f076d0e9/mandelbrot/mandelbrot.clj-3.clj

(By the way, these links should not be to blank pages, as you
experienced earlier.  I can follow them when reading in the Clojure
group web page, or in my email client.  Perhaps the software you are
using to read these messages is truncating the URLs, and thus they are
not going to the intended place?  Sorry they are so long, which tends
to cause these kinds of issues.)

I did two runs for each version, with the only difference between them
being replacing the (zero? i) expression in function 'dot' with a
different expression, as indicated below.  (zero? i) is a clear winner
in reducing run time.

If it makes a difference, I'm also using latest github clojure and
clojure-contrib as of about August 6, 2009.  Here is what the REPL
says about the definition of zero?

% clj
Clojure 1.1.0-alpha-SNAPSHOT
user=> (use 'clojure.contrib.repl-utils)
nil
user=> (source zero?)
(defn zero?
  "Returns true if num is zero, else false"
  {:tag Boolean
   :inline (fn [x] `(. clojure.lang.Numbers (isZero ~x)))}
  [x] (. clojure.lang.Numbers (isZero x)))



using (zero? i) in dot:

real2m38.378s
user2m40.601s
sys 0m1.875s

real2m30.614s
user2m33.081s
sys 0m1.853s

using (= 0 i) in dot:

real3m18.556s
user3m20.334s
sys 0m2.060s

real3m20.425s
user3m23.392s
sys 0m1.734s

using (== 0 i) in dot:

real3m21.701s
user3m24.043s
sys 0m1.982s

real3m22.441s
user3m24.420s
sys 0m2.013s

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



Re: Pure-functional N-body benchmark implementation

2009-08-10 Thread Andy Fingerhut

On Aug 10, 11:35 am, fft1976  wrote:
> On Aug 10, 4:46 am, Jarkko Oranen  wrote:
>
> > I'm not going to start optimising,
>
> Somebody'd better!
>
> You always hear this dogma that one should write "elegant" code first
> and optimize later, and when you do that, a few little changes can
> make Clojure as fast as Java.
>
> Here's your chance to show it :-)
>
> > but somehow I doubt that is
> > the bottleneck
>
> The locality of changes is what I doubt.

I've got a functional version in my clojure-benchmarks git repository,
too, and it is currently 138 times slower on my machine than the Java
version.  I haven't looked in detail at your code, but at a high level
it appears to be similar to yours in structure -- i.e., it doesn't try
to go overboard with float/double declarations, and uses only Clojure
data structures.  I haven't tried optimizing it yet, just because I've
done more optimizing with some of the other benchmarks first.

It would be nice to have a Clojure version under 10 times Java's run
time here, without resorting to Java data structures and methods.
There may be better motivational techniques than using the word
"dogma" and daring people to do better :-)

Then again, perhaps this may be an example where the best thing for
someone working on a real project is to take the inner loop code and
write it in Java, the way some people take inner loops in C progams
and hand-code them in assembly -- because they are in a situation
where it is worth the time to optimize.  I would point out that some
of these benchmark programs in Haskell, for example, are not pure
functional implementations, and people have gone to (what seems to me)
great effort to optimize the heck out of their programs in ways that
most Haskell programmers would probably find excessive.  Even some of
the C and C++ implementations seem to pull out __builtin_memmove calls
and explicitly using SSE macros in order to tweak out a few more
milliseconds of lower run time.

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



Re: Pure-functional N-body benchmark implementation

2009-08-10 Thread Andy Fingerhut

On Aug 10, 2:19 pm, Jonathan Smith  wrote:
> 1.) use something mutable
> 2.) unroll all the loops (mapping is a loop)
> 3.) try not to coerce between seq/vec/hash-map too much.
>
> in real world, stuff like the shootout is pretty useless, as generally
> you'd reach for a better algorithm rather than implementing the
> shackled, crippled, naive algorithms that the benchmark forces you to
> implement.
>
> (Not that they aren't useful to some extent, just that language
> productivity and how fast you can iterate your software design in the
> language is, IMO, a much better indicator of a good language than
> micro benchmarking).

I agree that they are useful to some extent.  In the real world, you
would use a better algorithm, but those better algorithms can be
implemented in any language, too.  As you say, a higher level language
that lets you iterate more quickly on multiple implementations of
different algorithms has advantages.  At the end of the day, there is
something in the language implementations that can enable faster
execution times than others.  A micro-benchmark can be useful to tell
you that if your application needs to do lots of double number
crunching, you definitely shouldn't be implementing it in Perl, for
example -- at least not that part of your application.

By the way, fft1976, this Clojure version of the n-body benchmark
takes about half the time of your code on my machine (for a shorter
test than the one for the benchmark web site -- I haven't compared yet
on the full length test since it takes about an hour for my version).

http://github.com/jafingerhut/clojure-benchmarks/blob/3e45bd8f6c3eba47f982a0f6083493a9f076d0e9/n-body/nbody.clj-5.clj

It doesn't use any mutable data structures, but it does use vectors,
has some double declarations, and avoids using map for operations on
pairs of 3d vectors, so it has some optimizations.

Using the new transient vectors recently added by Rich, and also
either using transient maps, or changing the implementation of planet
data to use vectors instead of the maps that I use, would probably
speed things up some more.  I also still have a fair number of uses of
map that would probably be faster with loop/recur.

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



Re: Pure-functional N-body benchmark implementation

2009-08-10 Thread Andy Fingerhut

OK, I've got a new Clojure program for the n-body benchmark, and it is
significantly faster than my previous one -- down from 138 x Java run
time, to 37 x Java run time.  Still room for improvement somewhere
there, I'm sure, including perhaps using Java arrays instead of
Clojure vectors.

http://github.com/jafingerhut/clojure-benchmarks/blob/2423c5ba7bcded349bc21cfa4204bb840fd75bfa/n-body/nbody.clj-6.clj

The main changes from the slower version are:

+ make separate vectors for each "attribute" of a body in motion, i.e.
a separate vector of positions, a vector of velocities, etc., instead
of using maps.
+ Use loop/recur almost everywhere it makes sense.  I still have a few
map calls in the function 'energy' and the functions it calls, and
maybe in the init code, but that is only done twice and once during
the whole execution, versus advance which is called 50,000,000 times
in the long version of the benchmark.
+ It uses the new transient/assoc!/conj!/persistent! functions for
Clojure vectors, so you need a pretty new copy of Clojure if you want
to run it yourself.

Updates summary of results is here:

http://github.com/jafingerhut/clojure-benchmarks/blob/14c5df3ee28d418a938de584f6675860043dd0f5/RESULTS

And, as usual, improvements to the performance of these Clojure
programs are welcome.

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



Re: Pure-functional N-body benchmark implementation

2009-08-10 Thread Andy Fingerhut

On Aug 10, 5:57 pm, Mark Engelberg  wrote:
> Andy,
>
> My understanding is that any double that gets stored in a vector or
> map is boxed, and therefore, the vast majority of your double
> conversions aren't really doing anything, because when you pull them
> out of the vector or map, they'll just be Double objects again.
>
> I believe that the biggest reason for the performance difference
> between Clojure and Java on this benchmark is that if you use a
> Clojure data structure (e.g., a map) to represent each "body" object,
> you get a lot of boxing and unboxing of the doubles.
>
> So I hypothesize that the biggest bang for the buck is to find a way
> in Clojure to create body objects with primitive double fields.  Can
> the new new do that?  If not, your best bet may be to represent a body
> object as a Java array of several doubles, rather than using a Clojure
> map.  The first double could represent the mass, the second could
> represent vx, the second vy, and so on.  Make macros for the accessors
> that extract these values using aget.
>
> It's speculation on my part, but I think this will get you much closer
> to Java speed than your current approach.

I've tried an approach like you suggest, using mutable Java arrays of
doubles, macros using aget / aset-double for reading and writing these
arrays, and loop/recur everywhere iteration is needed in the inner
loop.  It is here:

http://github.com/jafingerhut/clojure-benchmarks/blob/173e68a52ca2e180f9d5f3ac4c81a737358d1491/n-body/nbody.clj-7.clj

I was surprised to find that it is significantly slower (about 3x)
than my best Clojure one so far, which uses the new transients, and
vectors of doubles to store the state of the bodies -- the one I
posted earlier today.

http://github.com/jafingerhut/clojure-benchmarks/blob/173e68a52ca2e180f9d5f3ac4c81a737358d1491/n-body/nbody.clj-6.clj

The updated summary of results is here:

http://github.com/jafingerhut/clojure-benchmarks/blob/173e68a52ca2e180f9d5f3ac4c81a737358d1491/RESULTS

I suspect I'm doing something wrong in my mutable Java array
implementation, but I don't see what it could be.

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



Re: Pure-functional N-body benchmark implementation

2009-08-10 Thread Andy Fingerhut

On Aug 10, 11:33 pm, Mark Engelberg  wrote:
> On Mon, Aug 10, 2009 at 11:15 PM, Andy
>
> Fingerhut wrote:
> > I suspect I'm doing something wrong in my mutable Java array
> > implementation, but I don't see what it could be.
>
> There still seems to be a lot of boxing and unboxing going on.  For example, 
> in:
> (let [[momx momy momz] (offset-momentum bodies)
> the call to offset-momentum returns a vector of the three doubles, so
> they would be boxed, so momx momy momz are not primitives.

That code is only run once during initialization, then never again.
It is well under 0.1% of the entire run time of the long benchmark.

The bulk of the computation is this call tree, where advance! is
called 50,000,000 times sequentially in the long benchmark:

advance!
bodies-update-velocities!
bodies-update-positions!

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



Re: Pure-functional N-body benchmark implementation

2009-08-11 Thread Andy Fingerhut

On Aug 10, 11:50 pm, Christophe Grand  wrote:
> Hi Andy,
>
> On Tue, Aug 11, 2009 at 8:15 AM, Andy Fingerhut <
>
> andy_finger...@alum.wustl.edu> wrote:
> > I've tried an approach like you suggest, using mutable Java arrays of
> > doubles, macros using aget / aset-double for reading and writing these
> > arrays, and loop/recur everywhere iteration is needed in the inner
> > loop.  It is here:
>
> aget-* and aset-* are slow, just use aget and aset with type hints.
>
> Christophe

Wow, you ain't kiddin.  I changed about 10 lines from my last version,
to avoid using aset-double, using aset and type hints until the
reflection warnings went away, and it sped up by a factor of 10.  I'm
leaving the previous version's source and results there just so I can
have a future reference to point to at the difference it makes.  New
results here:

http://github.com/jafingerhut/clojure-benchmarks/blob/9dc56d8ff53f0b8d363f213317587432bd8793de/RESULTS

Still almost 11 times slower than the Java version, but a lot more
respectable than my earlier attempts.

Should there be a similar warning like *warn-on-reflection* that tells
you to avoid using aset-* if you want better performance?  Or at least
put a loud warning in the doc strings for those functions about their
poor performance?  Or can they just be removed?

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



Re: Transient Data Structures

2009-08-11 Thread Andy Fingerhut

On Aug 10, 11:15 am, Christophe Grand  wrote:
> Hi Andy,
>
> On Thu, Aug 6, 2009 at 7:40 PM, Andy Fingerhut <
>
>
>
> andy_finger...@alum.wustl.edu> wrote:
> > Thank you, Christophe!  I've been wanting to try those out.
>
> > I made changes to 3 lines of my Clojure program for the k-nucleotide
> > benchmark, which spends most of its time in a function tally-dna-subs-
> > with-len that creates a hash map counting the number of times that
> > each of a bunch of length k strings occurs in a long string.  Source
> > here, if you're curious:
>
> >http://github.com/jafingerhut/clojure-benchmarks/blob/38e1f592ca3befe...
>
> > It went from about 19 minutes down to about 12 minutes.  Excellent
> > improvement for a small change to the code.  That brings it down to
> > about 7.7 times the run time of the Java version from the language
> > shootout web site.
>
> Could you try my "leafless" 
> branch;http://github.com/cgrand/clojure/tree/leafless?
>
> Thanks,
>
> Christophe

And Christophe's latest improvements to transient support for maps
improves the running time of my k-nucleotide benchmark program from
about 12 minutes to about 9.5 minutes.  Very nice stuff.  It isn't in
Rich's clojure repository yet, but you can get the changes from
Christophe's github repo if you want to try it out.

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



Re: Pure-functional N-body benchmark implementation

2009-08-11 Thread Andy Fingerhut

In case it matters to anyone, my intent in creating these Clojure
programs to compare their speed to others isn't to try to rip into
Clojure, or start arguments.  It is for me to get my feet wet with
Clojure, and perhaps produce some examples that others can learn from
on what performs well in Clojure and what doesn't.  So far, it has
even had the unexpected benefit of providing a ready-made test for
Christophe Grand to do a quick test of some improvements to his
implement of transients for Clojure maps.  Cool beans.

Also, while it may appear I do benchmarks for a living, I don't :-)
I'd personally like to know before investing more time with Clojure
what kind of performance I can attain with it.  Most of my commercial
software development to date has been in assembly and C, and the
expressiveness of Lisp is a breath of fresh air that helps me remember
why I love programming.  Clojure's concurrency features, and keeping
around the power of Lisp macros, are a huge pull for me.

But there are those times that you want performance, and I'm curious
how much I can get out of Clojure code, vs. implementing certain inner
loops in Java, C, or what-have-you.  Just because some part of your
code might lead you, for desire of better performance, to implement it
by hand in Java or C doesn't deter me from Clojure at all -- but I'd
like to know how likely that is.

OK, with that said, I've now got the n-body benchmark within 3.2 times
Java's run time on the same problem.  The only change from my previous
version that sped things up was to replace 3-operand arithmetic
operations with 2-operand operations.  Currently, this enables Clojure
to use primitive ops, instead of something slower.

Updated results here:

http://github.com/jafingerhut/clojure-benchmarks/blob/0f7fdd358086cb95c898d7c2656215408a8d0689/RESULTS

As always, suggestions or improved versions are welcome.

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



Re: Can Clojure be as fast as Java?

2009-08-11 Thread Andy Fingerhut

On Aug 11, 4:27 pm, Stuart Halloway  wrote:
> If I am reading the README correctly, clj-8 is 10.8 times slower than  
> Java, but clj-9 does better: 3.2 times slower.
>
> Stu

You are reading that correctly.  My clj-9 wasn't created until after
fft1976's message starting this thread.

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



Re: Pure-functional N-body benchmark implementation

2009-08-11 Thread Andy Fingerhut

On Aug 11, 2:36 pm, Aaron Cohen  wrote:
> At that point is it possible you're just paying the price of
> PersistentVector for the "bodies" vector?  Does it improve much if you
> change bodies to an array?

About 7% faster changing bodies to a Java array of java.lang.Object's,
each of which happens to be a Java array of primitive doubles, as
before.  Now about 3.0 x Java run time.

http://github.com/jafingerhut/clojure-benchmarks/blob/43ed2f42e6c1485541532e51eacc66488949c658/RESULTS

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



Clojure, Java JIT, and inlining

2009-08-12 Thread Andy Fingerhut

My apologies for the noise if this is well known in the Clojure
community, but I'll ask anyway.

One of the tweaks to my Clojure benchmarks that people have suggested
for improving performance, and that does help, is changing some
function definitions to macros.  This is in effect inlining those
functions at the source level, so the Clojure compiler has a shot at
it.

Is there some reason that the Java JIT is not doing this, with the
original code using defn, as fast as it works when using defmacro?

Perhaps some JITs do inlining, but cannot do it as well as a defn ->
defmacro change permits?

Is it because of some kind of function call/return overhead that the
JIT cannot eliminate?

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



Re: Newbie with problems building clojure-contrib

2009-08-12 Thread Andy Fingerhut

I've got a Mac and I've set it up to run jvm 1.6.0 instead of 1.5.0,
but I think I've done it with 1.5.0 before, too.  You should be fine
there.  Also I have ant version 1.7.1, but again, probably not a show
stopper difference.

I put my clojure-contrib in a directory "beside" my clojure directory,
instead of within it, and I gave a full absolute path name (e.g. /
Users/andy/clojure/clojure-1.0.0.jar) instead of a relative path name
when I built clojure-contrib.  I'd recommend trying that and see if it
makes any difference for you.

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



Re: Newbie with problems building clojure-contrib

2009-08-12 Thread Andy Fingerhut

Oh, one more thing.  If you have latest git clojure-contrib, I'd
recommend trying it with latest git clojure, too.  Latest clojure-
contrib might not work with clojure 1.0.0.

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



Can dosync transaction result computation be parallelized over multiple threads?

2009-08-13 Thread Andy Fingerhut

I know that if you have a dosync call in some function executed by a
thread, and then that function calls other functions (which might have
their own dosyncs, which get bundled together with the original
transaction), then everything is fine.  It seems common that all of
that work would be done sequentially, in a single thread.

But what if that thread that started the dosync did a pmap call, say,
and the function called on each of the elements of the collection
accessed Refs, and perhaps computed new values for some of them, and
those were not the same Refs that the original thread was accessing.
Do all of those get bundled together with the original transaction,
too?

If so, did it require anything special in the implementation to make
that work?

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



Transcript of Rich's "Clojure for Lispers" talk uploaded

2009-08-13 Thread Andy Fingerhut

This is the same Clojure for Lispers talk with audio, and video of
slides, available on clojure.blip.tv, among others, from the September
2008 Boston Lisp meeting.

It has been uploaded to the files section of the group with this name:

clojure-for-lispers-transcript.txt

I've added a very few references to books and articles that Rich
mentions during the talk, but other than that, it is just the text of
what he says, and a fraction of what the audience asks (some of them
are much more difficult to understand in the audio).

People are welcome to put this in some more easily accessible place,
if you know how and have the access to it.  For example, if a link to
it could be put on clojure.blip.tv, that might be cool.

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



Memory leak in vec (and maybe persistent!)?

2009-08-14 Thread Andy Fingerhut

If there is a better place to report things like this, let me know.

I've done some looking at how much memory various kinds of Clojure
data structures use, and come across some behavior that I think might
be a memory leak, in the sense that perhaps a reference to a
java.util.concurrent.atomic.AtomicReference object is being held onto
after a call to vec, even though it isn't needed any more.

It might still be needed for reasons that I'm not aware of.  I don't
know the implementation well enough to say.

Steps to reproduce the behavior (should work on at least OS X and
Linux -- tested on OS X with java 1.6.0_13, and latest clojure and
clojure-contrib from github):

Get these two files:

clj-run.sh
memuse.clj

You can either pull my whole clojure-benchmarks git repo (only a few
megabytes), or just get those two files here:

http://github.com/jafingerhut/clojure-benchmarks/tree/450da3b949550087e6b97333ba065c1fc875564a/memuse

Edit clj-run.sh to set the location of your Clojure jar files.  Then
run:

./clj-run.sh 50 5 1

When it prints "Done.  Going to sleep now.  Good night." then either
put that process in the background, or in a separate shell window,
find out the process ID of the java process created above, and run:

jmap -histo:live   > jmap.txt

My belief is that the ":live" part means that only live objects with
references to them, that cannot be garbage collected, will be reported
in the output.  I've confirmed on my system that if I use "-histo"
instead of "histo:live" that I get a lot more objects reported, which
are presumably garbage.

When I did this, one of the first several lines of output included a
little more than 1 AtomicReference object per calls to vec.

 num #instances #bytes  class name
--
   6:500022   12000528
java.util.concurrent.atomic.AtomicReference

I think that this AtomicReference object is fairly new in the Clojure
Java source code, with the addition of transients.  It used to be an
AtomicBoolean before that.

Would it be correct to nullify the reference to the persistent object
returned by a call to persistent! on a transient object?

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



Re: Memory leak in vec (and maybe persistent!)?

2009-08-15 Thread Andy Fingerhut

On Aug 15, 5:44 am, Christophe Grand  wrote:
> I wouldn't call this a memory leak: vectors have a bigger memory overhead
> than before (additional PersistentVector$Node and AtomicReference).
>
> On Sat, Aug 15, 2009 at 2:13 AM, Andy Fingerhut <
>
> andy_finger...@alum.wustl.edu> wrote:
> > When I did this, one of the first several lines of output included a
> > little more than 1 AtomicReference object per calls to vec.
>
> >  num     #instances         #bytes  class name
> > --
> >   6:        500022       12000528
> > java.util.concurrent.atomic.AtomicReference
>
> > Would it be correct to nullify the reference to the persistent object
> > returned by a call to persistent! on a transient object?
>
> For a single persistent object (built with transients) there are potentially
> several references to the same AtomicReference. I think that you can't
> nullify all references and have persistent! still be O(1).
>
> One AtomicRefrence is created for each pair of transient/persistent! calls
> and, in worst case, you can't have more than one AtomicReference per
> PersistentVector$Node. So, for a given vector it won't grow indefinitely.
>
> OTH,
>
> Christophe

Understood.

Not to say this ought to be done, but would it be possible to have no
'edit' field *at all* for persistent data structures (not even a null
reference), and only an edit field at the "root" data structure of a
transient (none of the children would have one, only the root), and
preserve O(1) transient/persistent! calls?

Even if that is possible, I guess the down side is two versions of all
the data structures for transients, one with edit and one without.

But even if edit remains in all of them, I'm wondering whether it
could be maintained that only the root node has a non-null edit field,
while that data structure is transient.

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



Re: How to have a fast access to a java array of non-primitives?

2009-08-15 Thread Andy Fingerhut



On Aug 15, 9:45 am, Nicolas Oury  wrote:
> Thank you very much for your answers.
> The syntax was difficult to guess.
> Is there a general rule for forming the internal name of types?
>
> It seems after a few tests that is is slightly slower (15-20%) than
> making a final static function:
>
> static final A arrayAccess (A [] array, int i)
> { return array[i]}
>
> and calling it.
>
> and similar in speed to:
> static final Object arrayAccess (Object [] array, int i)
> { return array[i]}
>
> Am I wrong if I deduce that this is not specialized on the type?
>
> I use it in  a tight loop that does not much inside each loop, so the
> type checks do not seem to be negligible.
>
> I guess that's the price of trying to write solutions to not very
> interesting micro-benchmark :).
>
> Best regards,
>
> Nicolas.
>
> On Sat, 2009-08-15 at 12:06 -0400, David Nolen wrote:
> > You need to specify the array type. For example the following produces
> > a primitive array of n javax.vecmath.Vector2d elements.
>
> > (defn #^"[Ljavax.vecmath.Vector2d;" point-array [n]
> >   (make-array javax.vecmath.Vector2d n))
>
> > It works. If you want to see it in action take a look at:
>
> >http://github.com/swannodette/convex-hull/tree/master
>
> > On Sat, Aug 15, 2009 at 11:41 AM, Nicolas Oury
> >  wrote:
>
> >         Dear all,
>
> >         I try to write a program where I access a java array of non
> >          primitive
> >         and realize aget is very slow.
> >         (6x slower than the same program with clojure vectors instead
> >         of java
> >         arrays access)
>
> >         I tried a few combinations of type hints but can't manage to
> >         prevent mty
> >         program to spend most of its time there:
>
> >         99.4%     0  +  8804    java.lang.reflect.Array.get
>
> >         Does anyone know how to speed that up?
> >         Is it written somewhere in the java interop documentation?
>
> >         Best,
>
> >         Nicolas.

I don't know if this works for all classes, but you can try this:

user> (class (make-array java.lang.Object 5))
[Ljava.lang.Object;

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



Re: Memory leak in vec (and maybe persistent!)?

2009-08-18 Thread Andy Fingerhut

On Aug 17, 3:51 am, Christophe Grand  wrote:
> On Sat, Aug 15, 2009 at 4:23 PM, Andy Fingerhut <
>
> andy_finger...@alum.wustl.edu> wrote:
> > Not to say this ought to be done, but would it be possible to have no
> > 'edit' field *at all* for persistent data structures (not even a null
> > reference), and only an edit field at the "root" data structure of a
> > transient (none of the children would have one, only the root), and
> > preserve O(1) transient/persistent! calls?
>
> The problem is when you have several calls to transient/persistent! You have
> to be able to tell transient nodes owned by the current transient processing
> from older transient nodes left in place by previous calls to persistent!.
> (and these transient nodes can be shared!)
> One could have a set of nodes owned by the current transient but it would
> incur some bookkeeping to not retain a reference to a reclaimable node.
> I don't know if there's another way to do that.

But if there is only a single non-null edit reference in the "root
node", then the non-root nodes don't really need a reference to the
thread that is currently mutating the data structure, right?

And after a call to peristent!, a different thread could later call
transient on it, and want to make its own modified version.  So any
non-null edit references anywhere in the persistent data structure are
useless, aren't they?

>
> But even if edit remains in all of them, I'm wondering whether it
>
> > could be maintained that only the root node has a non-null edit field,
> > while that data structure is transient.
>
> Why do you focus on these AtomicReferences? If you contrast pre-transient
> vectors and actual vectors you'll see that the overhead due to instance of
> PersistentVector$Node is far more important.
>
> Christophe

I only focus my questions on AtomicReferences because I noticed them.
I haven't yet taken the time to read through all the source code
related to the implementation of transient data structures.

It just seems to me that a persistent data structure doesn't _need_ a
reference to the thread that created it.  It is now immutable, and it
and all of its "sub-parts" always will be, until and unless they are
deallocated by garbage collection.

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



Re: Memory leak in vec (and maybe persistent!)?

2009-08-19 Thread Andy Fingerhut



On Aug 19, 2:38 am, Christophe Grand  wrote:
> Imagine a persistent data structure S1 with a root node A and two child
> nodes B and C.
> On this data structure you call transient, make some updates and call
> persistent! which yields an updated persistent data structure S2 with the
> root node A' and child nodes B and C' (B isn't updated and is thus shared
> with S1). A' and C' are "transiently created" nodes, B is a "regular" node.
> Now you call transient again on S2. How can one know that A' and C' must be
> cloned before modifying them in place? If one can't tell and modify B' the
> modification is propagated to S2: S2 is no longer persistent :-(
> That's why each node must carry an identifier: to be able to know if a node
> can be updated in place or must be cloned. Actually, once persistent!
> called, this identifier is a nulled AtomicReference. (Granted a simple
> Object would save us a handful of bytes.)
>
> The alternative impls I can think of (a set of owned nodes or performing a
> cleanup on persistent!) would trade the memory overhead for a runtime one.
>
> Christophe

OK, I think that explanation broke through the fog in my brain.  I had
been mistakenly thinking that there ought to be a straightforward way
to keep some kind of reference to the mutating thread of a transient
at the root only, forgetting that while it is transient we need a way
to distinguish which nodes we are allowed to mutate in place, and
which we are not.

I also do not see a way that we can do that, and still have an O(1)
persistent! call.

It does seem we could have a persistent! call that is O(# of
temporarily mutable nodes created while the data structure was
transient), by walking the data structure from the root node and
stopping whenever we hit a persistent node that hasn't been mutated,
but in general that could be all of the nodes.

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



Dynamic enforcement of no side effects in transactions?

2009-08-19 Thread Andy Fingerhut

During the Clojure for Lispers talk in Boston (see clojure.blip.tv if
you want to watch it), someone asked Rich about enforcing the no-side-
effect rule in transactions.  Rich answered that he couldn't do that,
because "I'm a dynamic language."  (audience got a chuckle out of that
way of putting it :-)

I've been thinking a bit about ways to automatically check for side
effects in transactions, for people that want to catch them and
eliminate them.  I know that they can be found by hand via various
types of testing/debugging, but I'm curious how we might be able to do
better.

I was toying with a code walker that tried to check for whether some
code had side effects or not, and now I see more clearly several of
the difficulties of trying to statically check for such things.  There
are easy cases of determining that a function is pure, or has side
effects, but there are lots of cases where it is tricky (and I'm sure
in general undecidable, in the complexity theoretic sense of the
word).

Someone asked Rich about dynamic enforcement during the talk, and he
answered that it might be possible.  Of course, this won't guarantee
that you've caught all possible side effects in transactions without
"sufficient testing", but at least it will quickly catch them if you
try to do one.

I know there is an io! macro meant to flag an error if it is wrapped
around code that you try to run during a transaction.  That's cool.
But currently almost nothing in the core libraries use it.  It would
certainly have some performance impact if all I/O routines used it.

A couple of other ideas, although I don't know whether they have holes
in them, or what their performance impact might be.

(1) At the time of entering a transaction, dynamically bind all
functions known to possibly cause side effects to a version that
throws an exception.

One down side is coming up with, and maintaining across changes to
Clojure, that list of functions.  Another is that such dynamic
bindings do not propagate from thread to thread, so a different thread
could call one of those side-effecting functions without causing any
problems.  Also, I'm not sure, but it might be possible for a "non
cooperative" function to restore the original side-effecting version
of one of those rebound functions.

(2) Use Java sandboxing features to try to catch side effects.

I suspect it might be possible to configure sandboxing to catch
attempted I/O, but I'd be surprised if it can catch all kinds of side
effects.  I was hoping someone on the group might have more knowledge
of Java sandboxing features and could comment.  I also don't know what
the performance impact of creating such a sandbox might be.


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



Re: Tight loop performance

2009-09-06 Thread Andy Fingerhut

Is there any reason to keep aset-* functions around in Clojure?  I
guess backwards compatibility?

It definitely seems worth flagging them when *warn-on-reflection* is
true, in a similar way to other warnings it enables.  Perhaps that
might be overloading the meaning of *warn-on-reflection*, but I think
there is definitely value in having _one_ flag you can turn on that
gives you as many kinds of performance warnings as we know how to
give.

Andy

On Sep 6, 7:49 am, Nicolas Oury  wrote:
> Hello,
>
> >         (aset-byte dst dst-offset (byte sample))
>
> Most of the time, aset is faster than aset-TYPE. Especially when, like here, 
> types are known.
> If you profile your code, you should see most of the time is in 
> Reflect.Array.set or something similar, and that should disappear
> if you want your code to perform well.
>
> Best,
>
> Nicolas.
>
> >         (aset-byte dst (inc dst-offset) (byte (bit-shift-right sample
> > 8
> >       (recur (inc src-offset) (unchecked-add 2 dst-offset)
>
> > Adding type coercions helped a bit but it's still too slow. In Java
> > I wrote this method:
>
> >  public static void shortsToBytes(short[] src, byte[] dst, int len)
> >  {
> >    int idx = 0;
> >    short s;
>
> >    while (len-- > 0) {
> >      s = src[idx];
> >      dst[idx*2] = (byte)s;
> >      dst[idx*2+1] = (byte)(s>>>8);
> >      idx++;
> >    }
> >  }
>
> > Then I timed them under both Clojure 1.0 and 1.1.0-SNAPSHOT and got
> > similar results.
>
> > [...]
> > (doseq [n (range 5)]
> >  (time (shorts-to-bytes a b 512000))
> >  (time (ArrayConverter/shortsToBytes a b 512000))
> >  (println))
>
> > "Elapsed time: 516.527512 msecs"
> > "Elapsed time: 32.316904 msecs"
>
> > "Elapsed time: 472.034037 msecs"
> > "Elapsed time: 5.096593 msecs"
>
> > "Elapsed time: 437.755411 msecs"
> > "Elapsed time: 4.10872 msecs"
>
> > "Elapsed time: 535.864767 msecs"
> > "Elapsed time: 3.106442 msecs"
>
> > "Elapsed time: 880.127444 msecs"
> > "Elapsed time: 3.124339 msecs"
>
> > So Java outperforms Clojure by two orders of magnitude.
>
> > Is there anything wrong with my code? I've been fine-tuning this code
> > for a couple of days now, to no avail.
>
> > Thank you and keep up!
> > Matt.
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: clojure-mode survey

2009-09-11 Thread Andy Kish

Very much agreed on the need for a default launcher/script. This is an
annoying obstacle to adoption in my mind. Most of the "Getting Started
with Clojure" tutorials show you how to launch clojure with java and
the jar, and then provide a shell script wrapper to simplify things.

On Sep 10, 6:23 am, Rick Moynihan  wrote:
> As I'm sure you and many others know, this problem exists in the Java
> community also...  A few years ago I found a solution in Apache
> Commons Launcher:
>
> http://commons.apache.org/launcher/

Another cool launcher I found is Hashdot:
http://hashdot.sourceforge.net/

It's simple 'n approachable and it comes with sane default settings
for the JVM for scripting tasks! The project also looks to be more
active than the Commons Launcher. It's missing a bit of spit and
polish in terms of distribution but that can be fixed. There isn't a
debian package and depending on your setup, you'll probably have to
edit the Makefile to install from source.

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



Re: Ann Arbor Clojure Meetup?

2009-09-11 Thread Andy Kish

I live in Ann Arbor and I'd love to meet people doing clojure stuff.
Lance, what ruby meetings have the folks interested in functional
languages?

SRT solutions hosts a bunch of UGs [1], but I haven't been to any of
them yet. If there's not a better place to meet, I'll show up at the
AAJUG on the 22nd in an old beat up Astros ballcap. Introduce yourself
if you see me. :-)

Andy.

[1] 
http://www.google.com/calendar/htmlembed?src=v2433p4md2226qtd3ja1annifc%40group.calendar.google.com&mode=AGENDA

On Sep 8, 1:07 am, Lance Carlson  wrote:
> Hi Clint,
>
> I attend the Ruby meetings locally and we're all interested in
> functional languages.. we used to do an erlang/functional languages
> group. I'd also be interested in getting something like this together.
>
> -Lance
>
>
>
> On Mon, Sep 7, 2009 at 9:32 PM, newsomc wrote:
>
> > Is anyone aware of a Clojure meetup in Ann Arbor, MI? I used to attend
> > a very small one in Brooklyn and Im missing it. If anyone is
> > interested in starting something that could be cool too!
>
> > Cheers,
>
> > Clint

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



Re: clojure-mode survey

2009-09-11 Thread Andy Kish

Phil thank you for your work on ESK and clojure-mode. When I started
doing more lisp stuff, I knew that I had to move from textmate to
emacs. ESK made switching a lot less daunting.

I use clojure-install (worked like a charm on debian and os x 10.6)
and clojure-update and I find them useful. They make setting up an
environment more stupid-proof, and I need that sort of thing! Until
there's a standardized way to launch clojure, clojure-project is nice
as well.

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



Re: Modeling Data Associations in Clojure?

2009-09-14 Thread Andy Kish

Hi Brenton,

Nested maps are a good way to start, but they're pretty low level as
you want to do more complicated things. If you're talking about data
associations, the relational model is higher level and it's really
worth modeling your data in that way.

Relational data manipulation doesn't require a sql database. If you
want to use an in memory data representation, clojure has a couple of
options. The clojure.set namespace [1] has some useful functions
operating on sets of maps, in a relational way. join, select, and
project will get you pretty far.

A more structured and powerful way of doing things is
clojure.contrib.datalog [2]. I haven't had a chance to play with this
(yet!), but it looks very cool. It's a functional approach and it's
more well integrated with the language than something generating sql.

If your app really does call for connection to an external db, then
there's no reason not to go with clj-record. You wouldn't be the first
person to make a SQL db backed web app. :) Using a database through
clojure feels a lot more natural than via an ORM.

I'm doing a small web app with compojure to familiarize myself with
clojure right now, so report back to the mailing list if something
works well for ya! I'm not at the point where I need a db, but if I do
I think I'll end up trying to use datalog.

Andy Kish.

[1] http://clojure.org/api#toc654
[2] http://richhickey.github.com/clojure-contrib/doc/datalog.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
-~--~~~~--~~--~--~---



Re: type checking/inference?

2009-09-16 Thread Andy Kish

Cool! Thanks for the heads up. Most of experience with functional
languages has been with Haskell up 'til now, so I've been itching for
a type system too.

Qi always looked interesting but the goofy website and license drove
me away. Maybe I'll have to take another look...

Andy Kish.

On Sep 16, 10:41 pm, Fogus  wrote:
> I'm pretty sure that the next generation Qi implementation is
> targetting Clojure.
>
> http://github.com/snorgers/Shen
>
> -m

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



doc-tests for clojure--please give my library a try!

2009-09-16 Thread Andy Kish

Hi all,

I've been playing with clojure for a few weeks now, and it's a good
time. One deficiency I've noticed is that the clojure api and
clojure.contrib documentation is really lacking in simple examples. I
do python for my day job and I really like what doctests have done for
the python documentation culture. There are simple examples of a
function's use in its documentation, and those examples are verified
to be correct.

I threw together a clojure namespace to do the same:
http://github.com/Kobold/clj-doc-test

Right now it is very simplistic, but it works. I've tried to make it
integrate as seamlessly as possible by writing it on top of
clojure.test. If this seems like a good idea, I'd eventually like to
go through clojure.contrib and add doc-tests to those. I'm happy to do
it myself to improve clojure's documentation.

Feedback on both the idea of doc-testing and my code are very welcome!
The introduction I wrote to doc-test is below.

Thanks!
Andy Kish.

-

doc-test is a Clojure namespace that provides Python-like doctests
[1].

WHY DOC-TEST?
-

Examples are very useful in documentation and help to clarify the
meaning of descriptions. Take #'clojure.set/join:

"When passed 2 rels, returns the rel corresponding to the natural
join. When passed an additional keymap, joins on the corresponding
keys."

Que? A simple example is much more clear for someone reading the docs
for the first time:

(def languages
 #{{:name "C"   :type "procedural"}
   {:name "Clojure" :type "functional"}
   {:name "Haskell" :type "functional"}})
(def fun-level
 #{{:type "procedural" :funness "meh"}
   {:type "functional" :funness "awesome"}})

=> (clojure.set/join languages fun-level)
#{{:name "Haskell", :type "functional", :funness "awesome"}
  {:name "Clojure", :type "functional", :funness "awesome"}
  {:name "C", :type "procedural", :funness "meh"}}

Awesome. The only problem is that sometimes documentation and actual
code fall out of sync with each other. Doc-tests provide a way to
assure that doesn't happen. The examples in the documentation are
tested with the rest of the code!

HOW TO DOC-TEST
---

Here's an example function with some doc-tests:

(defn adder
  "A simple function to test the doctest macro with.

  => ((adder 1) 2)
  4 ; incorrect!
  => ((adder 4) 5)
  9"
  [n1]
  (fn [n2] (+ n1 n2)))

To generate the tests from #'adder's doc-string:

 (doc-test adder)

Put this wherever you've put the rest of your
#'clojure.test/deftests. When the above test is run this error occurs:

FAIL in (adder__doc-test__88) (doc_test_tests.clj:19)
expected: (clojure.core/= ((adder 1) 2) (quote 4))
  actual: (not (clojure.core/= 3 4))

Doc-test makes efforts to make test failures easier to debug. Because
your documentation is turned into standard clojure.test declarations,
we see the failure display in the same way. The test name is the
symbol's name along with "__doc-test__". The expected and actual
statements are also exactly what was in the doc-string.

[1] http://docs.python.org/library/doctest.html
[2] http://clojure.org/API#toc662
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: Second Lisp to Learn

2009-12-20 Thread Andy Fingerhut
I don't have broad experience with various Lisps, but I have also done
some programming in Scheme and Common Lisp.

You can program in a functional style in both, or in an imperative
style in both.  In Scheme, functional style is a bit more idiomatic,
so you will find more examples of functional style code written in
Scheme than you will in Common Lisp, on average.  That makes it a bit
closer in idiomatic style to Clojure than Common Lisp is.

I can't speak to the awesomeness of the Scheme community, but they do
have lots of on line documentation, and in the last 5-8 years or so
they have taken the small "core" of scheme defined by the revised^5
report on Scheme (R5RS) and also version 6, and extended it with
"SRFIs", Scheme Requests For Implementation.  These are often
libraries of useful functionality.

http://srfi.schemers.org

There are many different Scheme implementations.  PLT Scheme might be
a good one to start with, in terms of the amount of example code and
documentation that comes with it.  I believe it implements many of the
SRFIs, as well as extensions of its own.

Andy


On Dec 20, 12:31 pm, Sean Devlin  wrote:
> Hi everyone,
> After hacking Clojure for a while, I've come to the conclusion that
> studying a second Lisp would help.  So, what do the people here
> think?  What is a good Lisp to study?  Are there particular dialects &
> distributions that are interesting? The things that are important to
> me are:
>
> A community at least 1/10th as awesome as this one.  Seriously.
> Libs in Lisp - I want to see if there are ideas worth stealing.
> Available documentation - I have to be able to read about it, and
> teach myself online.
>
> Thanks,
> Sean

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


Re: performance improvments for the following code

2010-01-27 Thread Andy Fingerhut
On Jan 27, 8:21 pm, Scott  wrote:
> wondering if I can please get some advice on how to improve the
> performance of this piece of code
>
> (defn select-n-tournament
>   [popu fit-fn n]
>   (let [k 7]
>     (take n (repeatedly #(first (sort-by fit-fn > (take k (shuffle
> popu))
>   )
> )

I don't know about using map, but here is a function inspired by one
called 'most' in Paul Graham's On Lisp.  You could use (most fit-fn
(take k (shuffle popu))) in place of your (first ...) subexpression
above, and it would avoid sorting elements that you would otherwise
simply be throwing away anyway.

(defn most [fit-fn c]
  "Return the element e of collection c that has the largest numerical
value of (fit-fn e)."
  (let [c (seq c)]
(when c
  (loop [winner (first c)
 winner-fitness (fit-fn winner)
 c (rest c)]
(if (seq c)
  (let [e (first c)
e-fitness (fit-fn e)]
(if (> e-fitness winner-fitness)
  (recur e e-fitness (rest c))
  (recur winner winner-fitness (rest c
  winner)

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


Re: ClassNotfound Exception while loading JAR files in Clojure 1.2

2013-05-22 Thread Andy Fingerhut
I'll be more blunt than Sean was :-)

Is there a reason why you *must* use Clojure 1.2?  If so, what is it?

If there isn't such a reason, you will likely get much better support from
other Clojure users if you use Clojure 1.4 or 1.5.1 (1.5.1 was released a
couple of months ago, so many are still using Clojure 1.4, and relatively
few are using 1.3).

Andy


On Wed, May 22, 2013 at 8:20 AM,  wrote:

> Hi Sean,
>
>Thanks for your reply. I use Clojure.Jar version 1.2.0 and the
> contrib.jar is also the same version.
>
>Copied below is the stack trace of the Error:
>
> Caused by: java.lang.NoClassDefFoundError:
> com/gargoylesoftware/htmlunit/html/BaseFrameElement (agent.clj:1)
> at clojure.lang.Compiler.eval(Compiler.java:5440)
> at clojure.lang.Compiler.eval(Compiler.java:5415)
> at clojure.lang.Compiler.load(Compiler.java:5857)
> at clojure.lang.RT.loadResourceScript(RT.java:340)
> at clojure.lang.RT.loadResourceScript(RT.java:331)
> at clojure.lang.RT.load(RT.java:409)
> at clojure.lang.RT.load(RT.java:381)
> at clojure.core$load$fn__4511.invoke(core.clj:4905)
> at clojure.core$load.doInvoke(core.clj:4904)
> at clojure.lang.RestFn.invoke(RestFn.java:409)
> at clojure.core$load_one.invoke(core.clj:4729)
> at clojure.core$load_lib.doInvoke(core.clj:4766)
> at clojure.lang.RestFn.applyTo(RestFn.java:143)
> at clojure.core$apply.invoke(core.clj:542)
> at clojure.core$load_libs.doInvoke(core.clj:4800)
> at clojure.lang.RestFn.applyTo(RestFn.java:138)
> at clojure.core$apply.invoke(core.clj:544)
> at clojure.core$use.doInvoke(core.clj:4880)
> at clojure.lang.RestFn.invoke(RestFn.java:458)
> at
> nlplabs.webfetch.lib.dgeneral$eval780$loading__4410__auto781.invoke(dgeneral.clj:1)
> at nlplabs.webfetch.lib.dgeneral$eval780.invoke(dgeneral.clj:1)
> at clojure.lang.Compiler.eval(Compiler.java:5424)
> at clojure.lang.Compiler.eval(Compiler.java:5415)
> at clojure.lang.Compiler.load(Compiler.java:5857)
> at clojure.lang.RT.loadResourceScript(RT.java:340)
> at clojure.lang.RT.loadResourceScript(RT.java:331)
> at clojure.lang.RT.load(RT.java:409)
> at clojure.lang.RT.load(RT.java:381)
> at clojure.core$load$fn__4511.invoke(core.clj:4905)
> at clojure.core$load.doInvoke(core.clj:4904)
> at clojure.lang.RestFn.invoke(RestFn.java:409)
> at clojure.core$load_one.invoke(core.clj:4729)
> at clojure.core$load_lib.doInvoke(core.clj:4766)
> at clojure.lang.RestFn.applyTo(RestFn.java:143)
> at clojure.core$apply.invoke(core.clj:542)
> at clojure.core$load_libs.doInvoke(core.clj:4804)
> at clojure.lang.RestFn.applyTo(RestFn.java:138)
> at clojure.core$apply.invoke(core.clj:542)
> at clojure.core$require.doInvoke(core.clj:4869)
> at clojure.lang.RestFn.invoke(RestFn.java:409)
> at nlplabs.webfetch.lib$eval776.invoke(lib.clj:35)
> at clojure.lang.Compiler.eval(Compiler.java:5424)
> at clojure.lang.Compiler.eval(Compiler.java:5414)
> at clojure.lang.Compiler.load(Compiler.java:5857)
> at com.nlplabs.util.GClojure.load(GClojure.java:41)
> at com.nlplabs.util.GClojure.loadExtractorLib(GClojure.java:32)
> at com.nlplabs.util.GClojure$loadExtractorLib.call(Unknown Source)
> at
> com.nlplabs.lf.protocols.WEBProtocol.(WEBProtocol.groovy:19)
> ... 27 more
> Caused by: java.lang.NoClassDefFoundError:
> com/gargoylesoftware/htmlunit/html/BaseFrameElement
> at java.lang.Class.forName0(Native Method)
> at java.lang.Class.forName(Class.java:169)
> at
> nlplabs.webfetch.agent$eval786$loading__4410__auto787.invoke(agent.clj:1)
> at nlplabs.webfetch.agent$eval786.invoke(agent.clj:1)
> at clojure.lang.Compiler.eval(Compiler.java:5424)
> ... 74 more
> Caused by: java.lang.ClassNotFoundException:
> com.gargoylesoftware.htmlunit.html.BaseFrameElement
> at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
> at java.security.AccessController.doPrivileged(Native Method)
> at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
> at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
> at java.lang.ClassLoader.loadClass(ClassLoader.java:252)
> at java.lang.ClassLoader.loadClass(ClassLoader.java:252)
> at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:320)
> ... 79 more
> Server running. Browse to http://localhost:8080/jlfr
>
>   Copied below is th

Re: why is this behaving badly?

2013-05-24 Thread Andy Fingerhut
Try adding (flush) after the print call.


On Fri, May 24, 2013 at 12:35 PM, Jim - FooBar(); wrote:

> Hi everyone,
>
> I am trying to do something very simple like asking the user whether he
> wants to continue or not (a-la bash). However, sometimes the print
> statement is printed sometimes it isn't! IN other words sometimes I get the
> prompt ,sometimes it looks like it's hanging (while in fact it's waiting
> for the user to type \y or ) and it's printing the warning altogether with
> what the user typed and the rest of the output...weird stuff!
>
>
> (print " \u001B[31mYOU ARE PERFORMING A POTENTIALLY ILLEGAL
> OPERATION...\n\t PROCEED AT YOUR OWN RISK!!!\u001B[m Proceed? (y/n):")
>  (when  (-> *in*
>   (java.util.Scanner.)
>   .next
>   (.charAt 0)
>   (= \y))
>
> any ideas?
>
> Jim
>
> --
> --
> 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+unsubscribe@**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+unsubscribe@**googlegroups.com
> .
> For more options, visit 
> https://groups.google.com/**groups/opt_out
> .
>
>
>

-- 
-- 
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/groups/opt_out.




Re: filter on sets ... [reward: me face palming]

2013-05-25 Thread Andy Fingerhut
If (map find-records query-parts) is returning this expression:

(({:a2p-id "1", :dh-uuid "abc-def-ghi-klm"} {:a2p-id "2", :dh-uuid
"def-ghi-klm-opq"} {:a2p-id "3", :dh-uuid nil}) ({:a2p-id "1", :dh-uuid
"abc-def-ghi-klm"} {:a2p-id "2", :dh-uuid "def-ghi-klm-opq"} {:a2p-id "3",
:dh-uuid nil}))

then especially note the double parentheses.  That is a list (or sequence),
whose first element is a list (or sequence) of maps.  You can use (first
(map find-records query-parts)) to get the inner list.

Andy


On Sat, May 25, 2013 at 4:21 AM, Mond Ray  wrote:

> I am missing something obvious... I get a list of maps back from a
> function and I want to find the elements with nil
>
> (({:a2p-id "1", :dh-uuid "abc-def-ghi-klm"} {:a2p-id "2", :dh-uuid
> "def-ghi-klm-opq"} {:a2p-id "3", :dh-uuid nil}) ({:a2p-id "1", :dh-uuid
> "abc-def-ghi-klm"} {:a2p-id "2", :dh-uuid "def-ghi-klm-opq"} {:a2p-id "3",
> :dh-uuid nil}))
>
> I try the select function but it has no effect ... same list
>
> (set/select #(not (:dh-uuid %)) (map find-records query-parts))
>
> also tried the previously working example... same list
>
> (filter #(not (:dh-uuid %)) (map find-records query-parts))
>
> I am assuming that I am not indexing into each of the maps but I cannot
> remember or find out how to do this ... all examples only show one map
>
> Thanks
>
> Ray
>
> --
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
> ---
> You received this message because you are subscribed to the Google Groups
> "Clojure" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to clojure+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/groups/opt_out.
>
>
>

-- 
-- 
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/groups/opt_out.




Re: filter on sets ... [reward: me face palming]

2013-05-25 Thread Andy Fingerhut
Woops, and here I wasn't being careful enough...  You have a list (or
sequence) of two elements, both of which are lists (or sequences) of maps.
You can use (apply concat (map find-records query-parts)) to return a
single list containing nothing but maps.

Andy


On Sat, May 25, 2013 at 10:27 AM, Andy Fingerhut
wrote:

> If (map find-records query-parts) is returning this expression:
>
>
> (({:a2p-id "1", :dh-uuid "abc-def-ghi-klm"} {:a2p-id "2", :dh-uuid
> "def-ghi-klm-opq"} {:a2p-id "3", :dh-uuid nil}) ({:a2p-id "1", :dh-uuid
> "abc-def-ghi-klm"} {:a2p-id "2", :dh-uuid "def-ghi-klm-opq"} {:a2p-id "3",
> :dh-uuid nil}))
>
> then especially note the double parentheses.  That is a list (or
> sequence), whose first element is a list (or sequence) of maps.  You can
> use (first (map find-records query-parts)) to get the inner list.
>
> Andy
>
>
> On Sat, May 25, 2013 at 4:21 AM, Mond Ray  wrote:
>
>> I am missing something obvious... I get a list of maps back from a
>> function and I want to find the elements with nil
>>
>> (({:a2p-id "1", :dh-uuid "abc-def-ghi-klm"} {:a2p-id "2", :dh-uuid
>> "def-ghi-klm-opq"} {:a2p-id "3", :dh-uuid nil}) ({:a2p-id "1", :dh-uuid
>> "abc-def-ghi-klm"} {:a2p-id "2", :dh-uuid "def-ghi-klm-opq"} {:a2p-id "3",
>> :dh-uuid nil}))
>>
>> I try the select function but it has no effect ... same list
>>
>> (set/select #(not (:dh-uuid %)) (map find-records query-parts))
>>
>> also tried the previously working example... same list
>>
>> (filter #(not (:dh-uuid %)) (map find-records query-parts))
>>
>> I am assuming that I am not indexing into each of the maps but I cannot
>> remember or find out how to do this ... all examples only show one map
>>
>> Thanks
>>
>> Ray
>>
>> --
>> --
>> You received this message because you are subscribed to the Google
>> Groups "Clojure" group.
>> To post to this group, send email to clojure@googlegroups.com
>> Note that posts from new members are moderated - please be patient with
>> your first post.
>> To unsubscribe from this group, send email to
>> clojure+unsubscr...@googlegroups.com
>> For more options, visit this group at
>> http://groups.google.com/group/clojure?hl=en
>> ---
>> You received this message because you are subscribed to the Google Groups
>> "Clojure" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to clojure+unsubscr...@googlegroups.com.
>> For more options, visit https://groups.google.com/groups/opt_out.
>>
>>
>>
>
>

-- 
-- 
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/groups/opt_out.




Re: java.lang.NoSuchMethodError: clojure.lang.RT.mapUniqueKeys

2013-05-27 Thread Andy Fingerhut
clojure.lang.RT.mapUniqueKeys was added to Clojure 1.5, and did not appear
in 1.4 or earlier.  It was added to Clojure 1.5 as part of this change:


https://github.com/clojure/clojure/blob/master/changes.md#210-set-and-map-constructor-functions-allow-duplicates

But yes, as Michael said, it means that you have some code compiled with
Clojure 1.5 or later that you are attempting to run with an earlier version
of Clojure.

Andy


On Mon, May 27, 2013 at 9:15 AM, Michael Klishin <
michael.s.klis...@gmail.com> wrote:

> 2013/5/27 ru 
>
>> Exception in thread "AWT-EventQueue-0" java.lang.NoSuchMethodError:
>> clojure.lang.RT.mapUniqueKeys([Ljava/lang/Object;)Lclojure/lang/IPersistentMap;
>>
>
> You have code compiled against 1.4 (or later) that's running against
> Clojure 1.3.
> --
> MK
>
> http://github.com/michaelklishin
> http://twitter.com/michaelklishin
>
> --
> --
> 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/groups/opt_out.
>
>
>

-- 
-- 
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/groups/opt_out.




Re: sorted-map-by issue?

2013-06-06 Thread Andy Fingerhut
Your comparator #(if (= %1 %2) 0 1) may happen to give the correct answers
for your example sorted-maps, but it is also a bad comparator that will
fail for larger examples:

user=> (:a (sorted-map-by #(if (= %1 %2) 0 1) :z -26 :b 1 :a 2 :c 3 :m 13
:h 8))
nil
user=> (:z (sorted-map-by #(if (= %1 %2) 0 1) :z -26 :b 1 :a 2 :c 3 :m 13
:h 8))
nil

That is because if two items are not =, by returning 1 you are telling the
caller "the first argument should come after the second argument".  Thus if
at some time the comparator is called as (cmp :a :z), and later it is
called as (cmp :z :a), it returns the inconsistent results that :a should
come after :z, and later that :z should come after :a.  No sorted tree can
hope to return correct results given such an inconsistent comparator.

More examples and discussion at the link below, if you are interested:


https://github.com/jafingerhut/thalia/blob/master/doc/other-topics/comparators.md

Andy


On Thu, Jun 6, 2013 at 4:19 AM, dennis zhuang  wrote:

> Sorry, it's my mistake.
> Because treep map use the comparator to compare keys, and if the
> comparator returns 1 constantly,it can not find the item that equals the
> key.
>
> So i can modified the example,and it works:
>
> user=> (sorted-map-by #(if (= %1 %2) 0 1) :b 1 :a 2)
> {:b 1, :a 2}
> user=> (:a (sorted-map-by #(if (= %1 %2) 0 1) :b 1 :a 2))
> 2
> user=> (:b (sorted-map-by #(if (= %1 %2) 0 1) :b 1 :a 2))
> 1
>
>
> 2013/6/6 dennis zhuang 
>
>> user=> (sorted-map-by (constantly 1) :b 1 :a 2)
>> {:b 1, :a 2}
>> user=> (:a (sorted-map-by (constantly 1) :b 1 :a 2))
>> nil
>> user=> (keys (sorted-map-by (constantly 1) :b 1 :a 2))
>> (:b :a)
>> user=> (count (sorted-map-by (constantly 1) :b 1 :a 2))
>> 2
>> user=> (:a (sorted-map-by (constantly 1) :b 1 :a 2))
>> nil
>>
>> It looks so strange.The result map has keys :a and :b,but i can't get
>> their values.
>> Why? I try to hack the code,but i can't find the reason.
>>
>>
>> --
>> 庄晓丹
>> Email:killme2...@gmail.com xzhu...@avos.com
>> Site:   http://fnil.net
>> Twitter:  @killme2008
>>
>>
>>
>
>
> --
> 庄晓丹
> Email:killme2...@gmail.com xzhu...@avos.com
> Site:   http://fnil.net
> Twitter:  @killme2008
>
>
>  --
> --
> 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/groups/opt_out.
>
>
>

-- 
-- 
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/groups/opt_out.




Re: sorted-map-by issue?

2013-06-06 Thread Andy Fingerhut
A few people, I believe primarily Alan Malloy and Anthony Grimes, have
created a Clojure library for what they call ordered sets and maps that do
exactly this.  They are implemented not as you tried to do, but by
remembering a number for each element (for ordered sets) or key (for
ordered maps) that is the relative order that it was added in.

https://github.com/flatland/ordered

Andy


On Thu, Jun 6, 2013 at 7:56 AM, dennis zhuang  wrote:

> Thanks,you are right.I want to creat a map which keeps elements in
> insertion order, but clojure doesn‘t have.
> 在 2013-6-6 下午10:02,"Andy Fingerhut" 写道:
>
> Your comparator #(if (= %1 %2) 0 1) may happen to give the correct answers
>> for your example sorted-maps, but it is also a bad comparator that will
>> fail for larger examples:
>>
>> user=> (:a (sorted-map-by #(if (= %1 %2) 0 1) :z -26 :b 1 :a 2 :c 3 :m 13
>> :h 8))
>> nil
>> user=> (:z (sorted-map-by #(if (= %1 %2) 0 1) :z -26 :b 1 :a 2 :c 3 :m 13
>> :h 8))
>> nil
>>
>> That is because if two items are not =, by returning 1 you are telling
>> the caller "the first argument should come after the second argument".
>> Thus if at some time the comparator is called as (cmp :a :z), and later it
>> is called as (cmp :z :a), it returns the inconsistent results that :a
>> should come after :z, and later that :z should come after :a.  No sorted
>> tree can hope to return correct results given such an inconsistent
>> comparator.
>>
>> More examples and discussion at the link below, if you are interested:
>>
>>
>> https://github.com/jafingerhut/thalia/blob/master/doc/other-topics/comparators.md
>>
>> Andy
>>
>>
>> On Thu, Jun 6, 2013 at 4:19 AM, dennis zhuang wrote:
>>
>>> Sorry, it's my mistake.
>>> Because treep map use the comparator to compare keys, and if the
>>> comparator returns 1 constantly,it can not find the item that equals the
>>> key.
>>>
>>> So i can modified the example,and it works:
>>>
>>> user=> (sorted-map-by #(if (= %1 %2) 0 1) :b 1 :a 2)
>>> {:b 1, :a 2}
>>> user=> (:a (sorted-map-by #(if (= %1 %2) 0 1) :b 1 :a 2))
>>> 2
>>> user=> (:b (sorted-map-by #(if (= %1 %2) 0 1) :b 1 :a 2))
>>> 1
>>>
>>>
>>> 2013/6/6 dennis zhuang 
>>>
>>>> user=> (sorted-map-by (constantly 1) :b 1 :a 2)
>>>> {:b 1, :a 2}
>>>> user=> (:a (sorted-map-by (constantly 1) :b 1 :a 2))
>>>> nil
>>>> user=> (keys (sorted-map-by (constantly 1) :b 1 :a 2))
>>>> (:b :a)
>>>> user=> (count (sorted-map-by (constantly 1) :b 1 :a 2))
>>>> 2
>>>> user=> (:a (sorted-map-by (constantly 1) :b 1 :a 2))
>>>> nil
>>>>
>>>> It looks so strange.The result map has keys :a and :b,but i can't get
>>>> their values.
>>>> Why? I try to hack the code,but i can't find the reason.
>>>>
>>>>
>>>> --
>>>> 庄晓丹
>>>> Email:killme2...@gmail.com xzhu...@avos.com
>>>> Site:   http://fnil.net
>>>> Twitter:  @killme2008
>>>>
>>>>
>>>>
>>>
>>>
>>> --
>>> 庄晓丹
>>> Email:killme2...@gmail.com xzhu...@avos.com
>>> Site:   http://fnil.net
>>> Twitter:  @killme2008
>>>
>>>
>>>  --
>>> --
>>> 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/groups/opt_out.
>>>
>>>
>>>
>>
>>  --
>> --
>> 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 post

Re: Why aim for repeatability of specification / generative testing?

2013-06-06 Thread Andy Fingerhut
I've worked on hardware logic design, where the time and effort required to
create good tests that find subtle bugs rivals the complexity of the
hardware being designed itself.  In this context, much of the testing has
often been generated using pseudo-random streams similar to test.generative
and the simulation approach being advocated for software.  I think that is
a great idea for improving software quality.

In hardware testing via simulation, reproducible tests are important
because most of the testing cycles are run with a low amount of logging
enabled -- just enough logging to look for signs of incorrect behavior.
When a hardware designer wants to debug the problem, the test can be re-run
with very detailed logs enabled (basically amounting to recording the logic
0/1 value of every wire in the hardware being designed at every instant in
simulated time).  These are much slower and require a lot more temporary
disk space to record the logs.

So you end up using a large variety of different seed values to increase
test coverage, and if any of them fails, you can turn on the extra logging
and re-run it, knowing that you will hit the same problem as before.

Andy


On Thu, Jun 6, 2013 at 12:30 PM, Chas Emerick  wrote:

> Well, if *that's* all it is, I'll feel like quite the heel for putting so
> much thought into it! ;-)
>
> Assuming failures are rarer, then starting with a just-previously-failed
> seed would be better as an explicit action, rather than defaulting to a
> constant?
>
> - Chas
>
> On Jun 6, 2013, at 3:21 PM, Raoul Duke wrote:
>
> > i always thought it was basically solely for letting you re-run the
> > test that just/previously failed, nothing more weird or silly than
> > that.
>
> --
> --
> 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/groups/opt_out.
>
>
>

-- 
-- 
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/groups/opt_out.




Re: [ANN] Instaparse 1.1.0

2013-06-11 Thread Andy Fingerhut
Mark,

I had not heard about Java changing the substring operation from O(1) to
O(n).  Do you have a link to any further info about this change?

I'm guessing that the implementation is changing from the O(1) "create a
new String object that is a reference to a portion of the original String
object" to O(n) "create a new String object that is a copy of a portion of
the original String object"?

If so, note that it is undesirable in some cases that the O(1) substring
operation works as it does, because it prevents the longer string from
being GC'ed if it would become garbage, except for the fact that one has
created and keeps substrings of it around.  One can explicitly call the
String constructor to copy the substrings if you want to avoid that
behavior, of course, so the O(1) with the O(n) fallback is more flexible in
that it lets the developer aware of this behavior choose between them.

I haven't done anything but think about it during commute time yet, but I
had been wondering in how many situations it might be useful to have a
string type that was something like Relaxed Radix Binary trees, in that
they can be concatenated and substring'd in O(log n) worst case time, and
yet substrings would only hold onto references of the parts that they
explicitly refer to, and perhaps a little bit more (but not the entire
original string).

Andy


On Tue, Jun 11, 2013 at 3:09 PM, Mark Engelberg wrote:

> Honestly I hadn't yet given it any thought.  Thanks for the interest in
> having it on Clojurescript.  Here are a few issues that come to mind:
>
> 1.  To achieve performance, I've spent time coding custom data structures
> that implement various Clojure and Java interfaces.  I haven't done much
> with Clojurescript, but my impression is that the ecosystem of protocols is
> completely different, so I imagine that could be a pain to transfer over.
>
> 2.  I don't know much about the performance of Javascript/Clojurescript's
> underlying data structures.  For example, in Java, the substring operation
> used to be O(1), but recently, much to my dismay, they changed it to O(n).
> That change was annoying, and it means I'm going to have to rework some
> code to deal with that, but at least I heard about it and can take it into
> account.  But in Javascript I don't even *know* the performance
> characteristics of its strings and substring operation.  What other
> Javascript performance gotchas don't I know about?
>
> 3. I'm assuming that due to the above, it won't be as simple as just
> recompiling the code for Clojurescript.  I have no idea what's involved
> with maintaining a code base for the two target languages simultaneously.
> Sounds non-trivial, although maybe it won't seem so intimidating once
> things have settled down and I'm not making quite so many performance
> tweaks and feature enhancements to the code.
>
> In any case, please add your request as a github issue, so I don't forget
> about it.
>
>
> On Tue, Jun 11, 2013 at 8:06 AM, JeremyS  wrote:
>
>> Hi Puzzler,
>>
>> I was wondering if you planned to port Instaparse to ClojureScript. I
>> know it's asking a lot, but I am one of those who would love
>> to be able to run it in a browser or in node.js...
>>
>> Cheers,
>>
>> Jeremys.
>>
>  --
> --
> 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/groups/opt_out.
>
>
>

-- 
-- 
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/groups/opt_out.




Re: [ANN] Instaparse 1.1.0

2013-06-11 Thread Andy Fingerhut
And to answer my own question about a reference for this change in
behavior, which appears to have been made in Java 7:


http://stackoverflow.com/questions/16123446/java-7-string-substring-complexity

Andy


On Tue, Jun 11, 2013 at 3:33 PM, Andy Fingerhut wrote:

> Mark,
>
> I had not heard about Java changing the substring operation from O(1) to
> O(n).  Do you have a link to any further info about this change?
>
> I'm guessing that the implementation is changing from the O(1) "create a
> new String object that is a reference to a portion of the original String
> object" to O(n) "create a new String object that is a copy of a portion of
> the original String object"?
>
> If so, note that it is undesirable in some cases that the O(1) substring
> operation works as it does, because it prevents the longer string from
> being GC'ed if it would become garbage, except for the fact that one has
> created and keeps substrings of it around.  One can explicitly call the
> String constructor to copy the substrings if you want to avoid that
> behavior, of course, so the O(1) with the O(n) fallback is more flexible in
> that it lets the developer aware of this behavior choose between them.
>
> I haven't done anything but think about it during commute time yet, but I
> had been wondering in how many situations it might be useful to have a
> string type that was something like Relaxed Radix Binary trees, in that
> they can be concatenated and substring'd in O(log n) worst case time, and
> yet substrings would only hold onto references of the parts that they
> explicitly refer to, and perhaps a little bit more (but not the entire
> original string).
>
> Andy
>
>
> On Tue, Jun 11, 2013 at 3:09 PM, Mark Engelberg 
> wrote:
>
>> Honestly I hadn't yet given it any thought.  Thanks for the interest in
>> having it on Clojurescript.  Here are a few issues that come to mind:
>>
>> 1.  To achieve performance, I've spent time coding custom data structures
>> that implement various Clojure and Java interfaces.  I haven't done much
>> with Clojurescript, but my impression is that the ecosystem of protocols is
>> completely different, so I imagine that could be a pain to transfer over.
>>
>> 2.  I don't know much about the performance of Javascript/Clojurescript's
>> underlying data structures.  For example, in Java, the substring operation
>> used to be O(1), but recently, much to my dismay, they changed it to O(n).
>> That change was annoying, and it means I'm going to have to rework some
>> code to deal with that, but at least I heard about it and can take it into
>> account.  But in Javascript I don't even *know* the performance
>> characteristics of its strings and substring operation.  What other
>> Javascript performance gotchas don't I know about?
>>
>> 3. I'm assuming that due to the above, it won't be as simple as just
>> recompiling the code for Clojurescript.  I have no idea what's involved
>> with maintaining a code base for the two target languages simultaneously.
>> Sounds non-trivial, although maybe it won't seem so intimidating once
>> things have settled down and I'm not making quite so many performance
>> tweaks and feature enhancements to the code.
>>
>> In any case, please add your request as a github issue, so I don't forget
>> about it.
>>
>>
>> On Tue, Jun 11, 2013 at 8:06 AM, JeremyS  wrote:
>>
>>> Hi Puzzler,
>>>
>>> I was wondering if you planned to port Instaparse to ClojureScript. I
>>> know it's asking a lot, but I am one of those who would love
>>> to be able to run it in a browser or in node.js...
>>>
>>> Cheers,
>>>
>>> Jeremys.
>>>
>>  --
>> --
>> 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/groups/opt_out.
>>
>>
>>

Re: (clojure 1.5.1) Weird performance results when using let versus def for variable

2013-06-21 Thread Andy Fingerhut
:jvm-opts and that ticket for Leiningen only affect the options passed to
the JVM if you let Leiningen invoke the JVM for you, e.g. via "lein run ..."

Colin showed pretty clearly in his email that he was using "lein uberjar"
followed by running the JVM explicitly with his own command line, so
Leiningen has no way to affect the JVM command line options in that case.

Andy


On Fri, Jun 21, 2013 at 6:59 AM, Jim - FooBar(); wrote:

>  Did you read the entire thread?
> both Jason and Leon (who originally posted) admit that this was the
> problem...Stuart even opened this issue:
> https://github.com/technomancy/leiningen/pull/1230
>
> the very last post reads:
>
> I should follow up on this and clarify that core.matrix's esum is in fact
> as fast as Java -- I apologize for the false statement (I was unaware that
> new versions of leiningen disable advanced JIT optimizations by default,
> which lead to the numbers I reported).
>
> Jim
>
>
>
>
> On 21/06/13 14:54, Michael Klishin wrote:
>
>  2013/6/21 Jim - FooBar(); 
>
>> If you're using leiningen, add this entry to your project.clj and rerun
>> your benchmarks.
>>
>> :jvm-opts ^replace []
>>
>
> Original post suggests the code is executed by building an uberjar running
> java -jar target/…
> so Leiningen default JVM options are not relevant.
> --
> MK
>
> http://github.com/michaelklishin
> http://twitter.com/michaelklishin
>  --
> --
> 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/groups/opt_out.
>
>
>
>
>  --
> --
> 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/groups/opt_out.
>
>
>

-- 
-- 
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/groups/opt_out.




Re: clojure 1.5 cheatsheet?

2013-06-24 Thread Andy Fingerhut
That link is also available near the top of
http://clojure.org/cheatsheet("Download other versions with
tooltips").

There are a few things new in 1.5 on the latest version, but I haven't yet
included any of the new reducers functions there yet.  If anyone has a
better suggestion for categorizing them, other than simply putting them all
together into one category together, I am open to suggestions.

Andy


On Mon, Jun 24, 2013 at 3:18 AM, terjesb  wrote:

> http://jafingerhut.github.io
>
> kl. 11:38:41 UTC+2 mandag 24. juni 2013 skrev Las følgende:
>
>> Hi,
>>
>> is there a clojure 1.5 cheatsheet somewhere, the last I could find was
>> 1.4.
>>
>> Thanks,
>>
>> --
>> László Törö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/groups/opt_out.
>
>
>

-- 
-- 
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/groups/opt_out.




Re: Unnecessary boxing with 1.5?

2013-06-24 Thread Andy Fingerhut
You have what is likely an undesired right paren at the end of the let
line, ending the scope of the let.

Andy


On Mon, Jun 24, 2013 at 4:32 PM, Cedric Greevey  wrote:

> (defn foo [x y z]
>   (let [x (long x) y (long y) z (long z)])
> (loop [a false b (long 0)]
>   (if a b (recur true (+ x (+ y z))
> NO_SOURCE_PATH:1 recur arg for primitive local: b is not matching
> primitive, had: Object, needed: long
> Auto-boxing loop arg: b
>
> What the fuh? Binary + with primitive args is supposed to produce
> primitive output. The auto-promoting +' and ternary-plus + are the ones
> that are supposed to produce Object. What gives?
>
>  --
> --
> 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/groups/opt_out.
>
>
>

-- 
-- 
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/groups/opt_out.




Re: Build fails with any IBM JDK above 6.0.x

2013-07-01 Thread Andy Fingerhut
Sherif:

The last time I tried a few months ago, Clojure 1.5.1 plus the patch
clj-967-disable-failing-io-copy-tests-on-ibm-jdk-16-patch1.txt built and
passed all tests with IBM JDK 1.6.

http://dev.clojure.org/jira/browse/CLJ-967

The main change in that patch is to disable a couple of unit tests for
clojure.java.io/copy that work on other JDKs but fail with IBM JDK 1.6,
related to how it handles UTF-16 encoding a bit differently.

Let me know if that works for you.

Andy


On Sun, Jun 30, 2013 at 10:22 AM, Sherif Ali  wrote:

> Hello all,
>
> I am having a problem building any Clojure version (1.1, 1.2, 1.3, 1.5)
> with any IBM JDK over 6.0.x. My main interest is for version 1.1 but I will
> take anything above as well. Is there a fix, certain setup, configuration,
> pre-built version, etc. that can get me running on IBM JDK 626 or above.
> Kindly take into consideration that if this is not possible then Clojure
> can't run on WebSphere Application Server 8.0 or above.
>
> Just to put your mind to ease, I was able to build all these version with
> SUN JDK normally.
>
> Your help is greatly appreciated. Thanks in advance.
> Sherif M Ali
>
> --
> --
> 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/groups/opt_out.
>
>
>

-- 
-- 
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/groups/opt_out.




Re: Overflowing (count ...)

2013-07-08 Thread Andy Fingerhut
Making count return a correct long or BigInt value in such cases would be a
significant change, given that Java's int is used for the return value for
many count() and countFrom() methods sprinkled around Clojure's source code.

I've created a ticket CLJ-1229 and attached a patch that causes count to
throw an ArithmeticException if the sequence contains more than
Integer/MAX_VALUE elements.  I don't know if such a patch is acceptable to
the Clojure/core team or not, but we may find out.

http://dev.clojure.org/jira/browse/CLJ-1229

Andy


On Sun, Jul 7, 2013 at 5:13 PM, John Jacobsen  wrote:

> Was unsure whether to post to clojure or clojure-dev, but here goes.
>
> I was surprised to learn today that count silently overflows to negative
> numbers:
>
> jenome.core> (time (count (range (*' 1000 1000 1000 3
> "Elapsed time: 375225.663 msecs"
> -1294967296
> jenome.core>
>
> I can easily get around this with my own (non-overflowing) count function,
> but would it make sense for count throw an ArithmeticException on overflow,
> with *unchecked-math* set to false (as it is in my case)?
>
> Curiously,
> John
>
> --
> --
> 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/groups/opt_out.
>
>
>

-- 
-- 
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/groups/opt_out.




Re: Group words by their first letter and sum their frequencies

2013-07-11 Thread Andy Fingerhut
There is a link "Download other versions with tooltips" near the top of the
Clojure Cheat Sheet page (http://clojure.org/cheatsheet) that links to
versions that are a bit more recent, and they include tooltips of the doc
strings when you hover your cursor over the symbol.

The version at clojure.org/cheatsheet gets updated less frequently, simply
because I have to ask someone else to do it who has the necessary
permissions.  I'll ask again now.

Andy


On Thu, Jul 11, 2013 at 6:50 AM, James Trunk  wrote:

> Hello Laurent,
>
> Thank you so much for your detailed and helpful reply.
>
> > You could use the new as-> macro in clojure 1.5
> Is it possible to get as-> to work with thread-last?
>
> > depends :-) since your 2 fns are helper fns rather than
> > generically-reusable fns, I would make them private to enforce that :
> > (defn- ...)
> Good point, and I'll definitely try to remember that in the future.
>
> > May I suggest alternative implementations ?
> > 
> I really like both of your alternative solutions, and have learned several
> new ideas from them. Thank you.
>
> By the way, I'm using the Clojure Cheat Sheet (
> http://clojure.org/cheatsheet) as my guide to the core functions, but it
> doesn't seem to be up-to-date with all these fancy 1.5 functions that
> you're using. Is there a new website that has superseded CCS? Do you know
> why CCS isn't kept up-to-date?
>
> Regards,
> James
>
> On Thursday, July 11, 2013 2:29:38 PM UTC+2, Laurent PETIT wrote:
>
>> Hello James,
>>
>> 2013/7/11 James Trunk :
>> > Hi everyone, I'm new to Clojure and trying to learn my way around the
>> > language.
>> >
>> > I've written a function that sums the frequencies of words starting
>> with the
>> > same letter, however I'm not fully satisfied with the result. I'm
>> striving
>> > for readability and idomaticity, but I fear that my rather limited
>> grasp of
>> > Clojure's core functions and lack of experience with functional
>> programming
>> > are letting me down on both counts.
>> >
>> > (def text (slurp 
>> > "http://www.ccel.org/ccel/**bible/kjv.txt<http://www.ccel.org/ccel/bible/kjv.txt>"))
>>
>> >
>> > (defn sum-last-elements [coll]
>> >   (reduce + (map last coll)))
>> >
>> > (defn group-first-elements [coll]
>> >   (map first coll))
>> >
>> > (->> text
>> >  (re-seq
>> > #"(?:(?:\bm[a|e]n\b)|(?:\bwom[**a|e]n\b)|(?:\bchild\b)|(?:\**bchildren\b))")
>>
>> >  frequencies
>> >  (group-by ffirst)
>> >  vals
>> >  (#(zipmap (map group-first-elements %) (map sum-last-elements
>> %
>> >
>> > Which on that file gives the result:
>> >
>> > {("woman" "women") 663, ("children" "child") 2274, ("men" "man") 5314}
>> >
>> > My questions:
>> >
>> > Is there a way to avoid using ?: everywhere in the regex?
>> > (group-by ffirst) vals - is there a more readable/declarative/idiomatic
>> way
>> > to group by first letter?
>>
>> you could first (group-by first), then create the final map by calling
>> (distinct) and count
>>
>> > Is there a trick to avoid the ugly looking anonymous function (which
>> I'm
>> > only using to reorder the thread-last argument)?
>>
>> You could use the new as-> macro in clojure 1.5
>>
>> > Is it idiomatic to extract small functions to give them names (with an
>> eye
>> > to aiding readability) or would most Clojure programmers prefer these
>> to be
>> > anonymous and in-line?
>>
>> depends :-) since your 2 fns are helper fns rather than
>> generically-reusable fns, I would make them private to enforce that :
>> (defn- ...)
>>
>> > Is thread-last the right approach when dealing with nested
>> data-structures
>> > or is list comprehension, or some other approach preferred?
>>
>> The thread-last as you employed it is fine by me.
>>
>> May I suggest alternative implementations ?
>>
>> (def text (slurp 
>> "http://www.ccel.org/ccel/**bible/kjv.txt<http://www.ccel.org/ccel/bible/kjv.txt>"))
>>
>> (let [words (re-seq
>> #"(?:(?:\bm[a|e]n\b)|(?:\bwom[**a|e]n\b)|(?:\bchild\b)|(?:\**bchildren\b))"
>>
>> text)
>>words-per-initial (vals (group-by first words))]
>>   (zipmap
>

Re: S-s-s-serious performance bug with `map` laziness

2013-07-13 Thread Andy Fingerhut
I believe that what you are seeing, with up to 32 more elements being
evaluated than is necessary to execute your code, is due precisely to
chunked sequences, as returned by (range n), preserved by map, and I
believe also for, doseq, and other Clojure functions and macros.

Chunked sequences can cause evaluation of things that you do not need.  In
the cases where you do want those things evaluated eventually anyway,
chunked sequences can save memory and time in producing those results.

They can also cause larger memory use than you want, and forcing full
laziness back into a chunked sequence can sometimes help, e.g. see the
issue description and my proposed pach here:
http://dev.clojure.org/jira/browse/MCOMB-2

Andy



On Sat, Jul 13, 2013 at 6:52 PM, Daniel Dinnyes  wrote:

> Seems these guys below have the same problem, and everyone thinks it is
> `apply` or `concat` to blame. One of the answerer even explains how apply
> is the issue, but in the reimplemented version of `mapcat` beside throwing
> out `apply` he does not use `map` either:
>
>
> http://stackoverflow.com/questions/4290665/does-concat-break-the-laziness-of-line-seq
>
> http://stackoverflow.com/questions/16194841/clojure-lazy-sequences-in-math-combinatorics-results-in-outofmemory-oom-error/16270113#16270113
>
>
> On Sunday, July 14, 2013 2:33:56 AM UTC+1, Daniel Dinnyes wrote:
>>
>> Hiya, check this code out guys:
>> 
>>
>> (defn point [x y]
>>   (println "x:" x "y:" y)
>>   [x y])
>>
>> (defn gen-data [n m]
>>   (for [i (range n)]
>> (for [j (range m)]
>>   (point i j
>>
>> (def data (apply concat (gen-data 100 100)))
>>
>> (nth data 5)
>>
>> "The output was the following:"
>>
>> "x: 0 y: 0
>>  x: 0 y: 1
>>  x: 0 y: 2
>>  x: 0 y: 3
>>  x: 0 y: 4
>>  x: 0 y: 5
>>  x: 0 y: 6
>>  x: 0 y: 7
>>  x: 0 y: 8
>>  x: 0 y: 9
>>  x: 0 y: 10
>>  x: 0 y: 11
>>  x: 0 y: 12
>>  x: 0 y: 13
>>  x: 0 y: 14
>>  x: 0 y: 15
>>  x: 0 y: 16
>>  x: 0 y: 17
>>  x: 0 y: 18
>>  x: 0 y: 19
>>  x: 0 y: 20
>>  x: 0 y: 21
>>  x: 0 y: 22
>>  x: 0 y: 23
>>  x: 0 y: 24
>>  x: 0 y: 25
>>  x: 0 y: 26
>>  x: 0 y: 27
>>  x: 0 y: 28
>>  x: 0 y: 29
>>  x: 0 y: 30
>>  x: 0 y: 31
>>  [0 5]"
>>
>> "Seems like other people have similar problems but the issue was
>> mis-attributed,
>> as they thought it has to do with `apply` and/or `concat` (read further
>> to find out why not):
>> https://groups.google.com/**forum/#!topic/clojure/**vzhFmpGkWTo<https://groups.google.com/forum/#!topic/clojure/vzhFmpGkWTo>
>> http://clojurian.blogspot.co.**uk/2012/11/beware-of-mapcat.**html<http://clojurian.blogspot.co.uk/2012/11/beware-of-mapcat.html>
>> "
>>
>> "First I too was suspicious about `concat` and `apply`, so I wrote a
>> version of concat which was not using varargs."
>>
>> (defn concat2 [coll]
>>   (lazy-seq
>>(if-let [s (seq coll)]
>>  (if-let [ss (seq (first s))]
>>(cons (first ss) (concat2 (cons (rest ss) (rest s
>>(concat2 (rest s)))
>>  nil)))
>>
>> (def data (apply concat (gen-data 100 100)))
>>
>> (nth data 5)
>>
>> "The issue was still there unfortunately, exactly the same printout like
>> the with the first example"
>>
>> "So next i became suspicious of `for`. Maybe it has to do with the way it
>> is evaluated. So I rewrote `gen-data` using `map`"
>>
>> (defn gen-data [n m]
>>   (map (fn [x]
>>  (map (fn [y] (point x y))
>>   (range m)))
>>(range n)))
>>
>> "Even with `map` the issue was still present. Maybe both `map` and `for`
>> has the same problem? Let's rewrite `map` then"
>>
>> (defn map2 [f coll]
>>   (lazy-seq
>>(if-let [s (seq coll)]
>>  (cons (f (first s))
>>(map2 f (rest s)))
>>  nil)))
>>
>> (defn gen-data [n m]
>>   (map2 (fn [x]
>>  (map2 (fn [y] (point x y))
>>   (range m)))
>>(range n)))
>>
>> (def data (apply concat (gen-data 100 100)))
>>
>> (nth data 5)
>>
>> "x: 0 y: 0
>>  x: 0 y: 1
>>  x: 0 y: 2
>>  x: 0 y: 3
>>  x: 0 y: 4
>>  x: 0 y: 5
>>  [0 5]"
>>
>> "GOTCHA!!! WORKS CORRECTLY!!! BUG FOUND!!!"
>>
>> "...seems like both `map` and `for` are affected, possibly be

Re: is intellij idea a good ide for clojure development?

2013-07-26 Thread Andy Fingerhut
There are many who agree with Richard Stallman that it is unethical to 
distribute software without the source code.

There are many who disagree with him, myself included.  I think it is 100% 
ethical to sell proprietary software, sans source code.

I only mention this in hopes that people interested in discussing the topic at 
length will find an appropriate forum to do so, which I hope the Clojure Google 
group is not.

Andy

On Jul 26, 2013, at 12:07 PM, Cedric Greevey  wrote:

> On Fri, Jul 26, 2013 at 10:29 AM, Charlie Griefer  
> wrote:
>> On Jul 25, 2013, at 8:15 PM, Cedric Greevey  wrote:
>> 
>>> Someone makes free software plugins for nonfree software?!
>>> 
>>> 
>>> On Thu, Jul 25, 2013 at 11:04 PM, Greg  wrote:
>>>>> You submit patches to nonfree software?!
>> 
>> 
>> I may regret asking this… but don't people deserve to get paid for their 
>> work?
> 
> There's a difference between "getting paid for your work" and "getting paid 
> over and over again for work you did once, years ago". There's also a 
> difference between "getting paid for your work" and "getting free 
> improvements contributed to your code but not making your code, in turn, 
> freely available to the community". And that's leaving aside the matter of 
> the "free" in "(non)free software" being "free as in speech, not as in beer".
> 
> -- 
> -- 
> 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/groups/opt_out.
>  
>  

-- 
-- 
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/groups/opt_out.




Re: BigDecimal and ==, with a proposed fix

2013-08-01 Thread Andy Fingerhut
I agree, which is why I wrote a patch for the ticket
http://dev.clojure.org/jira/browse/CLJ-1118

(Depending on when you read this, dev.clojure.org may not be accessible due
to a recent DNS update made by the Clojure folks.  Wait a while and try
again.)

It makes not only the change you suggest, but also another one to how hash
is calculated for BigDecimal values, so that hash is still consistent with
=.  Take a look at it and see if you think it is correct.

Andy


On Thu, Aug 1, 2013 at 9:28 PM, CGAT  wrote:

>   My understanding of == is that it is intended to establish numerical
> equivalence
>   across types. But I think that basic contract fails with BigDecimal. For
> instance,
>
>   (== 1M 1.0M) ; => false
>
>   because the scale properties of these numbers are different. So then of
> course:
>
>   [(== 1 1N 1.0) (== 1 1N 1.0 1M) (== 1 1N 1.0 1.0M) (== 1 1.0 1N 1.0M)]
> ; => [true true true false]
>   and
>   [(== 1.0M 1.0) (== 1.0 1) (== 1 1N) (== 1N 1.0M)]
> ; => [true true true false]
>
>   I find your lack of transitivity (and commutativity) ... disturbing.
>
>   The issue is that there are two notions of equality for BigDecimal,
>   equals and compareTo, where equals compares value *and* scale while
>   compareTo compares numerically.
>
>   The other numeric types use equals for equivalence, quite reasonably.
>   But in class BigDecimalOps in clojure/lang/Numbers.java, I propose
>   that
>
> public boolean equiv(Number x, Number y){
>   return toBigDecimal(x).equals(toBigDecimal(y));
> }
>
>   should be
>
> public boolean equiv(Number x, Number y){
>   return toBigDecimal(x).compareTo(toBigDecimal(y)) == 0;
> }
>
>   to give the proper sense of equivalence.
>
>   I haven't had a chance yet to recompile with this change to test it,
>   but we do have
>
>(zero? (. 1.0M (compareTo 1M)))  ; => true
>(zero? (. 1.M (compareTo 1M)))   ; => true
>(zero? (. 1.000M (compareTo 1.0M)))  ; => true
>
>   as desired.
>
>   Reactions?
>
>   Best,
>
>Chris
>
>  --
> --
> 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/groups/opt_out.
>
>
>

-- 
-- 
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/groups/opt_out.




Re: BigDecimal and ==, with a proposed fix

2013-08-01 Thread Andy Fingerhut
You can also see the patch at this link, in case it is a while before JIRA
is back up:

https://github.com/jafingerhut/clj-prescreen/blob/master/eval-results/2013-08-01/ticket-info/CLJ-1118-attachments/clj-1118-make-double-equals-true-for-more-bigdecimals-patch-v3.txt


On Thu, Aug 1, 2013 at 10:16 PM, Andy Fingerhut wrote:

> I agree, which is why I wrote a patch for the ticket
> http://dev.clojure.org/jira/browse/CLJ-1118
>
> (Depending on when you read this, dev.clojure.org may not be accessible
> due to a recent DNS update made by the Clojure folks.  Wait a while and try
> again.)
>
> It makes not only the change you suggest, but also another one to how hash
> is calculated for BigDecimal values, so that hash is still consistent with
> =.  Take a look at it and see if you think it is correct.
>
> Andy
>
>
> On Thu, Aug 1, 2013 at 9:28 PM, CGAT  wrote:
>
>>   My understanding of == is that it is intended to establish numerical
>> equivalence
>>   across types. But I think that basic contract fails with BigDecimal.
>> For instance,
>>
>>   (== 1M 1.0M) ; => false
>>
>>   because the scale properties of these numbers are different. So then of
>> course:
>>
>>   [(== 1 1N 1.0) (== 1 1N 1.0 1M) (== 1 1N 1.0 1.0M) (== 1 1.0 1N 1.0M)]
>> ; => [true true true false]
>>   and
>>   [(== 1.0M 1.0) (== 1.0 1) (== 1 1N) (== 1N 1.0M)]
>> ; => [true true true false]
>>
>>   I find your lack of transitivity (and commutativity) ... disturbing.
>>
>>   The issue is that there are two notions of equality for BigDecimal,
>>   equals and compareTo, where equals compares value *and* scale while
>>   compareTo compares numerically.
>>
>>   The other numeric types use equals for equivalence, quite reasonably.
>>   But in class BigDecimalOps in clojure/lang/Numbers.java, I propose
>>   that
>>
>> public boolean equiv(Number x, Number y){
>>   return toBigDecimal(x).equals(toBigDecimal(y));
>> }
>>
>>   should be
>>
>> public boolean equiv(Number x, Number y){
>>   return toBigDecimal(x).compareTo(toBigDecimal(y)) == 0;
>> }
>>
>>   to give the proper sense of equivalence.
>>
>>   I haven't had a chance yet to recompile with this change to test it,
>>   but we do have
>>
>>(zero? (. 1.0M (compareTo 1M)))  ; => true
>>(zero? (. 1.M (compareTo 1M)))   ; => true
>>(zero? (. 1.000M (compareTo 1.0M)))  ; => true
>>
>>   as desired.
>>
>>   Reactions?
>>
>>   Best,
>>
>>Chris
>>
>>  --
>> --
>> 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/groups/opt_out.
>>
>>
>>
>
>

-- 
-- 
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/groups/opt_out.




  1   2   3   4   5   6   7   8   9   10   >