I'm attempting to read and understand core.clj, and I'm walking through methods as I run into them, trying to understand them, line by line. I' mostly understand read-lines (w/ the exception of the last line), but I do not follow lazy-seq or if-let. Could someone check my deconstruction of read-lines and make sure I'm getting this right?
-Todd 1. read-lines (defn read-lines "Like clojure.core/line-seq but opens f with reader. Automatically closes the reader AFTER YOU CONSUME THE ENTIRE SEQUENCE." [f] (let [read-line (fn this [#^BufferedReader rdr] (lazy-seq (if-let [line (.readLine rdr)] (cons line (this rdr)) (.close rdr))))] (read-line (reader f)))) 1.1 define a function, named 'read-lines', that takes a single parameter, 'f' (defn read-lines [f] 1.2 create a scoped variable, 'read-line', and assign a function to it (let [read-line (fn this [#^BufferedReader rdr] 1.3 the function is called 'this', and it takes a BufferedReader...note the compiler hint telling that this is a 'BufferedReader' (that's what the #^ is doing) 1.4 create a lazy sequence (lazy-seq Q: what is a lazy-seq? 1.5 let line equal the result of rdr.readLine (if-let [line (.readLine rdr)] 1.6 if line is true, then insert this line at the head of a sequence (cons line (this rdr) 1.7 if line was false, then close the reader (.close rdr))))] 1.8 invoke the locally defined read-line function on... Q: what does (reader f) mean? What is 'reader'? (read-line (reader f)))) 2. lazy-seq (defmacro lazy-seq "Takes a body of expressions that returns an ISeq or nil, and yields a Seqable object that will invoke the body only the first time seq is called, and will cache the result and return it on all subsequent seq calls." {:added "1.0"} [& body] (list 'new 'clojure.lang.LazySeq (list* '^{:once true} fn* [] body))) 3. if-let (defmacro if-let "bindings => binding-form test If test is true, evaluates then with binding-form bound to the value of test, if not, yields else" {:added "1.0"} ([bindings then] `(if-let ~bindings ~then nil)) ([bindings then else & oldform] (assert-args if-let (and (vector? bindings) (nil? oldform)) "a vector for its binding" (= 2 (count bindings)) "exactly 2 forms in binding vector") (let [form (bindings 0) tst (bindings 1)] `(let [temp# ~tst] (if temp# (let [~form temp#] ~then) ~else))))) -- 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