On Sat, Jan 19, 2013 at 11:32 PM, Colin Yates <colin.ya...@gmail.com> wrote:
> I am struggling to understand what Clojure is doing.  This is definitely a
> newbie question but I cannot figure it out :).  The question is best asked
> via a repl session:
>
> [code]user=> (defn create-user [] {:id 1})
> #'user/create-user
> user=> (create-user)
> {:id 1}
> user=> (take 10 (repeatedly create-user))
> ({:id 1} {:id 1} {:id 1} {:id 1} {:id 1} {:id 1} {:id 1} {:id 1} {:id 1}
> {:id 1})
> user=> (defn stream1 [] repeatedly create-user)
> #'user/stream1
> user=> (take 10 stream1)
> IllegalArgumentException Don't know how to create ISeq from: user$stream1
> clojure.lang.RT.seqFrom (RT.java:494)
> user=> (take 10 (stream1))
> IllegalArgumentException Don't know how to create ISeq from:
> user$create_user  clojure.lang.RT.seqFrom (RT.java:494)

The mistake is in the body of stream1. You should have wrapped
`repeatedly ceate-user` in parenthesis, otherwise the return value of
stream1 is the function `create-user`.

You'd want to fix the code like this -

(defn stream1 []
    (repeatedly create-user))

And then, you should call get some users from the stream like this -

(take 10 (stream1))

You need to call stream1 like a function because otherwise it'd mean
`take`-ing things from a function which doesn't make any sense.

If you really want to deal with a "stream" directly and not call a
function, you can bind the stream in a var directly -

(def stream (repeatedly create-user))

`repeatedly` returns a lazy sequence so dealing with an infinite
sequence is not a problem. Mind you, you're "holding on to the head"
here, so you are still prone to facing stackoverflow errors if you
`def` an infinite sequence.


> user=> (defn stream2 [] (repeatedly create-user))
> #'user/stream2
> user=> (take 10 stream2)
> IllegalArgumentException Don't know how to create ISeq from: user$stream2
> clojure.lang.RT.seqFrom (RT.java:494)
> user=> (take 10 (stream2))
> ({:id 1} {:id 1} {:id 1} {:id 1} {:id 1} {:id 1} {:id 1} {:id 1} {:id 1}
> {:id 1})
> [/code]
>
> My question is two parted - what is the different between stream1 and
> stream2 - what exactly do they return.  And, based on that, why doesn't
> (stream1) return a sequence.  In other words, what effect does wrapping the
> function body in quotes actually do?

`stream1` returns just the function `create-user` when invoked.
`stream2` return an infinite lazy-sequence of the results of calling
`create-user` repeatedly.

Hope that helps.

Regards,
BG

--
Baishampayan Ghose
b.ghose at gmail.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

Reply via email to