Hi Laurent,
Thanks for the feedback. I'm still a bit stuck though since neither my
proposal nor yours work for the type of application I had in mind.
Here's a complete program which highlights the problems:
; ---- Begin lazyread.clj ----
(import '(java.io FileReader BufferedReader PrintWriter))
(def filename "test.data")
; Write out a small test file. Numbers 0 to 99, one per line.
(with-open [data (PrintWriter. filename)]
(dotimes [i 100] (.println data i)))
; An attempt at capturing the general idiom that doesn't work
(defn cons-while
[pred f]
(lazy-seq
(when pred
(cons f (cons-while pred f)))))
; Another attempt that doesn't work
(defn repeatedly-while
[pred f]
(take-while pred (repeatedly f)))
; A specific implementation for the problem at hand
(defn lazy-read [reader]
(lazy-seq
(when (.ready reader)
(cons (.readLine reader) (lazy-read reader)))))
(print "lazy-read: ")
(with-open [data (BufferedReader. (FileReader. filename))]
(prn (take 10 (lazy-read data))))
(print "cons-while: ")
(with-open [data (BufferedReader. (FileReader. filename))]
(prn (take 10 (cons-while (.ready data) (.readLine data)))))
(print "repeatedly-while: ")
(with-open [data (BufferedReader. (FileReader. filename))]
(prn (take 10 (repeatedly-while #(.ready data) #(.readLine data)))))
; ---- End lazyread.clj ----
Running this will write out a small test file named `test.data` in the
current directory with the numbers 0-99 one per line and then use
three techniques to lazily read in the first 10 lines.
The first technique, `lazy-read`, is an explicit use of the `lazy-seq`
+ `when` + `cons` combination I wish to generalise. The second one,
`cons-while`, is the attempt I made and the third, `repeatedly-while`
is your suggestion.
Here's the output I get when I run this as a script from the command
line:
----
$ clj lazyread.clj
lazy-read: ("0" "1" "2" "3" "4" "5" "6" "7" "8" "9")
cons-while: ("0" "0" "0" "0" "0" "0" "0" "0" "0" "0")
Exception in thread "main" java.lang.RuntimeException:
java.lang.RuntimeException: java.lang.IllegalArgumentException: Wrong
number of args passed to: user$eval--38$fn (scratch.clj:0)
----
Unsurprisingly, the problem-specific method seems to work fine. The
`cons-while` method returns the wrong output and the last technique
fails because of issues surrounding the macro expansion of (.ready
data) and the #(...) macro that have been discussed elsewhere.
Is it possible to get the `repeatedly-while` version working with
calls to Java without making the calling pattern too convoluted?
Also, can anyone explain why the `cons-while` approach only appears to
be repeatedly reading the first line?
Finally, would a macro approach be better for this type of problem?
Thanks,
Mark.
--
http://mark.reid.name
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Clojure" group.
To post to this group, send email to [email protected]
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
-~----------~----~----~----~------~----~------~--~---