Re: spec with schema and select?

2019-03-08 Thread Rob Nikander
Thanks, I will do that. 

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


spec with schema and select?

2019-03-07 Thread Rob Nikander
Hi,

I just watched a chunk of this talk from a few months ago ("Maybe Not" 
[1]). Is there a pre-release version of spec available, that has `schema` 
and `select` in it? I have a project where I'm fine with using bleeding 
edge stuff that will change.

Rob

[1]: https://www.youtube.com/watch?v=YR5WdGrpoug

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

2018-03-23 Thread Rob Nikander


On Friday, March 23, 2018 at 4:26:37 PM UTC-4, Andy Fingerhut wrote:
>
> I do not know what the result of that discussion was, but I would guess it 
> did not turn into a change that was incorporated into Clojure.  In the 
> discussion thread you linked to, Dave Griffith mentioned attaching a patch 
> "to the group".  I am pretty sure file attachments to Google groups went 
> away several years ago, but the file attached to this message might be the 
> one that Dave Griffith was referring to.  Looking at the latest Clojure 
> code and that patch should make it clear whether the patch was applied or 
> not.
>

Thanks. I just compared the code, and it looks like you guessed right; it 
was not 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.


Coordinating STM with database?

2018-03-23 Thread Rob Nikander
Hi,

I see this was discussed before. Did it go anywhere? Basic idea: make a 
`dosync` transaction succeed or fail along with a database transaction.

https://groups.google.com/forum/#!topic/clojure/qiKnCVAaZKw

Rob

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

2018-03-02 Thread Rob Nikander


On Friday, March 2, 2018 at 12:48:28 AM UTC-5, Daniel wrote:
>
> How do you know this code is causing the error? Unless this is all your 
> code does, descriptions of the error suggest the memory leak might be 
> coming from anywhere. This tight loop might trigger too many successive GCs 
> though: have you observed if the error only occurs under load, or under 
> large time intervals? Some combination?
>

Okay, thanks for looking it over. This is a single-threaded, short lived 
script, so this is the only thing happening. But it's possible there is an 
unexpected large result set. I'll look into that. It may be smarter to use 
`limit N` in my SQL, rather than the time range.

>

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


Loop causing OutOfMemoryError: GC overhead limit exceeded ?

2018-03-01 Thread Rob Nikander


I have some Clojure code that throws this, occasionally. Unfortunately I 
can’t paste my real function here, but it looks much like the one below. 
(Changed variable names and simplified some irrelevant - I hope - details). 
Anything jump out as a memory-leak? 


It queries a DB table to get a list of records. For performance reasons, it 
runs multiple smaller queries by time period (min-t, max-t), and furthering 
breaks the results into chunks, as it accumulates the final vector 
`records`.


