# Predicate to check for \`(values)\`?

**URL:** <https://racket.discourse.group/t/predicate-to-check-for-values/2012>\
**Category:** Questions & Answers\
**Tags:** question, values, predicate\
**Created:** [June 14, 2023, 6:16pm UTC](https://racket.discourse.group/t/predicate-to-check-for-values/2012 "2023-06-14T18:16:56Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![sschwarzer](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/sschwarzer/32/1940_2.png) [@sschwarzer](https://racket.discourse.group/u/sschwarzer)\
**Post date:** [June 14, 2023, 6:16pm UTC](https://racket.discourse.group/t/predicate-to-check-for-values/2012/1 "2023-06-14T18:16:56Z")

</div>

If I define a generator

```scheme
(require racket/generator)

(define a-generator
  (generator ()
    (yield 1)
    (yield 2)))

```

and call `a-generator` repeatedly, I get

```scheme
> (a-generator)
1
> (a-generator)
2
> (a-generator)
> (a-generator)

```

That is, after 1 and 2 are yielded, nothing is displayed in the REPL. When I try to `print` the result, I get an arity error, so I suspected that this is a multiple-values thing.

And indeed,

```scheme
(define-values () (a-generator))

```

succeeds.

Now I wonder if it would be possible to implement a predicate function to check if a value (or, actually, non-values 😉 ) is `(values)`. This would probably be tricky; I'm not even sure if there's a way to write a function that could be _called as_ `(predicate? (values))` in the first place, regardless of a check in the function.

Even "in-line", without defining a function, a check seems to be non-trivial or not possible. I thought it might work with `match`, but all I found in the `match` documentation seems to require that the number of values in `(values ...)` is known beforehand.

---

<div class="post-metadata">

**Author:** ![sschwarzer](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/sschwarzer/32/1940_2.png) [@sschwarzer](https://racket.discourse.group/u/sschwarzer)\
**Post date:** [June 14, 2023, 6:31pm UTC](https://racket.discourse.group/t/predicate-to-check-for-values/2012/2 "2023-06-14T18:31:23Z")

</div>

@soegaard pointed me to `call-with-values` (see [10.1&nbsp;Multiple Values](https://docs.racket-lang.org/reference/values.html#%28def._%28%28quote._~23~25kernel%29._call-with-values%29%29)), and indeed,

```scheme
> (call-with-values a-generator list)
'()

```

works. This doesn't answer how I could call a function with the _result of_ `a-generator`, but the suggestion is good enough for me. 🙂

---

<div class="post-metadata">

**Author:** ![sorawee](https://avatars.discourse-cdn.com/v4/letter/s/ea5d25/32.png) [@sorawee](https://racket.discourse.group/u/sorawee)\
**Post date:** [June 14, 2023, 10:32pm UTC](https://racket.discourse.group/t/predicate-to-check-for-values/2012/3 "2023-06-14T22:32:12Z")

</div>

An arguably more direct way is:

```scheme
(call-with-values 
 a-generator
 (case-lambda
  [() #t]
  [else #f]))

```

---

<div class="post-metadata">

**Author:** ![shawnw](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/shawnw/32/1031_2.png) [@shawnw](https://racket.discourse.group/u/shawnw)\
**Post date:** [June 15, 2023, 2:31am UTC](https://racket.discourse.group/t/predicate-to-check-for-values/2012/4 "2023-06-15T02:31:01Z")

</div>

Racket generators repeatedly return what the body of the generator last returned when it finishes evaluating. In this case, I'd expect a `#<void>` value like you normally get from an equivalent lambda expression, but `(void? (a-generator))` on your exhausted generator gives an arity error. It actually doesn't return _anything_, which I didn't think was possible.

Anyways, to check to see if a Racket-style generator is finished, use [`generator-state`](https://docs.racket-lang.org/reference/Generators.html#%28def._%28%28lib._racket%2Fgenerator..rkt%29._generator-state%29%29) instead of depending on the return value. Though that won't return `'done` until after your generator has returned an empty value...

(I prefer [SRFI-158](https://srfi.schemers.org/srfi-158/srfi-158.html) style generators that return end-of-file when done (Available in my [`extra-srfi-libs`](https://docs.racket-lang.org/extra-srfi-libs/index.html) collection). They're usually easier to work with (Unless EOF is a valid return value, in which case, have to drag boxes or something into it).

---

<div class="post-metadata">

**Author:** ![sschwarzer](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/sschwarzer/32/1940_2.png) [@sschwarzer](https://racket.discourse.group/u/sschwarzer)\
**Post date:** [June 15, 2023, 8:53am UTC](https://racket.discourse.group/t/predicate-to-check-for-values/2012/5 "2023-06-15T08:53:52Z")

</div>

> [@sorawee](#):
>
> An arguably more direct way is:
> 
> ```scheme
> (call-with-values 
> a-generator
> (case-lambda
> [() #t]
> [else #f]))
> 
> ```

I like both

```scheme
(null? (call-with-values a-generator list))

```

and your approach. The former because it's a simpler expression and yours because it's more explicit.

> [@shawnw](#):
>
> Anyways, to check to see if a Racket-style generator is finished, use [`generator-state`](https://docs.racket-lang.org/reference/Generators.html#%28def._%28%28lib._racket%2Fgenerator..rkt%29._generator-state%29%29) instead of depending on the return value.

In this context, this is of course the way to go. I just got sidetracked because of the "funny" return value of the generator. 😉

That said, In my concrete use case the easiest way was to return `#f` at the end of the generator and use `in-producer`.

> [@shawnw](#):
>
> In this case, I'd expect a `#<void>` value like you normally get from an equivalent lambda expression, but `(void? (a-generator))` on your exhausted generator gives an arity error.

I was also quite surprised at first and agree that `(void? (a-generator))` would be more "natural".

> [@shawnw](#):
>
> It actually doesn't return _anything_, which I didn't think was possible.

It depends on what you mean by "anything". You might as well argue that a function

```scheme
(define (test)
  (values))

```

returns _something_, namely `(values)`. 😉

It's "just" a special case of using `values`:

```scheme
> (values 1 2)
1
2
> (values 1) ; same as 1
1
> (values)

```

Generally, I think if `#f` or `(void)` as special values supposedly aren't enough, it's better to define a unique value with `(define unique-values (gensym))` instead of "inventing" more obscure values that might or might not conflict with client code.

That said, maybe returning `(values)` from an exhausted generator is just a side effect of the implementation, not an intentional special value.
