Hi Hank, That loop/recur is still wrong because `loop` set bindings to define names and gives initial values but `recur` does *not set bindings*, it just provides new values. So `recur` does not need a vector of bindings like `loop`
The pattern is as follow: (loop [a-local-var "initial-value"] (if (should-stop-looping? a-local-var) (execute-last-expression a-local-var) (recur a-new-local-var))) In your pt8 function, you are reading your stream to many times in a loop, if I write your pt8 function in procedural pseudo-code, this is what I get: bfr = input-stream() ct = string-buffer() set loop-start // set loop point with val, // set loop args val = read(bfr) // set args initial value, first read if !(val == -1) { ct.append(char(read(bfr))) // read again! and lose previous byte!! goto loop-start with val = vector(val, read(bfr)) // read again! this byte will be lost soon :( } ct.toString() Regards, Laurent Le dimanche 26 décembre 2021 à 18:12:56 UTC+1, hank....@gmail.com a écrit : > Hi -- > Thanks for taking the time to help me. > As far as I understand the examples, loop has this template: > > loop [binding] > (condition > (statement) > (recur (binding))) > And in 'recur' the loop is re-executed with new bindings. > > There was indeed an issue with the 'recur' outside 'when'. Thanks for > pointing that out. > I corrected that in the version below. > > I also changed to a smaller file (UTF-8 encoded in Linux), called > 'ribs.txt', with the following content: > > source/txt on master [!?] > ❯ cat ribs.txt > Try my delicious pork-chop ribs! > > source/txt on master [!?] > ❯ cat ribs.hexdump > 00000000: 54 72 79 20 6d 79 20 64 65 6c 69 63 69 6f 75 73 Try my delicious > 00000010: 20 70 6f 72 6b 2d 63 68 6f 70 20 72 69 62 73 21 pork-chop ribs! > 00000020: 0a . > > > (defn pt8 [file] > (let [afr (FileReader. file); instances of FileReader, BufferedReader, > StringBuffer > bfr (BufferedReader. afr) > ct (StringBuilder.) > this-list (list afr bfr ct)] > ; (apply println this-list) > ; put recur INSIDE THE WHEN > (loop [val (.read bfr)] > (when (not (= val -1)) > (.append ct (Character/toChars (.read bfr))) > (recur [val (.read bfr)]))) > ; when finished... > (.toString ct))) > > I think this fixed the 'recur', because it does rebinding to a new call to > "read()". > However, the errors remains. > > user> (pt8 ribs) > Execution error (IllegalArgumentException) at java.lang.Character/toChars > (Character.java:8572). > Not a valid Unicode code point: 0xFFFFFFFF > > The file used is sufficiently small so that we can walk the bytes using > jshell: > > jshell> FileReader afr = new FileReader("/home/hank/source/txt/ribs.txt/") > afr ==> java.io.FileReader@1698c449 > > jshell> BufferedReader bfr = new BufferedReader(afr) > bfr ==> java.io.BufferedReader@5ef04b5 > > jshell> StringBuilder ct = new StringBuilder() > ct ==> > > FileReader reads 2 bytes per character so, to get to the end, of the first > hexdump line, let's walk 32 bytes: > > jshell> for (int i=0; i < 31; i++) { > ...> if ((value = bfr.read()) != -1) { ct.append((char) value); } > ...> i++; > ...> } > > jshell> ct > ct ==> Try my delicious > > 00000000: 54 72 79 20 6d 79 20 64 65 6c 69 63 69 6f 75 73 Try my delicious > T r y SP m y SP d e l i c i o u s (<---- YOU ARE > HERE) > > 00000000: 54 72 79 20 6d 79 20 64 65 6c 69 63 69 6f 75 73 Try my delicious > 00000010: 20 70 6f 72 6b 2d 63 68 6f 70 20 72 69 62 73 21 pork-chop ribs! > 00000020: 0a . > > Now we iterate 31 more bytes, stopping short of the last character: > jshell> for (int i=0; i < 30; i++) { > ...> if ((value = bfr.read()) != -1) { ct.append((char) value); } > ...> i++; > ...> } > > jshell> ct > ct ==> Try my delicious pork-chop ribs > > 00000000: 54 72 79 20 6d 79 20 64 65 6c 69 63 69 6f 75 73 Try my delicious > 00000010: 20 70 6f 72 6b 2d 63 68 6f 70 20 72 69 62 73 21 pork-chop ribs! > ^ we stopped here > > We just advance one more: > > jshell> if ((value = bfr.read()) != -1) { ct.append((char) value); } > ...> > > jshell> ct > ct ==> Try my delicious pork-chop ribs! > > And one more time, to see if it borks: > jshell> if ((value = bfr.read()) != -1) { ct.append((char) value); } > > jshell> ct > ct ==> Try my delicious pork-chop ribs! > > Nope, everything looks fine. Now where does that '0xFFFFFFF" come from?! > -- Hank -- 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 --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/clojure/4c79cbf9-84d0-4c4b-9407-6badc8e74f94n%40googlegroups.com.