jcoo092
2020-5-17 02:47:38

I’m struggling to work out how to use the result from a function that returns a values (always with two values). Does anybody know of any good guidance, e.g. blog posts etc, on the topic?

In this instance, I am trying to gather together the results of calling (place-channel) several (but not a fixed number of) times, but everything I can think of to try that doesn’t require me hard-coding a fixed number of calls doesn’t really work - at least, not without being fairly complicated. I figure I must be missing something, but I can’t figure it out.


sorawee
2020-5-17 04:00:54

@jcoo092 define-values might be the easiest way


sorawee
2020-5-17 04:01:30

(define (f x) (values x (add1 x))) (define-values (x y) (f 10)) (println (+ x y))


sorawee
2020-5-17 04:02:29

There are other constructs that work with multiple values. To mention a few: call-with-values, let-values, match-define-values


sorawee
2020-5-17 04:04:07

E.g.,

(call-with-values (lambda () (f 10)) (lambda (x y) (println (+ x y)))) (let-values ([(x y) (f 10)]) (println (+ x y))) (match-define-values (x y) (f 10)) (println (+ x y))


jcoo092
2020-5-17 04:07:55

Currently I’m using this function that I wrote, but I figure there must be a better/more-idiomatic way: (define (create-chans length) (define (helper iteration rxes txes) (match iteration [0 (values rxes txes)] [iter (let-values ([(rx tx) (place-channel)]) (helper (sub1 iteration) (list* rx rxes) (list* tx txes)))])) (helper length null null)) (thinking about it, I probably should have posted this to begin with)


jcoo092
2020-5-17 04:08:15

Anyway, thanks @sorawee :slightly_smiling_face:


sorawee
2020-5-17 04:11:27

This looks perfectly fine to me. If I were to write it, I would write:

(define (create-chans length) (let loop ([iteration length] [rxes null] [txes null]) (match iteration [0 (values rxes txes)] [_ (define-values (rx tx) (place-channel)) (loop (sub1 iteration) (cons rx rxes) (cons tx txes))])))


jcoo092
2020-5-17 04:15:56

There’s a couple of things in there I didn’t know you could do with Racket. Thanks again :slightly_smiling_face:


sorawee
2020-5-17 04:16:03

Alternatively:

(define (create-chans length) (for/fold ([rxes null] [txes null] #:result (values rxes txes)) ([iteration (in-range length)]) (define-values (rx tx) (place-channel)) (values (cons rx rxes) (cons tx txes))))