Непосредственная проблема состоит в том, что многократно ожидает функцию, и вы даете результат (str (....)), который является String. Чтобы сделать Clojure счастливым, вам нужно «упаковать» вызов «str» в «fn»:
(repeatedly (fn [] (str (.read reader)))))
Лучшее решение - использовать slurp или slurp * (последний есть в contrib IIRC) или, по крайней мере, проверить, как оно написано.
[править]
Там нет такой вещи, как "ленивая строка" в clojure. Строки Clojure - это просто строки Java. У Clojure есть ленивые последовательности, поэтому вы можете попробовать их использовать, но вам придется бороться с завершающим потоком.
В качестве альтернативы вы можете использовать следующий подход (псевдокод):
(defn process-url [url proc-fn]
(with-open [the-stream ...]
(loop [c (.read r)]
(if-not (neg? c)
(proc-fn (char c)))))
Это вызовет функцию, которую вы передаете в качестве второго аргумента для каждого прочитанного символа.