Hi, the version of repeatedly-while I submitted still takes an argument for
the predicate function, that would be the value of the last generated item
in the list:

(defn repeatedly-while
 [pred f]
 (take-while pred (repeatedly f)))

So if you want to call it with a no-arg "predicate", you must adapt it :

(repeatedly-while (fn [ _ ] (no-arg-pred)) f)
instead of
(repeatedly-while no-arg-pred f)

(notice the underscore that emphazises the fact that we don't care about the
argument).

Or create a less general function that accepts only no-arg predicates:
(defn repeatedly-while2 [no-arg-pred f]
  (take-while (fn [ _ ] (no-arg-pred) f))

(not tested)

But this is a less general function ...

Regards,

-- 
Laurent

2009/5/9 Mark Reid <mark.r...@gmail.com>

>
> 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 clojure@googlegroups.com
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