I thought each loop/recur would drop the data from the previous loop 
iteration. But maybe not?


  (defn find-db-records [db min-time max-time]

(let [records (atom [])

  num-processed (atom 0)]

  (loop [min-t min-time]

(let [max-t (plus-minutes min-t 30) ;; 30 minutes at a time

  results (jdbc/query db

 ["select id, a, b, c from sometable where t > ? 
and t <= ? order by t" 

   min-t max-t])

  row-groups (partition-all 200 results)]

  (doseq [rows row-groups :let [foo (make-foo rows)]]

(doseq [{:keys [id a b c] :as row} rows]

  (if (relevant-record? foo a b)

(let [d (compute-d a b c)]

  (swap! records conj {:id id :a a :d d})))

  (swap! num-processed inc)))

  (if (before? max-t max-time)

(recur max-t)

{:records @records :num-processed @num-processed})


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

2018-01-06 Thread Rob Nikander

On Jan 5, 2018, at 8:01 PM, Gary Verhaegen  wrote:

> What about simply having the producer put items one by one on the channel?


I will do that. My current producer is doing too many other things, but if 
I break it up into separate threads or go blocks for each work queue, then 
that should work. Thank you.
 

On Saturday, January 6, 2018 at 8:22:34 AM UTC-5, Brian J. Rubinton wrote:
>
> I think the behavior in our examples differ because the blocking puts will 
> complete whenever there is a take and the buffer is not full, ignoring 
> whether the transducer is still outputting values. This bug may be 
> relevant, though there it arises in a less common scenario (fixed buffer of 
> size 0, which is now disallowed) 
> https://dev.clojure.org/jira/browse/ASYNC-140
>

So, should I report this as a bug? If you have channel with a buffer and a 
(mapcat identity) transducer, the number of items in the channel can grow 
without bound. I thought channels were supposed to prevent that.

 

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


Re: core.async consumer + producer working by chunk?

2018-01-05 Thread Rob Nikander


On Friday, January 5, 2018 at 4:00:25 PM UTC-5, Moritz Ulrich wrote:
>
>
> You have a channel with a buffer-size of one. You clear the buffer by 
> taking one item from it, making room for another one. Therefore the put 
> succeeds. Try just `(async/chan nil xform)` to create a channel without 
> a backing buffer (a rendezvouz channel) where puts only succeed if 
> there's a matching consumer. 
>

Then why does Brian's code work the way it does? See how he takes 2 things 
off the channel, and offer! still fails and returns nil. If offer! is 
returning nil, shouldn't >!! be blocking?



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

2018-01-05 Thread Rob Nikander
Thanks for the explanation! This is very close to what I want. I see some 
confusing behavior though. See below.

On Friday, January 5, 2018 at 2:40:14 PM UTC-5, Brian J. Rubinton wrote:
>
>
> The work-queue channel has a fixed buffer size of 1. A collection (range 
> 50) is put on the channel. While consumers can take items off the channel — 
> note the individual contents of (range 50) are returned — a producer cannot 
> put another value onto the channel until the entire initial collection is 
> consumed. 
>

I tried your example code works for me, but then I tried using `>!!` 
instead of `offer!` and it behaves differently.

user> (def c (chan 1 (mapcat identity)))
=> #'user/c
user> (do 
   (async/thread (async/>!! c [1 2 3]) (println "put #1"))
   (async/thread (async/>!! c [4 5 6]) (println "put #2"))
   (async/thread (async/>!! c [7 8 9]) (println "put #3")))
put #1

As expected it prints "put #1" right away, and other threads are blocked. 
But...
   
user> (poll! c)
=> 1
put #2
user> (poll! c)
=> 2
put #3

As soon as your read anything from it, other puts succeed. Shouldn't they 
be blocked?

Rob 

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

2018-01-05 Thread Rob Nikander


On Friday, January 5, 2018 at 2:03:00 PM UTC-5, Brian J. Rubinton wrote:
>
>
> What is the buffered channel’s buffer used for? If that’s set to 1 and the 
> channel’s transducer is `(mapcat identity)` then the producer should be 
> able to continuously put chunks of work onto the channel with the puts only 
> completing when the previous chunk is completely consumed.
>

The buffer is sort of a work queue, used to break up and distribute one 
"chunk" to a pool of consumers. I was imaging the buffer would be size 50. 
So the producer would grab 50 rows (one "chunk") and put them all in the 
channel. Consumers would pick them out one by one.

I'm not familiar with the transducer concept so I need to go read a bit 
before I can understand your point about the channel's transducer being 
`(mapcat identity)`.

 

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


core.async consumer + producer working by chunk?

2018-01-05 Thread Rob Nikander
Hi,

I’m wondering if there is a core.async design idiom for this situation...

- A buffered channel 
- One producer feeding it 
- A bunch of consumers pulling from it.
- Producer should wake up and fill the channel only when it’s empty. In 
other words, the producer should work in chunks.

My first idea is to have two channels. The second will be used by consumers 
to signal the producer that the primary channel is empty. But I'm wondering 
if there is a better way.

The motive for this is that the producer is doing a DB query that is more 
efficient in bulk. `select ... limit 50` rather than `select ... limit 1` 
50 times.

Rob

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

2017-10-13 Thread Rob Nikander


On Friday, October 13, 2017 at 2:55:51 PM UTC-4, Justin Smith wrote:
>
> what happens is that the metadata reader macro is applied before the 
> comment reader macro, so you comment out the name of the def (which also 
> had the metadata attached)
>
> user=> '(def #_ ^:private foo 1)
> (def 1)
>


Makes sense. Thanks.

Rob 

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


form comment and meta data?

2017-10-13 Thread Rob Nikander
Hi,

Why doesn't this compile? I tried to comment out the "private" metadata.

  (def #_^:private foo 1)
  CompilerException java.lang.RuntimeException: First argument to def must 
be a Symbol, compiling:(null:1:1) 


Rob


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

2017-10-10 Thread Rob Nikander
Gah. I changed one name and not another. I meant:

(update-in m [:qs * :nums] ...)



On Tuesday, October 10, 2017 at 10:18:56 AM UTC-4, Rob Nikander wrote:
>
> Hi,
>
> Say I have a map like this:
>
> (def m {:qs [{:nums [3 1 2]} {:nums [7 4]}]})
>
> I want to transform each number with a function (say, `inc`). I imagine 
> something like this:
>
> (update-in m [:qs * :cell-fns] #(map inc %))  
> ; or 
> (update-in m [:qs * :cell-fns *] inc)  
>
>
> But of course you can't write that.  The following code works, but I don't 
> like reading it:
>
> (update m :qs   
> (fn [qs]
>   (mapv
> (fn [q] 
>   (update q :nums #(mapv inc %)))
> qs)))
> => {:qs [{:nums [4 2 3]} {:nums [8 5]}]}
>
> Is there an idiomatic way to do this, that looks more like the shorter 
> `update-in` idea?
>
> Rob
>
>
>
>

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


Updating repeated nested structures?

2017-10-10 Thread Rob Nikander
Hi,

Say I have a map like this:

(def m {:qs [{:nums [3 1 2]} {:nums [7 4]}]})

I want to transform each number with a function (say, `inc`). I imagine 
something like this:

(update-in m [:qs * :cell-fns] #(map inc %))  
; or 
(update-in m [:qs * :cell-fns *] inc)  


But of course you can't write that.  The following code works, but I don't 
like reading it:

(update m :qs   
(fn [qs]
  (mapv
(fn [q] 
  (update q :nums #(mapv inc %)))
qs)))
=> {:qs [{:nums [4 2 3]} {:nums [8 5]}]}

Is there an idiomatic way to do this, that looks more like the shorter 
`update-in` idea?

Rob



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

2017-10-02 Thread Rob Nikander
I get this when I switch from 1.8 to 1.9 beta, but maybe it's an issue with 
the `core.match` library?

WARNING: boolean? already refers to: #'clojure.core/boolean? in namespace: 
clojure.tools.analyzer.utils, being replaced by: 
#'clojure.tools.analyzer.utils/boolean?

Rob


On Thursday, September 28, 2017 at 10:00:16 AM UTC-4, stuart@gmail.com 
wrote:
>
> Clojure 1.9 has been quite stable throughout the alpha period, and we now 
> hope to release after a very short beta. Please test your existing programs 
> on the latest beta (see below), and respond on this thread ASAP if you 
> discover anything you believe to be a regression.
>
> Thanks!
> Stu
>

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


tags or categories for tests?

2017-08-20 Thread Rob Nikander
Hi, 

The lein command `lein help test` explains that you can add metadata to 
tests and select subsets of tests to run. Is there a way to do something 
like that from the REPL (clojure.test/run-tests) without lein?

Rob

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

2017-07-24 Thread Rob Nikander
I think in my case here the easiest thing will be to remove the cycles, but 
still I'd like to understand a couple things...

On Sunday, July 23, 2017 at 10:12:46 PM UTC-4, Didier wrote:
>
> I'm not sure I can fully help without you explaining more what you're 
> doing. It sounds like you've got a collection or container type which has 
> an implementation of print that loops over its elements, and calls print on 
> them. So if you have a cycle, the print will go on forever until memory 
> runs out.
>

My container type (the tree node) is simply the standard clojure map. 

If you're using a standard type, you might be able to limit *print-level* 
> . Most Clojure 
> collections will limit how deep they print based on the value of this 
> global dynamic Var.
>

Okay, *print-level* works but it looks like I have to call print myself. I 
can't rely on the REPL to print it. 

(binding [*print-level* 2] (println (find-route "/reports")))   ; okay

Why does `alter-var-root` here seem to succeed, but have no effect?

(alter-var-root #'*print-level* (constantly 2))
=> 2
*print-level*
=> nil
(find-route "/reports")
stack overflow

 

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


printing self referential data?

2017-07-23 Thread Rob Nikander
I'm translating some code from an object oriented language to Clojure. I'm 
a little confused about a tree structure I had where tree nodes have parent 
and children properties, so the structure forms cycles. I used atoms for 
those properties, so I could wire it all up. The code is clean and simple 
and I'm happy with it, except ... the things don't print in the REPL. 
(stack overflow)

Are there any tricks to printing cyclical data structures in the REPL?  

Rob

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


Re: How is this code to create a stateful lazy sequence?

2017-07-23 Thread Rob Nikander
Yes, I find that much clearer too. Thanks!

On Saturday, July 22, 2017 at 4:50:23 PM UTC-4, tbc++ wrote:
>
> If we think about what we're doing here is a stateful filter, then maybe 
> we could leverage a few more core Clojure functions:
>
>
> (defn distinct-by [f coll]
>   (let [seen (atom #{})]
> (filter (fn [itm]
>(let [m (f itm)]
>   (when-not (@seen m)
> (swap! seen conj m 
>  coll)))
>
>

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


How is this code to create a stateful lazy sequence?

2017-07-22 Thread Rob Nikander
Hi,

Here's a function and a simple use of it. It works, but the code may not be 
good Clojure. I'm wondering how it might be better.

(defn distinct-by
  "Returns a sequence with no repeats of (f item). 
  A set is built up internally as the sequence is consumed, so don't use it 
on
  an infinite sequence or you will run out of memory."
  ([f coll]
(letfn [(get-more [seen input-seq]
   (if (not (empty? input-seq))
 (let [x (first input-seq)
   fx (f x)]
   (if (contains? seen fx)
 (lazy-seq (get-more seen (rest input-seq)))
 (lazy-seq (cons x (get-more (conj seen fx) (rest 
input-seq]
   (get-more #{} (seq coll)

(def xs (list {:n 1, :a 'a} {:n 2, :a 'b} {:n 3, :a 'a} {:n 4, :a 'c} {:n 
5, :a 'b}))

(distinct-by :a xs)
=> ({:n 1, :a a} {:n 2, :a b} {:n 4, :a c})

Rob

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