drym-org / qi

An embeddable flow-oriented language.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

`for/lists` idiomatic equivalent

benknoble opened this issue · comments

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.