Oh okay. So if a value given to gen/return function is coming via a
generator will shrink because that generator will shrink.
But say (gen/return [1 2 3 4]) will never shrink because it is saying just
return it as it is and never shrink this.
Got it! :)

On Fri, Aug 14, 2015 at 10:34 PM, Carlo Zancanaro <carlozancan...@gmail.com>
wrote:

> What it means is that the value returned by gen/return can't be shrunk.
>
> Shrinking is done by constructing a (lazily evaluated) tree of "smaller"
> forms of the same thing. So a number, let's say 4, contains a tree of
> smaller numbers (0, 1, 2, and 3) which specify how to shrink it. (The tree
> is constructed in an intelligent way to make shrinking more efficient than
> "try everything".) When you use gen/return you don't have any of that
> context, so the returned value cannot be shrunk.
>
> This situation is a bit more complex when you use gen/bind, though,
> because the result of the gen/bind call "inherits" a shrink tree from the
> generator given to gen/bind. That's why my function can shrink despite
> using gen/return for its final value. The gen/return isn't shrinking, but
> the gen/bind is.
>
> Carlo
>
> On 15 August 2015 at 02:49, Mayank Jain <firesof...@gmail.com> wrote:
>
>> Ah right! I knew I had to use gen/choose for this,
>> I am still grokking bind :)
>>
>> Thanks for your help!
>> That indeed did the trick for me :)
>>
>> One thing I am clear about is,
>> If I use gen/return it says it'll not shrink.
>> Does that mean when a test fails for a certain order, it won't try to
>> shrink that order of collection?
>> Because I have used a gen/return at the end of the generator?
>>
>> Thanks again for your help! :)
>>
>> On Fri, Aug 14, 2015 at 8:13 PM, Carlo Zancanaro <
>> carlozancan...@gmail.com> wrote:
>>
>>> Hey Mayank!
>>>
>>> Similarly to your attempt last time, you need to use gen/bind to get
>>> the result of a generator which you can then use to make a new generator.
>>>
>>> (defn- rand-interleave* [coll acc]
>>>   (if (seq coll)
>>>     (gen/bind (gen/choose 0 (dec (count coll)))
>>>               (fn [index]
>>>                 (let [value (first (get coll index))
>>>                       coll (->> (update-in coll [index] next)
>>>                                 (remove empty?)
>>>                                 vec)]
>>>                   (rand-interleave* coll (conj acc value)))))
>>>     (gen/return acc)))
>>>
>>> (defn rand-interleave [& colls]
>>>   (rand-interleave* (vec colls) []))
>>>
>>> The (gen/choose 0 (dec (count coll))) is similar to your rand-count
>>> function, then the generated number is passed to the function as result.
>>> Writing it this way will shrink towards the (apply concat args) (ie. as
>>> it shrinks it will move towards just concatenating the arguments).
>>>
>>> In terms of the recursion: this will eventually overflow the stack. I
>>> don't know of a way to trampoline generators, so I don't know how to avoid
>>> that. (This is a bit of a recurring problem with monadic code in Clojure, I
>>> feel, as algo.monads had a similar problem last time I checked.) For the
>>> moment I'm just ignoring this theoretical problem until it becomes a
>>> practical problem.
>>>
>>> I hope that helps!
>>>
>>> Carlo
>>>
>>> On 14 August 2015 at 23:39, Mayank Jain <firesof...@gmail.com> wrote:
>>>
>>>> Hi Everyone,
>>>>
>>>> Here's the problem I am facing,
>>>> I need to write a generator which takes any number of sequences,
>>>> interleaves them but maintains the order within each sequence.
>>>> Assume each sequence has at least one element.
>>>>
>>>> For example:
>>>>
>>>> (rand-interleave [1 2 3 4] [:a :b] [:A :B :C :D :E])
>>>>> => [:a 1 2 :b :A :B :C 3 :D 4 :E]
>>>>
>>>>
>>>> (rand-interleave [1 2 3 4])
>>>>> => [1 2 3 4]
>>>>
>>>>
>>>> (rand-interleave [1])
>>>>> => [1]
>>>>
>>>>
>>>> (rand-interleave [1] [:a] [:A])
>>>>> => [:a 1 :A]
>>>>
>>>>
>>>> I have been able to write this down as clojure functions.
>>>> But I am unable to convert this into a test.check generator.
>>>>
>>>> Specifically:
>>>>
>>>>    - How to pass random index count without using rand-int i.e. use
>>>>    gen/choose
>>>>    - How do I write recursive functions which play well with test.check
>>>>
>>>> Here's my take on it (without the generators).
>>>>
>>>> (defn- first-nth
>>>>>   "(first-nth [[1 2 3 4] [:a :b :c :d]]
>>>>>                   1)
>>>>>    => :a"
>>>>>   [coll n]
>>>>>   (first (nth coll n)))
>>>>
>>>>
>>>>
>>>> (defn- next-nth
>>>>>   "(next-nth [[1 2 3 4] [:a :b :c :d]]
>>>>>                   1)
>>>>>    => [[1 2 3 4] (:b :c :d)]"
>>>>>   [coll n]
>>>>>   (->> n
>>>>>        (nth coll)
>>>>>        next
>>>>>        (assoc coll n)
>>>>>        (remove nil?)
>>>>>        vec))
>>>>
>>>>
>>>>
>>>> (defn- rand-count
>>>>>   [coll]
>>>>>   (rand-int (count coll)))
>>>>
>>>>
>>>>
>>>> (defn- rand-interleave*
>>>>>   [coll acc]
>>>>>   (let [n (rand-count coll)]
>>>>>     (if (not-empty coll)
>>>>>       (rand-interleave* (next-nth coll n)
>>>>>                                   (conj acc
>>>>>                                           (first-nth coll n)))
>>>>>       acc)))
>>>>
>>>>
>>>>
>>>> (defn rand-interleave
>>>>>   [& args]
>>>>>   ;; Make args a vector as I would like to
>>>>>   ;; look up elements by their index values.
>>>>>   (rand-interleave* (vec args) []))
>>>>
>>>>
>>>> Looking forward to any suggestions on how to solve it :)
>>>>
>>>> Thanks,
>>>> Mayank.
>>>>
>>>> --
>>>> You received this message because you are subscribed to the Google
>>>> Groups "Clojure" group.
>>>> To post to this group, send email to clojure@googlegroups.com
>>>> Note that posts from new members are moderated - please be patient with
>>>> your first post.
>>>> To unsubscribe from this group, send email to
>>>> clojure+unsubscr...@googlegroups.com
>>>> For more options, visit this group at
>>>> http://groups.google.com/group/clojure?hl=en
>>>> ---
>>>> You received this message because you are subscribed to the Google
>>>> Groups "Clojure" group.
>>>> To unsubscribe from this group and stop receiving emails from it, send
>>>> an email to clojure+unsubscr...@googlegroups.com.
>>>> For more options, visit https://groups.google.com/d/optout.
>>>>
>>>
>>> --
>>> You received this message because you are subscribed to the Google
>>> Groups "Clojure" group.
>>> To post to this group, send email to clojure@googlegroups.com
>>> Note that posts from new members are moderated - please be patient with
>>> your first post.
>>> To unsubscribe from this group, send email to
>>> clojure+unsubscr...@googlegroups.com
>>> For more options, visit this group at
>>> http://groups.google.com/group/clojure?hl=en
>>> ---
>>> You received this message because you are subscribed to the Google
>>> Groups "Clojure" group.
>>> To unsubscribe from this group and stop receiving emails from it, send
>>> an email to clojure+unsubscr...@googlegroups.com.
>>> For more options, visit https://groups.google.com/d/optout.
>>>
>>
>> --
>> You received this message because you are subscribed to the Google
>> Groups "Clojure" group.
>> To post to this group, send email to clojure@googlegroups.com
>> Note that posts from new members are moderated - please be patient with
>> your first post.
>> To unsubscribe from this group, send email to
>> clojure+unsubscr...@googlegroups.com
>> For more options, visit this group at
>> http://groups.google.com/group/clojure?hl=en
>> ---
>> You received this message because you are subscribed to the Google Groups
>> "Clojure" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to clojure+unsubscr...@googlegroups.com.
>> For more options, visit https://groups.google.com/d/optout.
>>
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
> ---
> You received this message because you are subscribed to the Google Groups
> "Clojure" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to clojure+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

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

Reply via email to