Re: Stubbing with instrument and generators

2017-06-30 Thread Michael Glaesemann
Thanks for taking a look. Here's a ticket: 
https://dev.clojure.org/jira/browse/CLJ-2197

> On 2017-06-30, at 11:52, Alex Miller <a...@puredanger.com> wrote:
> 
> I don't think this is the same case as CLJ-2095 as the instrumented var 
> should have the opportunity to use the gen overrides you've included. In 
> particular, it seems like stest/instrument-choose-fn is currently passing the 
> :gen overrides map when getting the gen for the stubbed var. I'm wondering if 
> there is a bug there where the spec has already been resolved and thus the 
> gen key (::y) is not getting matched. Feel free to file a ticket for this.
> 
> On Friday, June 30, 2017 at 9:37:42 AM UTC-5, Michael Glaesemann wrote:
> Using spec instrument to stub functions is really helpful. I'm using stubbing 
> to test Stuart Sierra-style components with some success. However, I've been 
> surprised that generator override doesn't work as I would expect it to. 
> Here's an example: 
> 
> ;; [org.clojure/spec.alpha "0.1.123"] 
> 
> (require '[clojure.spec.alpha :as s]) 
> (require '[clojure.spec.gen.alpha :as gen]) 
> (require '[clojure.spec.test.alpha :as stest]) 
> 
> (defprotocol Y 
>   (-do-y [r])) 
> 
> (def y? (partial satisfies? Y)) 
> (s/def ::y y?) 
> 
> ;; Protocol methods can't be spec'd, so wrap it in a function. 
> 
> (defn do-y [r] 
>   (-do-y r)) 
> 
> (s/fdef do-y :args (s/cat :y-er ::y)) 
> 
> ;; Example of the protocol implementation that we're going to stub. 
> 
> (defrecord BadYer [] 
>   Y 
>   (-do-y [_] (throw (Exception. "can't make me!" 
> 
> 
> ;; Confirm BadYer instances are valid with respect to the protol spec. 
> 
> (s/valid? ::y (->BadYer)) 
> ;; => true 
> 
> ;; And confirm BadYer instances will throw when called. 
> 
> (try 
>   (do-y (->BadYer)) 
>   (catch Exception e 
> (.getMessage e))) 
> ;; => "can't make me!" 
> 
> 
> (def y-gen (gen/return (->BadYer))) 
> 
> ;; Confirm generator works as expected: 
> 
> (gen/sample y-gen 1) 
> ;; => (#spec_ex.core.BadYer{}) 
> 
> ;; We want to stub `do-y`, providing y-gen as a generator for `::y` 
> 
> (try 
>   (stest/instrument `do-y {:stub #{`do-y} 
>:gen {::y (fn [] y-gen)}}) 
>   (catch Exception e 
> (ex-data e))) 
> ;; => #:clojure.spec.alpha{:path [:y-er], :form :spec-ex.core/y, :failure 
> :no-gen} 
> 
> ;; However, we *can* stub `do-y` if we replace its spec. 
> 
> (stest/instrument `do-y 
>   {:stub #{`do-y} 
>:spec {`do-y (s/fspec 
>   :args (s/cat :y-er (s/with-gen ::y 
>(fn [] y-gen}}) 
> ;; => [spec-ex.core/do-y] 
> 
> There is a ticket open[ (CLJ-2095[1]) regarding using overrides s/gen with 
> custom generators. Is this a case where this applies? I can imagine that it 
> could be. Not overriding something that isn't there would result in the thing 
> still not being there, thus the :no-gen failure. And it is something that can 
> be worked around.  It would be decidedly more succinct if the gen override 
> worked rather than the spec override. 
> 
> Best, 
> 
> Michael Glaesemann 
> grzm seespotcode net 
> 
> 
> [1]: https://dev.clojure.org/jira/browse/CLJ-2095 
> 
> 
> -- 
> You received this 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.

Michael Glaesemann
grzm seespotcode net



-- 
You received this 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: Stubbing with instrument and generators

2017-06-30 Thread Alex Miller
I don't think this is the same case as CLJ-2095 as the instrumented var 
should have the opportunity to use the gen overrides you've included. In 
particular, it seems like stest/instrument-choose-fn is currently passing 
the :gen overrides map when getting the gen for the stubbed var. I'm 
wondering if there is a bug there where the spec has already been resolved 
and thus the gen key (::y) is not getting matched. Feel free to file a 
ticket for this.

On Friday, June 30, 2017 at 9:37:42 AM UTC-5, Michael Glaesemann wrote:
>
> Using spec instrument to stub functions is really helpful. I'm using 
> stubbing to test Stuart Sierra-style components with some success. However, 
> I've been surprised that generator override doesn't work as I would expect 
> it to. Here's an example: 
>
> ;; [org.clojure/spec.alpha "0.1.123"] 
>
> (require '[clojure.spec.alpha :as s]) 
> (require '[clojure.spec.gen.alpha :as gen]) 
> (require '[clojure.spec.test.alpha :as stest]) 
>
> (defprotocol Y 
>   (-do-y [r])) 
>
> (def y? (partial satisfies? Y)) 
> (s/def ::y y?) 
>
> ;; Protocol methods can't be spec'd, so wrap it in a function. 
>
> (defn do-y [r] 
>   (-do-y r)) 
>
> (s/fdef do-y :args (s/cat :y-er ::y)) 
>
> ;; Example of the protocol implementation that we're going to stub. 
>
> (defrecord BadYer [] 
>   Y 
>   (-do-y [_] (throw (Exception. "can't make me!" 
>
>
> ;; Confirm BadYer instances are valid with respect to the protol spec. 
>
> (s/valid? ::y (->BadYer)) 
> ;; => true 
>
> ;; And confirm BadYer instances will throw when called. 
>
> (try 
>   (do-y (->BadYer)) 
>   (catch Exception e 
> (.getMessage e))) 
> ;; => "can't make me!" 
>
>
> (def y-gen (gen/return (->BadYer))) 
>
> ;; Confirm generator works as expected: 
>
> (gen/sample y-gen 1) 
> ;; => (#spec_ex.core.BadYer{}) 
>
> ;; We want to stub `do-y`, providing y-gen as a generator for `::y` 
>
> (try 
>   (stest/instrument `do-y {:stub #{`do-y} 
>:gen {::y (fn [] y-gen)}}) 
>   (catch Exception e 
> (ex-data e))) 
> ;; => #:clojure.spec.alpha{:path [:y-er], :form :spec-ex.core/y, :failure 
> :no-gen} 
>
> ;; However, we *can* stub `do-y` if we replace its spec. 
>
> (stest/instrument `do-y 
>   {:stub #{`do-y} 
>:spec {`do-y (s/fspec 
>   :args (s/cat :y-er (s/with-gen ::y 
>(fn [] y-gen}}) 
> ;; => [spec-ex.core/do-y] 
>
> There is a ticket open[ (CLJ-2095[1]) regarding using overrides s/gen with 
> custom generators. Is this a case where this applies? I can imagine that it 
> could be. Not overriding something that isn't there would result in the 
> thing still not being there, thus the :no-gen failure. And it is something 
> that can be worked around.  It would be decidedly more succinct if the gen 
> override worked rather than the spec override. 
>
> Best, 
>
> Michael Glaesemann 
> grzm seespotcode net 
>
>
> [1]: https://dev.clojure.org/jira/browse/CLJ-2095 
>
>

-- 
You received this 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.


Stubbing with instrument and generators

2017-06-30 Thread Michael Glaesemann
Using spec instrument to stub functions is really helpful. I'm using stubbing 
to test Stuart Sierra-style components with some success. However, I've been 
surprised that generator override doesn't work as I would expect it to. Here's 
an example:

;; [org.clojure/spec.alpha "0.1.123"]

(require '[clojure.spec.alpha :as s])
(require '[clojure.spec.gen.alpha :as gen])
(require '[clojure.spec.test.alpha :as stest])

(defprotocol Y
  (-do-y [r]))

(def y? (partial satisfies? Y))
(s/def ::y y?)

;; Protocol methods can't be spec'd, so wrap it in a function.

(defn do-y [r]
  (-do-y r))

(s/fdef do-y :args (s/cat :y-er ::y))

;; Example of the protocol implementation that we're going to stub.

(defrecord BadYer []
  Y
  (-do-y [_] (throw (Exception. "can't make me!"


;; Confirm BadYer instances are valid with respect to the protol spec.

(s/valid? ::y (->BadYer))
;; => true

;; And confirm BadYer instances will throw when called.

(try
  (do-y (->BadYer))
  (catch Exception e
(.getMessage e)))
;; => "can't make me!"


(def y-gen (gen/return (->BadYer)))

;; Confirm generator works as expected:

(gen/sample y-gen 1)
;; => (#spec_ex.core.BadYer{})

;; We want to stub `do-y`, providing y-gen as a generator for `::y`

(try
  (stest/instrument `do-y {:stub #{`do-y}
   :gen {::y (fn [] y-gen)}})
  (catch Exception e
(ex-data e)))
;; => #:clojure.spec.alpha{:path [:y-er], :form :spec-ex.core/y, :failure 
:no-gen}

;; However, we *can* stub `do-y` if we replace its spec.

(stest/instrument `do-y
  {:stub #{`do-y}
   :spec {`do-y (s/fspec
  :args (s/cat :y-er (s/with-gen ::y
   (fn [] y-gen}})
;; => [spec-ex.core/do-y]

There is a ticket open[ (CLJ-2095[1]) regarding using overrides s/gen with 
custom generators. Is this a case where this applies? I can imagine that it 
could be. Not overriding something that isn't there would result in the thing 
still not being there, thus the :no-gen failure. And it is something that can 
be worked around.  It would be decidedly more succinct if the gen override 
worked rather than the spec override.

Best,

Michael Glaesemann
grzm seespotcode net


[1]: https://dev.clojure.org/jira/browse/CLJ-2095

-- 
You received this 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: Custom generators for custom predicate functions

2016-12-08 Thread Dave Dixon
Thanks Alex. I agree it probably isn't "needed", was just a little 
surprised to discover the asymmetry. Mostly was curious if there was some 
deeper design decision, e.g. that you need to start with some set of 
primitive predicates upon which you can start building named specs.

On Thursday, December 8, 2016 at 9:23:11 AM UTC-8, Alex Miller wrote:
>
> In general, you shouldn't need to do this (it is better to attach the 
> generator to the spec). Generator mappings are provided for core Clojure 
> predicates so that many common predicates gen automatically and so that 
> they can be combined (via things like s/and) with other predicates that 
> filter but don't gen.
>
> I was not part of the design discussion, but I assume that it would open a 
> can of worms around conflicts, ordering, and function resolution that Rich 
> and Stu didn't want to open at this time. Nothing precludes this from being 
> expanded later if deemed useful.
>
> On Thursday, December 8, 2016 at 10:56:29 AM UTC-6, Dave Dixon wrote:
>>
>> Though one can obviously attach a custom generator to a keyword-named 
>> spec, it appears there is no way to do the same for a custom predicate 
>> function. I see that the generators for predicate functions testing for 
>> core primitives are hard-coded in the private 
>> clojure.spec.gen\gen-builtins. Curious why this isn't extensible, since it 
>> naively seems similar to the keyword case, but with the custom generator 
>> keyed by a symbol rather than a map.
>>
>> Dave
>>
>

-- 
You received this 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: Custom generators for custom predicate functions

2016-12-08 Thread Alex Miller
In general, you shouldn't need to do this (it is better to attach the 
generator to the spec). Generator mappings are provided for core Clojure 
predicates so that many common predicates gen automatically and so that 
they can be combined (via things like s/and) with other predicates that 
filter but don't gen.

I was not part of the design discussion, but I assume that it would open a 
can of worms around conflicts, ordering, and function resolution that Rich 
and Stu didn't want to open at this time. Nothing precludes this from being 
expanded later if deemed useful.

On Thursday, December 8, 2016 at 10:56:29 AM UTC-6, Dave Dixon wrote:
>
> Though one can obviously attach a custom generator to a keyword-named 
> spec, it appears there is no way to do the same for a custom predicate 
> function. I see that the generators for predicate functions testing for 
> core primitives are hard-coded in the private 
> clojure.spec.gen\gen-builtins. Curious why this isn't extensible, since it 
> naively seems similar to the keyword case, but with the custom generator 
> keyed by a symbol rather than a map.
>
> Dave
>

-- 
You received this 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.


Custom generators for custom predicate functions

2016-12-08 Thread Dave Dixon
Though one can obviously attach a custom generator to a keyword-named spec, 
it appears there is no way to do the same for a custom predicate function. 
I see that the generators for predicate functions testing for core 
primitives are hard-coded in the private clojure.spec.gen\gen-builtins. 
Curious why this isn't extensible, since it naively seems similar to the 
keyword case, but with the custom generator keyed by a symbol rather than a 
map.

Dave

-- 
You received this 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: Spec & test.check generators for complex data structures

2016-11-01 Thread Alex Miller
The general approach to this is to first create a "model" of your domain, 
which might be some random seed info and then generate one or more entities 
that are consistent with the model.

Stu does a simple example of this in 
http://blog.cognitect.com/blog/2016/8/10/clojure-spec-screencast-customizing-generators
 
using gen/fmap and gen/bind which is probably the best way to build 
something like this.

As an example, if you need to test on a graph of nodes, your model might 
consist of first creating random nodes, then generating random edges 
between the nodes (rather than randomly generating nodes and edges, which 
will likely have no commonality). 



On Tuesday, November 1, 2016 at 2:14:28 PM UTC-5, Maarten Truyens wrote:
>
> Completely convinced of Spec, I am diving into property-based testing with 
> test.check. However, I encounter some difficulties for which I would like 
> to get the community's input. 
>
> The central part of the software I am developing, consists of a tree of 
> different kinds of nodes that can refer to — and interact with — each 
> other. There are many business rules that specify how those nodes can 
> interact — e.g., a node of type A can refer to other nodes of types B and C 
> (but not D); or a node can have max. 3 child nodes of type E but more than 
> 3 child nodes of type F. 
>
> It is trivial to have Spec generate completely random nodes to test 
> functions that can ignore the business rules. However, other functions do 
> depend on the business rules, and for those it is necessary to somewhat 
> "guide" the generators towards random-but-compliant output. And here I'm 
> stumbling: due to the business rules' complexity, this is not a matter of 
> simply inserting a few such-that generators, so that I have already spent 
> many days on writing a business rule compliant generator. Part of this is 
> due to the multitude and complexity of the business rules, part due to the 
> difficulty of writing generators (which operate at a higher level of 
> abstraction, and for which only a subset of the normal Clojure constructs 
> can be used).
>
> How do others cope with this issue? I have the feeling that I am pushing 
> the generators far beyond what they were designed to do, but at the same I 
> have to acknowledge that the time required to write traditional tests for 
> functions dealing with the business rules is also substantial — so maybe 
> the time required to write those generators is not abnormal.   
>
> Any suggestions are welcomed! I did not find any in-depth observations of 
> other developers about property-based testing on the Net.
>
> Maarten
>

-- 
You received this 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: Spec & test.check generators for complex data structures

2016-11-01 Thread Maarten Truyens
Thanks - the start of that thread was indeed interesting, but it quickly 
changed course towards a discussion on whether Spec should check function 
outputs. Rich hinted at exactly the kind of in-depth discussion I wanted to 
find — but much too briefly... 

-- 
You received this 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: Spec & test.check generators for complex data structures

2016-11-01 Thread Josh Tilles
I don’t have any answers, but you might find the discussion in the first 
several messages of this thread 
<https://groups.google.com/d/topic/clojure/jcVnjk1MOWY/discussion> to be 
relevant.

On Tuesday, November 1, 2016 at 3:14:28 PM UTC-4, Maarten Truyens wrote:
>
> Completely convinced of Spec, I am diving into property-based testing with 
> test.check. However, I encounter some difficulties for which I would like 
> to get the community's input. 
>
> The central part of the software I am developing, consists of a tree of 
> different kinds of nodes that can refer to — and interact with — each 
> other. There are many business rules that specify how those nodes can 
> interact — e.g., a node of type A can refer to other nodes of types B and C 
> (but not D); or a node can have max. 3 child nodes of type E but more than 
> 3 child nodes of type F. 
>
> It is trivial to have Spec generate completely random nodes to test 
> functions that can ignore the business rules. However, other functions do 
> depend on the business rules, and for those it is necessary to somewhat 
> "guide" the generators towards random-but-compliant output. And here I'm 
> stumbling: due to the business rules' complexity, this is not a matter of 
> simply inserting a few such-that generators, so that I have already spent 
> many days on writing a business rule compliant generator. Part of this is 
> due to the multitude and complexity of the business rules, part due to the 
> difficulty of writing generators (which operate at a higher level of 
> abstraction, and for which only a subset of the normal Clojure constructs 
> can be used).
>
> How do others cope with this issue? I have the feeling that I am pushing 
> the generators far beyond what they were designed to do, but at the same I 
> have to acknowledge that the time required to write traditional tests for 
> functions dealing with the business rules is also substantial — so maybe 
> the time required to write those generators is not abnormal.   
>
> Any suggestions are welcomed! I did not find any in-depth observations of 
> other developers about property-based testing on the Net.
>
> Maarten
>

-- 
You received this 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.


Spec & test.check generators for complex data structures

2016-11-01 Thread Maarten Truyens
Completely convinced of Spec, I am diving into property-based testing with 
test.check. However, I encounter some difficulties for which I would like 
to get the community's input. 

The central part of the software I am developing, consists of a tree of 
different kinds of nodes that can refer to — and interact with — each 
other. There are many business rules that specify how those nodes can 
interact — e.g., a node of type A can refer to other nodes of types B and C 
(but not D); or a node can have max. 3 child nodes of type E but more than 
3 child nodes of type F. 

It is trivial to have Spec generate completely random nodes to test 
functions that can ignore the business rules. However, other functions do 
depend on the business rules, and for those it is necessary to somewhat 
"guide" the generators towards random-but-compliant output. And here I'm 
stumbling: due to the business rules' complexity, this is not a matter of 
simply inserting a few such-that generators, so that I have already spent 
many days on writing a business rule compliant generator. Part of this is 
due to the multitude and complexity of the business rules, part due to the 
difficulty of writing generators (which operate at a higher level of 
abstraction, and for which only a subset of the normal Clojure constructs 
can be used).

How do others cope with this issue? I have the feeling that I am pushing 
the generators far beyond what they were designed to do, but at the same I 
have to acknowledge that the time required to write traditional tests for 
functions dealing with the business rules is also substantial — so maybe 
the time required to write those generators is not abnormal.   

Any suggestions are welcomed! I did not find any in-depth observations of 
other developers about property-based testing on the Net.

Maarten

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


Re: clojure.spec.test/instrument causes clojure.spec/exercise-fn to use generators which fail the args spec!?

2016-10-20 Thread J.-F. Rompre
Ah, I missed thatthank you very much!

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


Re: clojure.spec.test/instrument causes clojure.spec/exercise-fn to use generators which fail the args spec!?

2016-10-20 Thread Beau Fabry
You have two possible branches for your ::fizbuzz arguments, a one-arity 
and a 3-arity. The 1-arity branch allows for the value 1, which when passed 
to the function fizzbuzz recursively calls the function fizzbuzz with the 
arguments (3 5 1) is not a valid set of values for ::fizzbuzz and so raises 
an exception.

The reason you only get the exception when you've instrumented the 
function, is because the non-conforming set of arguments is constructed in 
the 1-arity, and doesn't get checked against ::fizzbuzz unless 
instrumentation is turned on.


On Thursday, October 20, 2016 at 3:17:19 PM UTC+11, J.-F. Rompre wrote:
>
> I am trying to learn clojure.spec and tried my hand at a spec for a 
> fizzbuzz function. 
> For some strange reason, generators created for it fail the same spec 
> during clojure.spec/exercise-fn !
>
> Stranger, this happens only if the same function is first instrumented 
> using clojure.spec.stest/instrument.
> Otherwise (commenting out the instrument call), exercise-fn generates 
> compliant inputs and returns.
>
> I tried to reproduce this with a trivial example to show here but 
> couldn't, so created a gist to illustrate the issue: 
>  https://gist.github.com/KingCode/101ff425f1abd9693a7e8c4b5d389e74
>
> Thanks for any comment and enlightening, I can't wait to use spec 
> productively :)
> JF
>

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


clojure.spec.test/instrument causes clojure.spec/exercise-fn to use generators which fail the args spec!?

2016-10-19 Thread J.-F. Rompre
I am trying to learn clojure.spec and tried my hand at a spec for a 
fizzbuzz function. 
For some strange reason, generators created for it fail the same spec 
during clojure.spec/exercise-fn !

Stranger, this happens only if the same function is first instrumented 
using clojure.spec.stest/instrument.
Otherwise (commenting out the instrument call), exercise-fn generates 
compliant inputs and returns.

I tried to reproduce this with a trivial example to show here but couldn't, 
so created a gist to illustrate the issue: 
 https://gist.github.com/KingCode/101ff425f1abd9693a7e8c4b5d389e74

Thanks for any comment and enlightening, I can't wait to use spec 
productively :)
JF

-- 
You received this 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.


Q: Is there a reason why some clojure.test.check generators are excluded from clojure.spec.gen lazy primitives?

2016-06-04 Thread Joseph Wayne Norton

Is there a reason why some clojure.test.check generators are excluded from 
clojure.spec.gen lazy primitives?

https://github.com/clojure/clojure/blob/1f25347a7b219488d5d9f8d17b04f2cc7828b30e/src/clj/clojure/spec/gen.clj#L114

The nat generator as one example is missing.

Best regards,

Joe N

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


clojure.spec guide updated with generators

2016-05-27 Thread Alex Miller
I've added a new section to the clojure.spec guide for generators. 
Certainly doesn't cover everything yet but hope it helps!

http://clojure.org/guides/spec#_generators

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


[ANN] schema-generators 0.1.0 (now with ClojureScript!)

2016-03-24 Thread Jason Wolfe
We've released schema-generators 0.1.0, which includes ClojureScript 
support via cljc:

https://github.com/plumatic/schema-generators

This library allows you to generate test data from most plumatic/schemas 
out of the box, as well as automatically "complete" partial datums -- which 
can both be very useful in different testing scenarios.  Please note the 
the corresponding functionality is now deprecated in the main schema 
project.

Big thanks to Milton Reder and others who helped with this release!   And 
on this note, *schema, plumbing, and our other libraries are now a 
completely volunteer effort, with no commercial support*.  Any help the 
community can provide in triaging issues, fixing bugs, etc would be much 
appreciated -- especially on the ClojureScript side of things.  If you're 
interested in helping out, please let me know and I'm happy to provide 
suggestions for how to get started.  

Have fun, and please let us know your feedback!  

-Jason

-- 
You received this 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] boot-new 0.4.0 -- Templates AND Generators for Boot!

2016-02-29 Thread Bryan Maass
I have some feedback.

Great work! I just blogged about a pure-boot way to get started with 
clojurescript: ( http://escherize.com/2016/02/29/boot-with-cljs ) so of 
course boot-new made an appearance. 

On Monday, February 29, 2016 at 12:20:50 PM UTC+11, Sean Corfield wrote:
>
> Frank Liu wrote on Saturday, February 27, 2016 at 9:39 AM:
>
> Love your project. Could you try to add them to the boot official pages 
> and github wiki's third party tasks? The reason is I can never find this 
> project on google (via "boot-new") or anywhere other than your github or 
> search here in the Clojure google group.
>
>
> It is listed on the third party tasks wiki page:
>
> https://github.com/boot-clj/boot/wiki/Community-Tasks
>
> As:
>
> Templates (Boot new) seancorfield/boot-new 
> <https://github.com/seancorfield/boot-new>
>
> But the plan is to merge it into the core Boot project at some point (once 
> we get a bit more feedback on boot-new itself and its templates and 
> generators) to knock off any rough edges.
>
> Sean Corfield -- (904) 302-SEAN
> An Architect's View -- http://corfield.org/
>
> "If you're not annoying somebody, you're not really alive."
> -- Margaret Atwood
>
>

-- 
You received this 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] boot-new 0.4.0 -- Templates AND Generators for Boot!

2016-02-28 Thread Sean Corfield
Frank Liu wrote on Saturday, February 27, 2016 at 9:39 AM:
Love your project. Could you try to add them to the boot official pages and 
github wiki's third party tasks? The reason is I can never find this project on 
google (via "boot-new") or anywhere other than your github or search here in 
the Clojure google group.

It is listed on the third party tasks wiki page:

https://github.com/boot-clj/boot/wiki/Community-Tasks

As:

Templates (Boot new)seancorfield/boot-new

But the plan is to merge it into the core Boot project at some point (once we 
get a bit more feedback on boot-new itself and its templates and generators) to 
knock off any rough edges.

Sean Corfield -- (904) 302-SEAN
An Architect's View -- http://corfield.org/

"If you're not annoying somebody, you're not really alive."
-- Margaret Atwood


-- 
You received this 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] boot-new 0.4.0 -- Templates AND Generators for Boot!

2016-02-27 Thread Frank Liu
Hi Sean,

Love your project. Could you try to add them to the boot official pages and 
github wiki's third party tasks? The reason is I can never find this 
project on google (via "boot-new") or anywhere other than your github or 
search here in the Clojure google group.

Frank

On Saturday, February 13, 2016 at 2:21:18 PM UTC-8, Sean Corfield wrote:
>
> What / Where?
> Boot new — a task to produce new projects from Boot and/or Leiningen 
> templates!
> boot-new 0.4.0 — https://github.com/seancorfield/boot-new
>
> Updates?
> Now supports generators to add / modify code in the current project!
> Add a new namespace with: boot new –g ns=foo.bar.quux
> Add a new function with: boot new –g defn=foo.bar.quux/my-func
>
> Sean Corfield -- (904) 302-SEAN
> An Architect's View -- http://corfield.org/
>
> "Perfection is the enemy of the good."
> -- Gustave Flaubert, French realist novelist (1821-1880)
>
>

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


[ANN] boot-new 0.4.0 -- Templates AND Generators for Boot!

2016-02-13 Thread Sean Corfield
What / Where?
Boot new — a task to produce new projects from Boot and/or Leiningen templates!
boot-new 0.4.0 — https://github.com/seancorfield/boot-new

Updates?
Now supports generators to add / modify code in the current project!
Add a new namespace with: boot new –g ns=foo.bar.quux
Add a new function with: boot new –g defn=foo.bar.quux/my-func

Sean Corfield -- (904) 302-SEAN
An Architect's View -- http://corfield.org/

"Perfection is the enemy of the good."
-- Gustave Flaubert, French realist novelist (1821-1880)


-- 
You received this 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: Controlling growth rates of generators with test.check

2015-07-29 Thread Mayank Jain
Nice. Any updates on this?
Is this a good idea?

On Friday, May 15, 2015 at 12:13:06 PM UTC+5:30, Mikera wrote:

 Hi all,

 I am doing some generative testing with test.check and need a way to 
 control the growth rate of data structures (the regular linear growth 
 quickly makes the computations too large for meaningful testing usage). I 
 came up with the following solution to do this:

 (defn gen-resize 
   Creates a generator that pre-modifies the 'size' pramater with the 
 function f. Use if you want to 
have the size grow at a different rate from the normal linear scaling.
   ([f gen]
 (let [gf (or (:gen gen) gen paramter must be a test.check generator)
   new-gf (fn [rnd size]
(gf rnd (f size)))]
   (clojure.test.check.generators.Generator. new-gf

 Normal O(n) growth:

 (gen/sample gen/s-pos-int 30)
 = (1 2 3 2 4 5 4 7 6 3 3 7 10 4 8 11 14 12 6 10 9 1 8 21 12 16 25 25 21 6)

 Controlled O(sqrt(n)) growth:

 (gen/sample (gen-resize sqrt gen/s-pos-int) 30)
 = (1 2 2 2 2 4 3 3 3 3 4 3 5 1 2 3 2 4 4 2 2 3 6 6 2 5 5 4 6 3)

 So it seems to work, but is this a sane / recommended approach? Am I 
 relying too much on test.check internals?

   mikera


-- 
You received this 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: Controlling growth rates of generators with test.check

2015-07-29 Thread Mikera
See:
https://github.com/clojure/test.check/commit/d4883873df73717629272d0ab71619d7e58c9c9e

On Wednesday, 29 July 2015 23:31:14 UTC+8, Mayank Jain wrote:

 Nice. Any updates on this?
 Is this a good idea?

 On Friday, May 15, 2015 at 12:13:06 PM UTC+5:30, Mikera wrote:

 Hi all,

 I am doing some generative testing with test.check and need a way to 
 control the growth rate of data structures (the regular linear growth 
 quickly makes the computations too large for meaningful testing usage). I 
 came up with the following solution to do this:

 (defn gen-resize 
   Creates a generator that pre-modifies the 'size' pramater with the 
 function f. Use if you want to 
have the size grow at a different rate from the normal linear scaling.
   ([f gen]
 (let [gf (or (:gen gen) gen paramter must be a test.check generator)
   new-gf (fn [rnd size]
(gf rnd (f size)))]
   (clojure.test.check.generators.Generator. new-gf

 Normal O(n) growth:

 (gen/sample gen/s-pos-int 30)
 = (1 2 3 2 4 5 4 7 6 3 3 7 10 4 8 11 14 12 6 10 9 1 8 21 12 16 25 25 21 
 6)

 Controlled O(sqrt(n)) growth:

 (gen/sample (gen-resize sqrt gen/s-pos-int) 30)
 = (1 2 2 2 2 4 3 3 3 3 4 3 5 1 2 3 2 4 4 2 2 3 6 6 2 5 5 4 6 3)

 So it seems to work, but is this a sane / recommended approach? Am I 
 relying too much on test.check internals?

   mikera



-- 
You received this 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: Controlling growth rates of generators with test.check

2015-07-29 Thread Mayank Jain
Thanks. That looks useful.
On Jul 30, 2015 6:14 AM, Mikera mike.r.anderson...@gmail.com wrote:

 See:

 https://github.com/clojure/test.check/commit/d4883873df73717629272d0ab71619d7e58c9c9e

 On Wednesday, 29 July 2015 23:31:14 UTC+8, Mayank Jain wrote:

 Nice. Any updates on this?
 Is this a good idea?

 On Friday, May 15, 2015 at 12:13:06 PM UTC+5:30, Mikera wrote:

 Hi all,

 I am doing some generative testing with test.check and need a way to
 control the growth rate of data structures (the regular linear growth
 quickly makes the computations too large for meaningful testing usage). I
 came up with the following solution to do this:

 (defn gen-resize
   Creates a generator that pre-modifies the 'size' pramater with the
 function f. Use if you want to
have the size grow at a different rate from the normal linear
 scaling.
   ([f gen]
 (let [gf (or (:gen gen) gen paramter must be a test.check
 generator)
   new-gf (fn [rnd size]
(gf rnd (f size)))]
   (clojure.test.check.generators.Generator. new-gf

 Normal O(n) growth:

 (gen/sample gen/s-pos-int 30)
 = (1 2 3 2 4 5 4 7 6 3 3 7 10 4 8 11 14 12 6 10 9 1 8 21 12 16 25 25 21
 6)

 Controlled O(sqrt(n)) growth:

 (gen/sample (gen-resize sqrt gen/s-pos-int) 30)
 = (1 2 2 2 2 4 3 3 3 3 4 3 5 1 2 3 2 4 4 2 2 3 6 6 2 5 5 4 6 3)

 So it seems to work, but is this a sane / recommended approach? Am I
 relying too much on test.check internals?

   mikera



-- 
You received this 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.


Controlling growth rates of generators with test.check

2015-05-15 Thread Mikera
Hi all,

I am doing some generative testing with test.check and need a way to 
control the growth rate of data structures (the regular linear growth 
quickly makes the computations too large for meaningful testing usage). I 
came up with the following solution to do this:

(defn gen-resize 
  Creates a generator that pre-modifies the 'size' pramater with the 
function f. Use if you want to 
   have the size grow at a different rate from the normal linear scaling.
  ([f gen]
(let [gf (or (:gen gen) gen paramter must be a test.check generator)
  new-gf (fn [rnd size]
   (gf rnd (f size)))]
  (clojure.test.check.generators.Generator. new-gf

Normal O(n) growth:

(gen/sample gen/s-pos-int 30)
= (1 2 3 2 4 5 4 7 6 3 3 7 10 4 8 11 14 12 6 10 9 1 8 21 12 16 25 25 21 6)

Controlled O(sqrt(n)) growth:

(gen/sample (gen-resize sqrt gen/s-pos-int) 30)
= (1 2 2 2 2 4 3 3 3 3 4 3 5 1 2 3 2 4 4 2 2 3 6 6 2 5 5 4 6 3)

So it seems to work, but is this a sane / recommended approach? Am I 
relying too much on test.check internals?

  mikera

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


Re: Howto write test.check custom generators

2014-08-19 Thread Reid Draper
Hey Tim,

When you write a property, like your `has-agroup`, there's no need to call 
`gen/sample`. You can simply write: (prop/for-all [v my-generator] ...)

-Reid

On Sunday, August 10, 2014 6:04:21 PM UTC-5, frye wrote:

 Oook, this is starting to sink in. 

 I've gotten a little farther, in that I can run quick-check with my custom 
 generator. However, after a bunch of values had been generated, it fails on 
 a NullPointerException. How can I know where the breakdown is happening? 

 = (tc/quick-check 100 u/has-agroup)
 {:email , :last-name , :first-name , :username }
 {:email , :last-name , :first-name , :username 0}
 {:email , :last-name , :first-name Rq, :username 0}
 {:email 5D2, :last-name R4F, :first-name x, :username G0H}
 ...
 {:email 8KQgSr497EPw14X80oEbWC0, :last-name cdkLb8D5ol, :first-name 
 8DCOXz1U4S3JM641u5I7yPwQ, :username DADOk}
 {:email x, :last-name Qq3h07d6Cbs4, :first-name 6H6Enrwu, :username 
 yf40SClLjJHp1ptbnx4I9xFbwI3}
 *NullPointerException   clojure.test.check.generators/gen-bind/fn--18990 
 (generators.clj:77)*
 bkell.bkell (pst *e)
 NullPointerException
 clojure.test.check.generators/gen-bind/fn--18990 
 (generators.clj:77)
 clojure.test.check.generators/gen-bind/fn--18990 
 (generators.clj:79)
  clojure.test.check.generators/gen-bind/fn--18990 
 (generators.clj:77)
 clojure.test.check.generators/gen-fmap/fn--18985 
 (generators.clj:70)
 clojure.test.check.generators/call-gen (generators.clj:56)
 clojure.test.check/quick-check (check.clj:57)
 bkell.bkell/eval19267 (form-init7280611083923741467.clj:1)
 clojure.lang.Compiler.eval (Compiler.java:6703)
 clojure.lang.Compiler.eval (Compiler.java:)
 clojure.core/eval (core.clj:2927)
  clojure.main/repl/read-eval-print--6625/fn--6628 (main.clj:239)
 clojure.main/repl/read-eval-print--6625 (main.clj:239)


 This is my domain function: 

   (defn *create-user* 
 ([] (create {}))
 ([opts]
(println opts)
(let [sans-nils (apply merge (for [[k v]
   opts
   :when (not (nil? v))]
   {k v}))]

  (merge {:id (mu/generate-uuid)
  :username 
  :password (crypto/base64 12)
  :first-name 
  :last-name 
  :email 
  :country {}}
 sans-nils


 And these are my test functions. 

   (def gend-user
 (gen/fmap *du/create-user*
   (gen/hash-map :username gen/string-alpha-numeric
 :first-name gen/string-alpha-numeric
 :last-name gen/string-alpha-numeric
 :email gen/string-alpha-numeric)))

   (def has-agroup
 (prop/for-all [v (gen/sample gend-user)]
   (- v nil? not)))



 Tim Washington 
 Interruptsoftware.com http://interruptsoftware.com 


 On Sun, Aug 10, 2014 at 3:02 PM, Sam Ritchie sritc...@gmail.com 
 javascript: wrote:

 You can to use gen/fmap to build up generators. Here's an example:



-- 
You received this 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.


Howto write test.check custom generators

2014-08-10 Thread Timothy Washington
Hi there,

I'm trying to get my head wrapped around test.check
https://github.com/clojure/test.check/. My current stumbling block is
custom generators. Of course I've combed through the docs
https://github.com/clojure/test.check/blob/master/doc/intro.md#record-generators
and source
https://github.com/clojure/test.check/blob/master/src/main/clojure/clojure/test/check/generators.clj.
And I'm pretty sure I need to use *gen-bind* to get this all working. But
it's just not clicking yet.


Let's say I want to create a *user* and a *group*, where a user can belong
to many groups. So let's say I have a generic *create-user* function.

  (defn *create-user* [opts]
(merge {:id (mu/generate-uuid)
:username 
:password (crypto/base64 12)
:first-name 
:last-name 
:email 
:country {}}
   opts))


And a generic *create-group* function.

  (defn create [opts]
(merge {:id (mu/generate-uuid)
:name 
:users []}
   opts))




   1. Now, if I try `*(gen/sample create-user)*`, or `*(gen/sample
   (gen/vector du/create))*`it will fail.
   2. I also want to do the same thing with groups (ie *(gen/sample
   create-user)*).
   3. Additionally however, I want to assert that a created group will
   always have at least 1 user in the `*:users []*` k/v field.


How can I make test.check generators for these data structures?



Tim Washington
Interruptsoftware.com http://interruptsoftware.com

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


Re: Howto write test.check custom generators

2014-08-10 Thread Sam Ritchie

You can to use gen/fmap to build up generators. Here's an example:

;; generates a millisecond using gen/choose, then maps that to a time 
instance using my u/ms-to-time function.

(def result-gen
  (- (gen/choose 0 u/max-time)
   (gen/fmap u/ms-to-time)))

;; Generates EITHER a result or nil, then maps that into an event entry 
data structure:

(def event-entry-gen
  (- (gen/one-of [(gen/return nil) result-gen])
   (gen/fmap (fn [result]
   (merge {:_id id
   :_rev rev
   :type event-entry
   :division {:age-group U17
  :boat-type K1
  :gender male}
   :event-id event-id
   :regatta-id regatta-id
   :athletes []
   :racer-number 10}
  (when result
{:result {:division-size 10
  :rank {:overall 1
 :division 1}
  :time result}}))

Once you have a generator instance you can copy the rest of the 
test.check examples, run gen/sample on the generator directly... all the 
good stuff.



Timothy Washington mailto:twash...@gmail.com
August 10, 2014 at 12:38 PM
Hi there,

I'm trying to get my head wrapped around test.check 
https://github.com/clojure/test.check/. My current stumbling block 
is custom generators. Of course I've combed through the docs 
https://github.com/clojure/test.check/blob/master/doc/intro.md#record-generators 
and source 
https://github.com/clojure/test.check/blob/master/src/main/clojure/clojure/test/check/generators.clj. 
And I'm pretty sure I need to use */gen-bind/* to get this all 
working. But it's just not clicking yet.



Let's say I want to create a */user/* and a */group/*, where a user 
can belong to many groups. So let's say I have a generic 
*/create-user/* function.


  (defn */create-user/* [opts]
(merge {:id (mu/generate-uuid)
:username 
:password (crypto/base64 12)
:first-name 
:last-name 
:email 
:country {}}
   opts))


And a generic */create-group/* function.

  (defn create [opts]
(merge {:id (mu/generate-uuid)
:name 
:users []}
   opts))



 1. Now, if I try `*/(gen/sample create-user)/*`, or `*/(gen/sample
(gen/vector du/create))/*`it will fail.
 2. I also want to do the same thing with groups (ie /(gen/sample
create-user)/).
 3. Additionally however, I want to assert that a created group will
always have at least 1 user in the `*/:users []/*` k/v field.


How can I make test.check generators for these data structures?



Tim Washington
Interruptsoftware.com http://interruptsoftware.com


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

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

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


--
Sam Ritchie (@sritchie)
Paddleguru Co-Founder
703.863.8561
www.paddleguru.com http://www.paddleguru.com/
Twitter http://twitter.com/paddleguru// Facebook 
http://facebook.com/paddleguru


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

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


Re: Howto write test.check custom generators

2014-08-10 Thread Timothy Washington
Oook, this is starting to sink in.

I've gotten a little farther, in that I can run quick-check with my custom
generator. However, after a bunch of values had been generated, it fails on
a NullPointerException. How can I know where the breakdown is happening?

= (tc/quick-check 100 u/has-agroup)
{:email , :last-name , :first-name , :username }
{:email , :last-name , :first-name , :username 0}
{:email , :last-name , :first-name Rq, :username 0}
{:email 5D2, :last-name R4F, :first-name x, :username G0H}
...
{:email 8KQgSr497EPw14X80oEbWC0, :last-name cdkLb8D5ol, :first-name
8DCOXz1U4S3JM641u5I7yPwQ, :username DADOk}
{:email x, :last-name Qq3h07d6Cbs4, :first-name 6H6Enrwu, :username
yf40SClLjJHp1ptbnx4I9xFbwI3}
*NullPointerException   clojure.test.check.generators/gen-bind/fn--18990
(generators.clj:77)*
bkell.bkell (pst *e)
NullPointerException
clojure.test.check.generators/gen-bind/fn--18990 (generators.clj:77)
clojure.test.check.generators/gen-bind/fn--18990 (generators.clj:79)
clojure.test.check.generators/gen-bind/fn--18990 (generators.clj:77)
clojure.test.check.generators/gen-fmap/fn--18985 (generators.clj:70)
clojure.test.check.generators/call-gen (generators.clj:56)
clojure.test.check/quick-check (check.clj:57)
bkell.bkell/eval19267 (form-init7280611083923741467.clj:1)
clojure.lang.Compiler.eval (Compiler.java:6703)
clojure.lang.Compiler.eval (Compiler.java:)
clojure.core/eval (core.clj:2927)
clojure.main/repl/read-eval-print--6625/fn--6628 (main.clj:239)
clojure.main/repl/read-eval-print--6625 (main.clj:239)


This is my domain function:

  (defn *create-user*
([] (create {}))
([opts]
   (println opts)
   (let [sans-nils (apply merge (for [[k v]
  opts
  :when (not (nil? v))]
  {k v}))]

 (merge {:id (mu/generate-uuid)
 :username 
 :password (crypto/base64 12)
 :first-name 
 :last-name 
 :email 
 :country {}}
sans-nils


And these are my test functions.

  (def gend-user
(gen/fmap *du/create-user*
  (gen/hash-map :username gen/string-alpha-numeric
:first-name gen/string-alpha-numeric
:last-name gen/string-alpha-numeric
:email gen/string-alpha-numeric)))

  (def has-agroup
(prop/for-all [v (gen/sample gend-user)]
  (- v nil? not)))



Tim Washington
Interruptsoftware.com http://interruptsoftware.com


On Sun, Aug 10, 2014 at 3:02 PM, Sam Ritchie sritchi...@gmail.com wrote:

 You can to use gen/fmap to build up generators. Here's an example:



-- 
You received this 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: Advice on managing random number generators across threads

2014-06-07 Thread Alexander Hudek
Keep in mind that there could be accuracy reasons why you might want to use 
multiple random number generators (aka multiple streams). See the section 
Single Versus Multiple Streams here:

http://www.cse.msu.edu/~cse808/CSIM_Notes03/cse808/html_c/16random.htm

Also, the built in java random number generator is ok, but not 
state-of-the-art in terms of quality. A more popular high quality generator 
is the Mersenne twister. There are several java implementations available. 


On Friday, June 6, 2014 11:33:04 PM UTC-4, Mars0i wrote:

 Wow.  Linus, thanks for the very detailed answer.

 It sounds as your view is that there's no problem with the logic of my 
 proposed solution, but it seems wasteful to create 100 RNGs, when I don't 
 actually need to have so many of them.  Your solutions provide ways to get 
 the same result without maintaining so many RNG objects in a simulation 
 run.  Is that roughly correct?

 On Friday, June 6, 2014 2:26:25 PM UTC-5, Linus Ericsson wrote:

 (I think your stepwise problem is better to be solved without agents, see 
 below.)

 I realized that the *rng* actually is conflated, it keeps both the state 
 for the random number generator AND the algorithm used for the random 
 number generation. This is usually not a problem, since the state-size and 
 usage is dependent on the particular random number generator, but it 
 becomes a problem when we need to separate and multithread things 


 Interesting point.  OK.  But seem my comment below about sharing of code 
 between RNG objects.
  

 One solution would be to either re-implement the algorithm (by Knuth) 
 used in the original Sun Java random implementation, or use the 
 experimental library Four [1] by Gary Fredericks that does exactly this.


 Four looks very nice.  Its stateless RNGs return a new RNG, rather than an 
 RNG state, btw:
 (class (rs/java-random 1001))
 ;==  four.stateless.JavaRandom
 (map class (rs/next-long (rs/java-random 1001)))
 ;== (java.lang.Long four.stateless.JavaRandom)
  I can see how this might be useful, though.

 What you would like to do is to be able to feed the rng-algorithm with the 
 state (it is just a 64 bit long), and simply take the random-result 
 generated from it, and store the state in the agent together with the rest 
 of the simulation state.

 Dubious Speculations:
 This makes it necessary to know that the agents are called in the same 
 order (if the influence on each other). 


  

 Given the non-guarantee of ordering in the nature of Java Threads and how 
 agents rely on them I don't think you can expect your result to be 
 reproducible. 


 Right.  I can guarantee the order in which the random numbers are used 
 when I use map to cause each person to do its work, but I assume that I 
 can't guarantee this order when I use pmap.
  

 Here I assume that the incoming calls to agents aren't guaranteed to 
 strictly ordered among different agents, even though the agents reside in 
 one of two thread-pools (the send- vs. send-off pools). If two agents sent 
 messages that arrived a third agent in different order, the rng-state would 
 differ between the runs). Please correct me if I'm wrong on this one. 


 No, there's no issue about the order in which messages are received, I 
 believe.  Communication is effectively simultaneous, because all sending 
 happens in one step, and all receiving happens in another step.
  
 (Here are the details, if you're interested:  Each Person random chooses 
 other Persons to send a message to, and then randomly chooses a message to 
 send.  The pmap over the Persons ends, and all of the messages are 
 collected into a single hashmap.  Then a separate pmap goes through each 
 Person, applying the messages in the hashmap that are supposed to be sent 
 to that Person.  Thus, although Persons perform their work in some order, 
 the sending and the receiving of the messages are separated, so that 
 message sending and receipt occurs as if all messages were sent 
 simultaneously.  In the next timestep, the messages received by a Person 
 affect the probabilities that various messages will be chosen to send to 
 another Person.)
  

 A possible clever way around this could be to send the rng state together 
 with the message arriving at the agent, to make the agent at least react to 
 the state in a similar way. 


 Interesting idea.  I don't think I'll need this, though.
  

 If you have some kind of continous magnitudes in the simulation - like 
 pheromones - the simulation would maybe converge to similar results since 
 the interaction effects would be reproducible but this is indeed a very 
 far-fetched hypothesis.


 The simulation converges, but the same parameters can allow convergence to 
 different outcomes.  I usually have to run the simulation many times with 
 the same parameters so that I can get a frequency distribution over 
 outcomes.
  

 So only if your Person transform functions are commutative (ie gives the 
 same result whichever

Re: Advice on managing random number generators across threads

2014-06-07 Thread Mars0i
On Saturday, June 7, 2014 7:09:53 PM UTC-5, Alexander Hudek wrote:

 Keep in mind that there could be accuracy reasons why you might want to 
 use multiple random number generators (aka multiple streams). See the 
 section Single Versus Multiple Streams here:

 http://www.cse.msu.edu/~cse808/CSIM_Notes03/cse808/html_c/16random.htm


Very nice--thanks.  I had never heard of this issue, but it makes sense.  
 

 Also, the built in java random number generator is ok, but not 
 state-of-the-art in terms of quality. A more popular high quality generator 
 is the Mersenne twister. There are several java implementations available. 


That's what I thought, and I was leaning toward using a Mersenne twister.  
An additional advantage of sampling libraries like data.generators and 
bigml/sampling that allow one to specify the RNG is the ability to use a 
different RNG algorithm.

-- 
You received this 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.


Advice on managing random number generators across threads

2014-06-06 Thread Mars0i
I'm writing an agent-based simulation framework, in which agents are 
Clojure records called Persons.  There are 40-100 persons at present, but 
conceivably the number could go up to 1000.  In each timestep, Persons' 
states are functionally updated by mapping update functions across the 
collection of Persons.  The application is designed to be able to run in a 
single thread, or to be run in multiple threads, depending on whether I do 
the mapping using map or pmap.  (The application is generally faster with 
pmap (and all I had to do was add p), but I think there might be contexts 
in which single-threaded operation is preferable.)

At one point in the Person-update process, each Person randomly samples a 
small number (1 to 50) of elements from some small collections (size 10 up 
to the max number of persons).  When the application is multi-threaded, I'd 
rather not have separate threads accessing the same random number 
generator.  (Java 1.7 allows a way of dealing with that, but for now I'd 
rather be compatible with Java 1.6 as well.)

Does the following solution make sense?

1. During initialization, I'll get a random number generator from 
java.util.Random, initialized with the system time or something else that 
varies.

2. I'll give each person a field :rng, and will initialize each one with a 
sparate call to java.util.Random, with a seed determined by the RNG 
mentioned in the previous line.  (After this I can let the inititial RNG to 
be garbage collected.)

3. During the steps in which each Person needs to sample from collections, 
the code will get the RNG from the Person's :rng file, and use it to 
determine what elements are sampled.  

There is more than one way that I could implement step 3.  Here are some 
options I'm considering:
(a) Bind data.generators/*rnd* to the RNG, and then call functions in 
data.generators http://clojure.github.io/data.generators/.
(b) Pass the Person's RNG to functions from bigml/sampling 
https://github.com/bigmlcom/sampling (which allow you to pass in an RNG).
(c) Write my own sampling functions that use the RNG from the Person.

Further remarks:

When the application is single-threaded, each Person will use a different 
RNG, which isn't necessary, but it won't hurt, since the RNGs will have 
different seeds, except that I waste memory by creating multiple RNGs.  
When the application is multi-threaded, I still don't need one RNG per 
person, strictly speaking, since the number of threads will be much less 
than the number of Persons.  However, giving each Person its own RNG is 
simpler.  It means that my code can ignore  threads and let Clojure figure 
out how to manage them.


What do you think?  Thanks in advance for any 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: Advice on managing random number generators across threads

2014-06-06 Thread Mars0i
One more point:

I would save the system-time-determined seed of the initial RNG to a file 
(i.e. the RNG used to generate seeds for each Person's RNG).  I believe 
this will allow me to re-run a simulation with identical results, by 
seeding the initial RNG with the seed saved from the previous simulation 
run.  Let me know if this doesn't make sense.  Thanks.

-- 
You received this 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: Advice on managing random number generators across threads

2014-06-06 Thread Gunnar Völkel
In Java 7 you would use ThreadLocalRandom you said in another thread. Well, 
in Java 6 you already have ThreadLocal [1] and thus you are able to build a 
thread local Random yourself to keep Java 6 as minimum requirement.

[1] 
http://docs.oracle.com/javase/6/docs/api/index.html?java/lang/ThreadLocal.html

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


Re: Advice on managing random number generators across threads

2014-06-06 Thread Mars0i
On Friday, June 6, 2014 2:05:16 PM UTC-5, Gunnar Völkel wrote:

 In Java 7 you would use ThreadLocalRandom you said in another thread. 
 Well, in Java 6 you already have ThreadLocal [1] and thus you are able to 
 build a thread local Random yourself to keep Java 6 as minimum requirement.

 [1] 
 http://docs.oracle.com/javase/6/docs/api/index.html?java/lang/ThreadLocal.html


OK, that's good to know.  Great.  I may use that.  Thanks Gunnar.  

I still wonder whether the scheme I outlined would be a good strategy for 
preventing delays due to contention by different threads for the same RNG. 
  In my scheme, none of the RNGs would actually be local to threads.  Each 
would be globally accessible in principle, but no RNG would be accessed 
from more than one thread at a time.  (I like keeping things simple, but 
maybe I'm being simplistic.)

-- 
You received this 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: Advice on managing random number generators across threads

2014-06-06 Thread Linus Ericsson
(I think your stepwise problem is better to be solved without agents, see
below.)

I realized that the *rng* actually is conflated, it keeps both the state
for the random number generator AND the algorithm used for the random
number generation. This is usually not a problem, since the state-size and
usage is dependent on the particular random number generator, but it
becomes a problem when we need to separate and multithread things.

One solution would be to either re-implement the algorithm (by Knuth) used
in the original Sun Java random implementation, or use the experimental
library Four [1] by Gary Fredericks that does exactly this.

What you would like to do is to be able to feed the rng-algorithm with the
state (it is just a 64 bit long), and simply take the random-result
generated from it, and store the state in the agent together with the rest
of the simulation state.

Dubious Speculations:
This makes it necessary to know that the agents are called in the same
order (if the influence on each other). Given the non-guarantee of ordering
in the nature of Java Threads and how agents rely on them I don't think you
can expect your result to be reproducible. Here I assume that the incoming
calls to agents aren't guaranteed to strictly ordered among different
agents, even though the agents reside in one of two thread-pools (the send-
vs. send-off pools). If two agents sent messages that arrived a third agent
in different order, the rng-state would differ between the runs). Please
correct me if I'm wrong on this one. A possible clever way around this
could be to send the rng state together with the message arriving at the
agent, to make the agent at least react to the state in a similar way. If
you have some kind of continous magnitudes in the simulation - like
pheromones - the simulation would maybe converge to similar results since
the interaction effects would be reproducible but this is indeed a very
far-fetched hypothesis.

So only if your Person transform functions are commutative (ie gives the
same result whichever order they was called in every timestep) the
simulation could be reproducible by storing the local random generator seed
in each Person.

If it's just speed you are after, do use either the java 1.7
ThreadLocalRandom (at least try out if this really gives any performance
boost).

A naive ThreadLocalImplementation implementation of clojure.core/rand would
be:

(defn rand
  Returns a random floating point number between 0 (inclusive) and
  n (default 1) (exclusive).
  {:added 1.0
   :static true}
*  ([] (.nextDouble (java.util.concurrent.ThreadLocalRandom/current)))*
  ([n] (* n (rand

but as you can see in the source code, random integers are generated using
a call to (rand), multiplied with the integer and floored (when converting
to int), so there are ways to get an limited range int more efficiently
(check the source code for java.util.Random, which makes various tricks for
getting just enough random bits out.

As always, measure performance (Hugo Duncans Criterium,
criterium.core/bench is a really good start). Numerical double operations
are cheap, memory accesses - in this case to resulting data structures or
other agents and likely context switches - could as well be the more
expensive part.

BTW: It looks like the problem you want to solve would benefit much from
being formulated as a two-step problem, one where you applied all the
incoming calls to each Person, and another where you sorted the messages to
each Person in some reproducible order, like

* = has an incoming message

initial state: Person A will hit Person B, just for the lulz.

apply map: A* B C
resulting actions sorted by Receiver: [A hits B]
apply these: A B* C
[B gets mad and throw raspberry pies at both A and C]
A* B C*
[A yells at B, C yells at B] - mind the ordering! Always apply A's action
before Cs (or let B's random seed shuffle a sorted ordering of the same to
avoid ordering biases and make it reproducible)
A B* C
[B sends a stern look to A and C]
no further actions

If you makes the message passing explicit instead of
Java-thread-call-uncertain-implicit (which IS possible and parallelizeable
in a stepwise simulation!) you can still parallelize it in many ways (for
example with reducers) and at the same time make simulations reproducible,
and you'll avoid a lot (N²) of potentially expensive context switching.

/Linus - take everything I say with a sand-pile avalanche of salt-grains.

[1] https://github.com/fredericksgary/four


2014-06-06 18:37 GMT+02:00 Mars0i marsh...@logical.net:

 One more point:

 I would save the system-time-determined seed of the initial RNG to a file
 (i.e. the RNG used to generate seeds for each Person's RNG).  I believe
 this will allow me to re-run a simulation with identical results, by
 seeding the initial RNG with the seed saved from the previous simulation
 run.  Let me know if this doesn't make sense.  Thanks.

 --
 You received this message because you are subscribed to 

Re: Advice on managing random number generators across threads

2014-06-06 Thread Lee Spector

I don't know if this will be helpful in your application, or even if it's the 
best approach for our own work (or if java 1.7 provides a simpler approach?), 
but FWIW one of my projects deals with the thread-local RNG issue via: 
https://clojars.org/clj-random

 -Lee

On Jun 6, 2014, at 12:28 PM, Mars0i marsh...@logical.net wrote:

 I'm writing an agent-based simulation framework, in which agents are Clojure 
 records called Persons.  There are 40-100 persons at present, but conceivably 
 the number could go up to 1000.  In each timestep, Persons' states are 
 functionally updated by mapping update functions across the collection of 
 Persons.  The application is designed to be able to run in a single thread, 
 or to be run in multiple threads, depending on whether I do the mapping using 
 map or pmap.  (The application is generally faster with pmap (and all I had 
 to do was add p), but I think there might be contexts in which 
 single-threaded operation is preferable.)
 
 At one point in the Person-update process, each Person randomly samples a 
 small number (1 to 50) of elements from some small collections (size 10 up to 
 the max number of persons).  When the application is multi-threaded, I'd 
 rather not have separate threads accessing the same random number generator.  
 (Java 1.7 allows a way of dealing with that, but for now I'd rather be 
 compatible with Java 1.6 as well.)
 
 Does the following solution make sense?
 
 1. During initialization, I'll get a random number generator from 
 java.util.Random, initialized with the system time or something else that 
 varies.
 
 2. I'll give each person a field :rng, and will initialize each one with a 
 sparate call to java.util.Random, with a seed determined by the RNG mentioned 
 in the previous line.  (After this I can let the inititial RNG to be garbage 
 collected.)
 
 3. During the steps in which each Person needs to sample from collections, 
 the code will get the RNG from the Person's :rng file, and use it to 
 determine what elements are sampled.  
 
 There is more than one way that I could implement step 3.  Here are some 
 options I'm considering:
 (a) Bind data.generators/*rnd* to the RNG, and then call functions in 
 data.generators.
 (b) Pass the Person's RNG to functions from bigml/sampling (which allow you 
 to pass in an RNG).
 (c) Write my own sampling functions that use the RNG from the Person.
 
 Further remarks:
 
 When the application is single-threaded, each Person will use a different 
 RNG, which isn't necessary, but it won't hurt, since the RNGs will have 
 different seeds, except that I waste memory by creating multiple RNGs.  When 
 the application is multi-threaded, I still don't need one RNG per person, 
 strictly speaking, since the number of threads will be much less than the 
 number of Persons.  However, giving each Person its own RNG is simpler.  It 
 means that my code can ignore  threads and let Clojure figure out how to 
 manage them.
 
 
 What do you think?  Thanks in advance for any 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: [ANN] clj-generators - generator magic inspired by Python

2014-06-06 Thread Alex Engelberg
Gary, I fully acknowledge that there are many ways to create lazy sequences 
that are much more elegant and efficient. However, as I mentioned, I'm very 
fascinated by generators in Python, and I mostly wanted to toy around with 
how to implement it in Clojure. Also, as I mentioned, for beginners who are 
not well-versed in Clojure laziness, it's easy to use generators in 
combination with the loop macro (or other more imperative macros) for a 
lazy but still functional-ish sequence. However, I'm probably not going to 
use this library for any of my own projects. :-)

Thanks for the comments.
--Alex

On Wednesday, June 4, 2014 8:50:21 AM UTC-7, tbc++ wrote:

 A little known fact is that the guts of the go macro are quite flexible. 
 We use this in the test framework:


 https://github.com/clojure/core.async/blob/master/src/test/clojure/clojure/core/async/ioc_macros_test.clj#L17

 I also spent some time once and created a yield like macro:


 https://github.com/halgari/async-bench/blob/master/src/async_bench/core.clj#L64

 WARNING: this uses unpublished APIs from core.async, use at your own risk. 

 Timothy


 On Wed, Jun 4, 2014 at 9:43 AM, Gary Johnson gwjo...@uvm.edu 
 javascript: wrote:

 What new features does this syntax provide over the existing infinite 
 sequence generators?

 - lazy-seq
 - iterate
 - repeat
 - repeatedly
 - range

 I realize you provided a simple example for clarity, but perhaps you 
 could illustrate something more complex that couldn't be done with the 
 above functions easily. For example, the case you provided could be written 
 as follows:

 (take 5 (iterate inc 1))

   Thanks,
 ~Gary

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




 -- 
 “One of the main causes of the fall of the Roman Empire was that–lacking 
 zero–they had no way to indicate successful termination of their C 
 programs.”
 (Robert Firth) 


-- 
You received this 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] clj-generators - generator magic inspired by Python

2014-06-06 Thread Gary Johnson
Gotcha. By all means then, hack away. ;-)

-- 
You received this 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: Advice on managing random number generators across threads

2014-06-06 Thread Mars0i
Thanks Lee.  It looks like this could be useful.

On Friday, June 6, 2014 4:19:11 PM UTC-5, Lee wrote:


 I don't know if this will be helpful in your application, or even if it's 
 the best approach for our own work (or if java 1.7 provides a simpler 
 approach?), but FWIW one of my projects deals with the thread-local RNG 
 issue via: https://clojars.org/clj-random 

  -Lee 


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


Re: Advice on managing random number generators across threads

2014-06-06 Thread Mars0i
Wow.  Linus, thanks for the very detailed answer.

It sounds as your view is that there's no problem with the logic of my 
proposed solution, but it seems wasteful to create 100 RNGs, when I don't 
actually need to have so many of them.  Your solutions provide ways to get 
the same result without maintaining so many RNG objects in a simulation 
run.  Is that roughly correct?

On Friday, June 6, 2014 2:26:25 PM UTC-5, Linus Ericsson wrote:

 (I think your stepwise problem is better to be solved without agents, see 
 below.)

 I realized that the *rng* actually is conflated, it keeps both the state 
 for the random number generator AND the algorithm used for the random 
 number generation. This is usually not a problem, since the state-size and 
 usage is dependent on the particular random number generator, but it 
 becomes a problem when we need to separate and multithread things 


Interesting point.  OK.  But seem my comment below about sharing of code 
between RNG objects.
 

 One solution would be to either re-implement the algorithm (by Knuth) used 
 in the original Sun Java random implementation, or use the experimental 
 library Four [1] by Gary Fredericks that does exactly this.


Four looks very nice.  Its stateless RNGs return a new RNG, rather than an 
RNG state, btw:
(class (rs/java-random 1001))
;==  four.stateless.JavaRandom
(map class (rs/next-long (rs/java-random 1001)))
;== (java.lang.Long four.stateless.JavaRandom)
 I can see how this might be useful, though.

What you would like to do is to be able to feed the rng-algorithm with the 
 state (it is just a 64 bit long), and simply take the random-result 
 generated from it, and store the state in the agent together with the rest 
 of the simulation state.

 Dubious Speculations:
 This makes it necessary to know that the agents are called in the same 
 order (if the influence on each other). 


 

 Given the non-guarantee of ordering in the nature of Java Threads and how 
 agents rely on them I don't think you can expect your result to be 
 reproducible. 


Right.  I can guarantee the order in which the random numbers are used when 
I use map to cause each person to do its work, but I assume that I can't 
guarantee this order when I use pmap.
 

 Here I assume that the incoming calls to agents aren't guaranteed to 
 strictly ordered among different agents, even though the agents reside in 
 one of two thread-pools (the send- vs. send-off pools). If two agents sent 
 messages that arrived a third agent in different order, the rng-state would 
 differ between the runs). Please correct me if I'm wrong on this one. 


No, there's no issue about the order in which messages are received, I 
believe.  Communication is effectively simultaneous, because all sending 
happens in one step, and all receiving happens in another step.
 
(Here are the details, if you're interested:  Each Person random chooses 
other Persons to send a message to, and then randomly chooses a message to 
send.  The pmap over the Persons ends, and all of the messages are 
collected into a single hashmap.  Then a separate pmap goes through each 
Person, applying the messages in the hashmap that are supposed to be sent 
to that Person.  Thus, although Persons perform their work in some order, 
the sending and the receiving of the messages are separated, so that 
message sending and receipt occurs as if all messages were sent 
simultaneously.  In the next timestep, the messages received by a Person 
affect the probabilities that various messages will be chosen to send to 
another Person.)
 

 A possible clever way around this could be to send the rng state together 
 with the message arriving at the agent, to make the agent at least react to 
 the state in a similar way. 


Interesting idea.  I don't think I'll need this, though.
 

 If you have some kind of continous magnitudes in the simulation - like 
 pheromones - the simulation would maybe converge to similar results since 
 the interaction effects would be reproducible but this is indeed a very 
 far-fetched hypothesis.


The simulation converges, but the same parameters can allow convergence to 
different outcomes.  I usually have to run the simulation many times with 
the same parameters so that I can get a frequency distribution over 
outcomes.
 

 So only if your Person transform functions are commutative (ie gives the 
 same result whichever order they was called in every timestep) the 
 simulation could be reproducible by storing the local random generator seed 
 in each Person.


I see.  I think I understand now.  If I store the state and not the RNG 
code, but I am able to pass the state into the RNG code, that's all that I 
need to store in each Person.  I think the idea is that this would do the 
same work as in my proposal, but with less storage.

But wouldn't the RNG code be shared between RNG objects anyway?  For 
example, don't all java.util.Random objects share the same code, differing 
only in that they 

Re: Advice on managing random number generators across threads

2014-06-06 Thread Mars0i


On Friday, June 6, 2014 10:33:04 PM UTC-5, Mars0i wrote:

 On Friday, June 6, 2014 2:26:25 PM UTC-5, Linus Ericsson wrote:

 Here I assume that the incoming calls to agents aren't guaranteed to 
 strictly ordered among different agents, even though the agents reside in 
 one of two thread-pools (the send- vs. send-off pools). If two agents sent 
 messages that arrived a third agent in different order, the rng-state would 
 differ between the runs). Please correct me if I'm wrong on this one. 


 No, there's no issue about the order in which messages are received, I 
 believe.  Communication is effectively simultaneous, because all sending 
 happens in one step, and all receiving happens in another step.
  
 (Here are the details, if you're interested:  Each Person random chooses 
 other Persons to send a message to, and then randomly chooses a message to 
 send.  The pmap over the Persons ends, and all of the messages are 
 collected into a single hashmap.  Then a separate pmap goes through each 
 Person, applying the messages in the hashmap that are supposed to be sent 
 to that Person.  Thus, although Persons perform their work in some order, 
 the sending and the receiving of the messages are separated, so that 
 message sending and receipt occurs as if all messages were sent 
 simultaneously.  In the next timestep, the messages received by a Person 
 affect the probabilities that various messages will be chosen to send to 
 another Person.) 


One more point about the detailed description: The immediate effects of 
messages on a Person who receives them are commutative (literally: they are 
additions).  Nothing else happens until all of the immediate effects of all 
messages are applied.

-- 
You received this 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] clj-generators - generator magic inspired by Python

2014-06-04 Thread Gary Johnson
What new features does this syntax provide over the existing infinite 
sequence generators?

- lazy-seq
- iterate
- repeat
- repeatedly
- range

I realize you provided a simple example for clarity, but perhaps you could 
illustrate something more complex that couldn't be done with the above 
functions easily. For example, the case you provided could be written as 
follows:

(take 5 (iterate inc 1))

  Thanks,
~Gary

-- 
You received this 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] clj-generators - generator magic inspired by Python

2014-06-04 Thread Timothy Baldridge
A little known fact is that the guts of the go macro are quite flexible. We
use this in the test framework:

https://github.com/clojure/core.async/blob/master/src/test/clojure/clojure/core/async/ioc_macros_test.clj#L17

I also spent some time once and created a yield like macro:

https://github.com/halgari/async-bench/blob/master/src/async_bench/core.clj#L64

WARNING: this uses unpublished APIs from core.async, use at your own risk.

Timothy


On Wed, Jun 4, 2014 at 9:43 AM, Gary Johnson gwjoh...@uvm.edu wrote:

 What new features does this syntax provide over the existing infinite
 sequence generators?

 - lazy-seq
 - iterate
 - repeat
 - repeatedly
 - range

 I realize you provided a simple example for clarity, but perhaps you could
 illustrate something more complex that couldn't be done with the above
 functions easily. For example, the case you provided could be written as
 follows:

 (take 5 (iterate inc 1))

   Thanks,
 ~Gary

 --
 You received this 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.




-- 
“One of the main causes of the fall of the Roman Empire was that–lacking
zero–they had no way to indicate successful termination of their C
programs.”
(Robert Firth)

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


[ANN] clj-generators - generator magic inspired by Python

2014-06-03 Thread Alex Engelberg
https://github.com/aengelberg/clj-generators

My all-time favorite feature of Python is generators. It allows you to 
write lazy sequences imperatively.

def infinite_range():
x = 1
while True:
yield x
x += 1
for i in infinite_range():
if (i  5):
break
else:
print(i)
= 1 2 3 4 5

This feature is so amazing and powerful, a common practice of mine is to 
ponder how to implement such magic in other languages. Python implements 
this feature using virtual stacks to suspend the computation in memory. 
Most languages don't have a similar way to pause a computation like that, 
short of manipulating entire threads, which gets messy quickly. However, 
when core.async came out for Clojure, I realized that the go-blocks can in 
fact pause in a lightweight way (because they park as they read/write), 
so it came to mind as a possible candidate for a Python generator 
implementation. The infinite_range example above would translate to the 
following Clojure code:

(defn infinite-range []
  (generator
(loop [x 1]
  (yield x)
  (recur (inc x)

(take 5 (infinite-range))
= (1 2 3 4 5)

I realize this is a bit more imperative than most Clojure programmers would 
like. However, the addition of generators allows functional macros like 
loop to create lazy sequences (like in the example above), which it 
previously was unable to do.

Check out the github site https://github.com/aengelberg/clj-generators 
for more details. It's relatively slow and inefficient but serves as a 
proof-of-concept. Enjoy!

-- 
You received this 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: generators...?

2014-03-27 Thread Tim
I'm fairly new to Clojure and this was a fun little exercise to try.

(def color-map (reduce #(assoc % (count %) %2) {} [:red :yellow :blue 
:green :purple]))

color-map
= {4 :purple, 3 :green, 2 :blue, 1 :yellow, 0 :red}

(defn random-repeating-map
  ([coll-map] (random-repeating-map coll-map coll-map))
  ([coll-map new-coll-map]
   (if (seq new-coll-map)
 (let [ key-vec (into [] (keys new-coll-map))
idx-key (key-vec (rand-int (count key-vec)))]
   (cons (new-coll-map idx-key)
   (lazy-seq (random-repeating-map coll-map (dissoc new-coll-map 
idx-key) (random-repeating-map coll-map

(take 20 (random-repeating-map color-map))
= (:blue :purple :yellow :red :green :purple :blue :red :yellow :green 
:red :purple :yellow :green :blue :green :blue :yellow :red :purple)

Step 4: Profit

On Wednesday, March 26, 2014 1:10:12 PM UTC-7, Gary Trakhman wrote:

 true, he did say 'or something that would be as useful', but lazy-seqs 
 are more useful :-).


 On Wed, Mar 26, 2014 at 4:08 PM, Ben Wolfson wol...@gmail.comjavascript:
  wrote:

 cycle isn't really the same thing, though, at least if the OP really 
 does require (for some reason) something that can be called repeatedly and 
 get a different answer each time.
  

 On Wed, Mar 26, 2014 at 1:05 PM, Gary Trakhman 
 gary.t...@gmail.comjavascript:
  wrote:

 cycle - http://clojuredocs.org/clojure_core/clojure.core/cycle

 And generally, this class of functionality is called lazy-seqs.


 On Wed, Mar 26, 2014 at 3:59 PM, Christopher Howard 
 cmho...@alaska.edujavascript:
  wrote:

 Hi. I'm still fairly new to Clojure. I was wondering: What's the
 easiest way to make a generator (or something that would be as useful).
 In one application, I need something that will return a different color
 each time I call it - following a predefined list of colors, and
 starting over again at the beginning when colors are exhausted.

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


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




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

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




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

generators...?

2014-03-26 Thread Christopher Howard
Hi. I'm still fairly new to Clojure. I was wondering: What's the
easiest way to make a generator (or something that would be as useful).
In one application, I need something that will return a different color
each time I call it - following a predefined list of colors, and
starting over again at the beginning when colors are exhausted.

-- 
You received this 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: generators...?

2014-03-26 Thread Gary Trakhman
cycle - http://clojuredocs.org/clojure_core/clojure.core/cycle

And generally, this class of functionality is called lazy-seqs.


On Wed, Mar 26, 2014 at 3:59 PM, Christopher Howard cmhowa...@alaska.eduwrote:

 Hi. I'm still fairly new to Clojure. I was wondering: What's the
 easiest way to make a generator (or something that would be as useful).
 In one application, I need something that will return a different color
 each time I call it - following a predefined list of colors, and
 starting over again at the beginning when colors are exhausted.

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


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


Re: generators...?

2014-03-26 Thread Ben Wolfson
If you really want something that can be called repeatedly and returns
something different each time (rather than just iterating through an
infinite sequence, which seems like it would be the more functional-ish
approach):

user (defn cycle-gen [input]
(let [iter (atom (cycle input))]
  (fn [] (let [v (first @iter)]
   (swap! iter rest)
   v
#'user/cycle-gen
user (def colors (cycle-gen '(red green blue)))
#'user/colors
user (colors)
red
user (colors)
green
user (colors)
blue
user (colors)
red
user (colors)
green
user (colors)
blue



On Wed, Mar 26, 2014 at 12:59 PM, Christopher Howard
cmhowa...@alaska.eduwrote:

 Hi. I'm still fairly new to Clojure. I was wondering: What's the
 easiest way to make a generator (or something that would be as useful).
 In one application, I need something that will return a different color
 each time I call it - following a predefined list of colors, and
 starting over again at the beginning when colors are exhausted.

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




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

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


Re: generators...?

2014-03-26 Thread Ben Wolfson
cycle isn't really the same thing, though, at least if the OP really does
require (for some reason) something that can be called repeatedly and get a
different answer each time.


On Wed, Mar 26, 2014 at 1:05 PM, Gary Trakhman gary.trakh...@gmail.comwrote:

 cycle - http://clojuredocs.org/clojure_core/clojure.core/cycle

 And generally, this class of functionality is called lazy-seqs.


 On Wed, Mar 26, 2014 at 3:59 PM, Christopher Howard 
 cmhowa...@alaska.eduwrote:

 Hi. I'm still fairly new to Clojure. I was wondering: What's the
 easiest way to make a generator (or something that would be as useful).
 In one application, I need something that will return a different color
 each time I call it - following a predefined list of colors, and
 starting over again at the beginning when colors are exhausted.

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


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




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

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


Re: generators...?

2014-03-26 Thread Gary Trakhman
true, he did say 'or something that would be as useful', but lazy-seqs are
more useful :-).


On Wed, Mar 26, 2014 at 4:08 PM, Ben Wolfson wolf...@gmail.com wrote:

 cycle isn't really the same thing, though, at least if the OP really
 does require (for some reason) something that can be called repeatedly and
 get a different answer each time.


 On Wed, Mar 26, 2014 at 1:05 PM, Gary Trakhman gary.trakh...@gmail.comwrote:

 cycle - http://clojuredocs.org/clojure_core/clojure.core/cycle

 And generally, this class of functionality is called lazy-seqs.


 On Wed, Mar 26, 2014 at 3:59 PM, Christopher Howard cmhowa...@alaska.edu
  wrote:

 Hi. I'm still fairly new to Clojure. I was wondering: What's the
 easiest way to make a generator (or something that would be as useful).
 In one application, I need something that will return a different color
 each time I call it - following a predefined list of colors, and
 starting over again at the beginning when colors are exhausted.

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


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




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

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


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


avoiding generators

2013-10-14 Thread Brian Craft
I need to pull sequence ids from a db, which is a lot like using a 
generator. I found this thread about generators:

https://groups.google.com/forum/?fromgroups=#!searchin/clojure/generator/clojure/IL_ONPb52-0/S_2p2-vjVCYJ

which suggests using seqs, like so:

(defn sines [] 
   (cycle (map #(Math/sin %) (range 0 6.28 0.01 

(doseq [s (take num-iters (sines))] 
  (println s)) 

However my case is more complex, because there's not a single call (like 
doseq, above) consuming the seq. I'm processing structured data, and need 
to get ids for the leaf nodes. So it looks more like

(defn process-row [row]
  (map #(process-value (get-id) %) row))

(map process-row rows)

That is, process-row gets called multiple times, and needs to retrieve ids. 
If I pass in a seq of ids, I'll get the same ids each time. If I try to 
work around this by, say, have process-row return the number of ids 
consumed, and doing a drop n when calling process-row the next time, I'm 
holding the seq head (which I can't afford).

Is there some other way to do this?


-- 
-- 
You received this 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.