# Chaining together functions with multiple return values

**URL:** <https://racket.discourse.group/t/chaining-together-functions-with-multiple-return-values/3803>\
**Category:** Questions & Answers\
**Created:** [June 21, 2025, 6:39pm UTC](https://racket.discourse.group/t/chaining-together-functions-with-multiple-return-values/3803 "2025-06-21T18:39:45Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![sora22](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/sora22/32/2622_2.png) [@sora22](https://racket.discourse.group/u/sora22)\
**Post date:** [June 21, 2025, 6:39pm UTC](https://racket.discourse.group/t/chaining-together-functions-with-multiple-return-values/3803/1 "2025-06-21T18:39:45Z")

</div>

I've recently tried writing functions that return multiple values for some calculations that chain together, and I feel that I am likely doing something incorrectly. When I attempt to chain them I can't find a way to get it work without wrapping each of the sequential function calls in a thunk. Wouldn't this incur a performance loss (not to mention a lot of extra typing)? Theres enough friction chaining them together that I feel like I have to do be doing something wrong

An example of what I mean:

```scheme
(define (test-func0 x y)
  (values (+ x 1) (+ y 1)))

(define (test-func1 x y)
  (values (* x 2) (* y 2)))

(define (test-func2 x y)
  (+ x y))

(call-with-values (lambda () (call-with-values (lambda () (test-func0 1 1)) test-func1)) test-func2)

```

Am I missing something?

---

<div class="post-metadata">

**Author:** ![LiberalArtist](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/liberalartist/32/151_2.png) [@LiberalArtist](https://racket.discourse.group/u/LiberalArtist)\
**Post date:** [June 21, 2025, 7:17pm UTC](https://racket.discourse.group/t/chaining-together-functions-with-multiple-return-values/3803/2 "2025-06-21T19:17:46Z")

</div>

> [@sora22](#):
>
> Theres enough friction chaining them together that I feel like I have to do be doing something wrong

What you did isn't _wrong_, but you could more concisely write:

```scheme
((compose test-func2 test-func1 test-func0) 1 1)

```

> [@sora22](#):
>
> When I attempt to chain them I can't find a way to get it work without wrapping each of the sequential function calls in a thunk. Wouldn't this incur a performance loss (not to mention a lot of extra typing)?

The compiler recognizes `call-with-values`, so it can avoid creating unnecessary closures. (Also, Racket in general works to make patterns like this perform reasonably.)

There is some overhead for `compose`, because:

1. It is just a function, so it doesn't even know how many arguments it's being called with until runtime; and
2. It is extremely general, preserving the arity (including potential keywords) of the first function in the pipeline and allowing for any number of values in intermediate steps.

However, `compose` does put effort into optimizing common cases, which happens to include procedures of arity 2, so your example won't fall into the worst-case fallback.

The performance overhead is why `compose1` exists. You could define a `compose2` if it were relevant for your purposes, or you could use a macro to compose statically.

---

<div class="post-metadata">

**Author:** ![EmEf](https://avatars.discourse-cdn.com/v4/letter/e/53a042/32.png) [@EmEf](https://racket.discourse.group/u/EmEf)\
**Post date:** [June 21, 2025, 7:22pm UTC](https://racket.discourse.group/t/chaining-together-functions-with-multiple-return-values/3803/3 "2025-06-21T19:22:49Z")

</div>

`compose` works, as @LiberalArtist points out.

```scheme
(let*-values
    ([(s t) (test-func0 1 1)]
     [(s t) (test-func1 s t)]
     [(s) (test-func2 s t)])
  s)

```

is my preferred way of writing such expressions, unless I really want function composition in the mathematical sense.

---

<div class="post-metadata">

**Author:** ![sora22](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/sora22/32/2622_2.png) [@sora22](https://racket.discourse.group/u/sora22)\
**Post date:** [June 21, 2025, 11:40pm UTC](https://racket.discourse.group/t/chaining-together-functions-with-multiple-return-values/3803/4 "2025-06-21T23:40:18Z")

</div>

I started looking through the source code for compose and compose1 to see if I could write a static version like you had mentioned, and saw that the general case (at least from my understanding of the code) was doing a similar thing with call-with-values. Assuming that Racket will optimize the closures away I wrote this macro (very quickly might I add, this probably isn't the ideal way to deal with an arbitrary number of arguments but it works well enough for my use case) in case anyone else wanted a more succinct way to write it:

```scheme
(define-syntax (call-with-values-chained stx)
  (syntax-parse stx
    [(_ last-elem)
     #'last-elem]
    [(_ first-elem (~seq rest-lst ...))
     #'(call-with-values (lambda () (call-with-values-chained rest-lst ...)) first-elem)]))

```

---

<div class="post-metadata">

**Author:** ![benknoble](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/benknoble/32/16_2.png) [@benknoble](https://racket.discourse.group/u/benknoble)\
**Post date:** [June 22, 2025, 5:39pm UTC](https://racket.discourse.group/t/chaining-together-functions-with-multiple-return-values/3803/5 "2025-06-22T17:39:01Z")

</div>

This is also a perfect opportunity to show Qi syntax (from `(require qi)` after installing the package).

```scheme
(~> (1 1) test-func0 test-func1 test-func2)

```
