qi
qi copied to clipboard
`for/lists` idiomatic equivalent
Here's some old Frosthaven Manager code:
(define (element-cyclers es)
(for/fold ([@states empty]
[views empty]
#:result (values (reverse @states)
(reverse views)))
([e (in-list es)])
(define-values (@state view) (element-cycler e))
(values (cons @state @states)
(cons view views))))
Ignoring the details, the general pattern is that we have a function element-cycler
that returns two values; we want to map that function over function over a list es
and collect the resulting values in two parallel lists. The above code implements that, but the intent is obscured.
Using for/lists
, which I only learned about later, we could in fact write
(define (element-cyclers es)
(for/lists (@states views)
([e (in-list es)])
(element-cycler e)))
What is the corresponding Qi idiom? At first glance, it doesn't seem like ><
(amp
) and collect
are enough, because we need to split the values into parallel "streams" or "flows." Naïvely, we could write a Qi macro that wraps for/lists
via esc
; to be "natural" Qi, though, I would argue that the resulting lists should be passed as values to subordinate flows, rather than be given back as lists directly (use collect
to retrieve the lists: hopefully a compiler will avoid list-to-values-to-list).
Alternately, we could probably write a Qi macro over loop
or the fold forms that translates the original fold/cons/reverse pattern.
In either case, the number of parallel streams in the result should (must?) be a parameter of the flow.
Based on discussion in the Racket Discord.