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.

Reply via email to