Fork me on GitHub
#missionary
<
2021-12-23
>
Misi (ミシ)23:12:54

hello, i just started playing with missionary today and i just can't figure out why only the last page is returned in the result, the code is based on this example: https://github.com/leonoel/missionary/wiki/Iterative-queries#the-solution:

(defn read-numbers []
  (m/ap
   (loop [first-number 0]
     (let [numbers (m/?> (m/seed [(range first-number (inc first-number))]))
           last-number (last numbers)]
       (println "page:" numbers)
       (if (< last-number 10)
         (recur (inc last-number))
         numbers)))))

(println "result:" (m/? (m/reduce conj (read-numbers))))
the output:
page: (0)
page: (1)
page: (2)
page: (3)
page: (4)
page: (5)
page: (6)
page: (7)
page: (8)
page: (9)
page: (10)
result: [(10)]
i wonder if i can ask for help figuring this out

Panel23:12:46

Not sure what kind of process you are trying to replicate with this example. numbers is always going to be a seq of one element last-number is always going to be = to first-number (m/seed [(range first-number (inc first-number))]) This statement is always going to be something like -> (m/seed [(some-int))])` So unlike the example you never create multiple branch of the process. If you want to return element while in the loop you can fork the process with amb> like so:

(defn read-numbers []
  (m/ap
   (loop [first-number 0]
     (let [numbers (m/?> (m/seed [(range first-number (inc first-number))]))
           last-number (last numbers)]
       (println "page:" numbers)
       (if (< last-number 10)
         (m/amb> last-number (recur (inc last-number)))
         numbers)))))

Misi (ミシ)09:12:35

i wanted to create a minimal code example, but what i want is to get data from an api in multiple pages in this example the page size happens to be 1, this might have made it more confusing but your suggestion works, thank you! i'm embarrassed, but then i'm not sure where does the forking happen in the wiki code example, according to the comment it should happen at this point:

...
(m/?>))] ;; fork the process
...
but that part is replicated in my code and didn't work, what did i miss?

leonoel09:12:51

This guide predates amb>, I would write it like that now :

(defn pages
  ([] (pages :start))
  ([id]
   (m/ap
     (loop [id id]
       (let [{:keys [page next]} (m/? (api id))]
         (if next (m/amb> page (recur next)) page))))))

leonoel09:12:05

it's probably a better start, amb> is easier to understand than ?> IMO