On Sat, Jan 19, 2013 at 11:32 PM, Colin Yates <[email protected]> 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 [email protected]
Note that posts from new members are moderated - please be patient with your
first post.
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en