# How to check equality of \`values\`?

**URL:** <https://racket.discourse.group/t/how-to-check-equality-of-values/2758>\
**Category:** General\
**Tags:** question\
**Created:** [March 3, 2024, 1:26pm UTC](https://racket.discourse.group/t/how-to-check-equality-of-values/2758 "2024-03-03T13:26:42Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![xiaoyu2006](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/xiaoyu2006/32/1682_2.png) [@xiaoyu2006](https://racket.discourse.group/u/xiaoyu2006)\
**Post date:** [March 3, 2024, 1:26pm UTC](https://racket.discourse.group/t/how-to-check-equality-of-values/2758/1 "2024-03-03T13:26:42Z")

</div>

The intuitive way doesn't work

```rkt
> (equal? (values 1 2) (values 1 2))
result arity mismatch;
 expected number of values not received
  expected: 1
  received: 2
 [,bt for context]

```

(P.S. Interestingly I failed to find a solution to this seemingly simple question, because searching keyword `values` appears in so many contexts.)

---

<div class="post-metadata">

**Author:** ![soegaard](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/soegaard/32/19_2.png) [@soegaard](https://racket.discourse.group/u/soegaard)\
**Post date:** [March 3, 2024, 1:33pm UTC](https://racket.discourse.group/t/how-to-check-equality-of-values/2758/2 "2024-03-03T13:33:37Z")

</div>

Compare one pair of values at at a time.

```scheme
> (let-values ([(a b) (values 1 2)]
               [(c d) (values 1 2)])
      (and (equal? a c)
           (equal? b d)))
#t

```

---

<div class="post-metadata">

**Author:** ![xiaoyu2006](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/xiaoyu2006/32/1682_2.png) [@xiaoyu2006](https://racket.discourse.group/u/xiaoyu2006)\
**Post date:** [March 3, 2024, 1:41pm UTC](https://racket.discourse.group/t/how-to-check-equality-of-values/2758/3 "2024-03-03T13:41:02Z")

</div>

That looks cumbersome. Also any reasons why `equal?` don't work?

---

<div class="post-metadata">

**Author:** ![soegaard](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/soegaard/32/19_2.png) [@soegaard](https://racket.discourse.group/u/soegaard)\
**Post date:** [March 3, 2024, 2:07pm UTC](https://racket.discourse.group/t/how-to-check-equality-of-values/2758/4 "2024-03-03T14:07:30Z")

</div>

In an application `(proc-expr arg ...)` each `arg` expression must evaluate to a single value. The context of the first `(values 1 2)` expects a single value, so you get an error. To work with values, you need to use either `let-values` (or similar) or `call-with-values` .

---

<div class="post-metadata">

**Author:** ![xiaoyu2006](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/xiaoyu2006/32/1682_2.png) [@xiaoyu2006](https://racket.discourse.group/u/xiaoyu2006)\
**Post date:** [March 3, 2024, 2:17pm UTC](https://racket.discourse.group/t/how-to-check-equality-of-values/2758/5 "2024-03-03T14:17:01Z")

</div>

Oh I get this. So values is not a simple data structure but rather some syntax-level stuff?

---

<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:** [March 3, 2024, 2:32pm UTC](https://racket.discourse.group/t/how-to-check-equality-of-values/2758/6 "2024-03-03T14:32:10Z")

</div>

```scheme
#lang racket

;; define in one module 

(define-syntax-rule (equal-values? x y)
  (call-with-values
   (λ () x)
   (λ a
     (call-with-values
      (λ () y)
      (λ b
        (and (equal? (length a) (length b))
             (andmap equal? a b)))))))

;; —————— ———————— ——————— 

;;; import into this module: 

(equal-values? (values 1 2) (values 1 2))

(equal-values? (values 1 2) (values 1 2 3))

```

---

<div class="post-metadata">

**Author:** ![xiaoyu2006](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/xiaoyu2006/32/1682_2.png) [@xiaoyu2006](https://racket.discourse.group/u/xiaoyu2006)\
**Post date:** [March 3, 2024, 3:03pm UTC](https://racket.discourse.group/t/how-to-check-equality-of-values/2758/7 "2024-03-03T15:03:38Z")

</div>

I've worked out my own version too:

```rkt
(define-syntax values-equal?
    (syntax-rules ()
      [(_ a b) (equal? (call-with-values (lambda () a) list)
                             (call-with-values (lambda () b) list))])))

```

---

<div class="post-metadata">

**Author:** ![soegaard](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/soegaard/32/19_2.png) [@soegaard](https://racket.discourse.group/u/soegaard)\
**Post date:** [March 3, 2024, 3:08pm UTC](https://racket.discourse.group/t/how-to-check-equality-of-values/2758/8 "2024-03-03T15:08:41Z")

</div>

> Oh I get this. So values is not a simple data structure but rather some syntax-level stuff?

In a simple stack [1] based implementation return values from function calls are pushed to the stack. [In the following I am ignoring the return address and the argument count.] A call `(+ 1 2)` will push the values 1 and 2 to the stack. Jump to the code implementing +. Here the values 1and 2 will be popped from the stack and the result 3 is pushed to stack  
before returning.

The expression `(values 1 2)` will simply push two values 1 and 2 onto the stack.

The problem with `(equal? (values 1 2) (values 3 4))` is that it pushes 4 values in total to the stack. And `equal?` expects exactly 2 values on the stack.

[1] Since call/cc is available, it's technically a tree.

---

<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:** [March 3, 2024, 5:36pm UTC](https://racket.discourse.group/t/how-to-check-equality-of-values/2758/9 "2024-03-03T17:36:01Z")

</div>

Warning: Rambling ahead.

One of the things I'm not sure if I like about Common Lisp is that extra values returned over the number expected are silently discarded (And if not enough are returned, the extras become `nil`). So `(equal (values 1 2) (values 3 4))` is `nil` in CL, not an error.

There are times I find myself wondering if it'd be possible to emulate that behavior with a `#lang` in Racket by replacing `#%app` etc.

---

<div class="post-metadata">

**Author:** ![soegaard](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/soegaard/32/19_2.png) [@soegaard](https://racket.discourse.group/u/soegaard)\
**Post date:** [March 3, 2024, 10:27pm UTC](https://racket.discourse.group/t/how-to-check-equality-of-values/2758/10 "2024-03-03T22:27:32Z")

</div>

I think, it would be difficult to make a `#lang` based solution without affecting the speed of the compiled code.

If you want a low-level approach.

"An Eﬃcient Implementation of Multiple Return Values in Scheme" by J. Michael Ashley and R. Kent Dybvig

From the introduction:

> In this paper we describe an implementation of the new Scheme multiple values interface that handles multiple values eﬃciently without penalizing code that does not use them or sacriﬁcing our fast implementation of ﬁrst-class continuations. Full run-time error checking is performed to insure that the correct number of values is received in all situations. We also describe how the implementation can be adapted to handle Common Lisp’s multiple values interface.

[https://citeseerx.ist.psu.edu/document?repid=rep1&type=pdf&doi=1490ecc3267e0ff759506ed51f9071ee9fed91a8](https://citeseerx.ist.psu.edu/document?repid=rep1&type=pdf&doi=1490ecc3267e0ff759506ed51f9071ee9fed91a8)

---

<div class="post-metadata">

**Author:** ![jbclements](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/jbclements/32/11_2.png) [@jbclements](https://racket.discourse.group/u/jbclements)\
**Post date:** [March 3, 2024, 11:45pm UTC](https://racket.discourse.group/t/how-to-check-equality-of-values/2758/11 "2024-03-03T23:45:00Z")

</div>

I don't think I would call it syntax-level stuff.

I would say that generally speaking, multiple values are a nifty theoretical side-slip that doesn't actually turn out to be the right solution to most problems.

... quick trip to google scholar ...

I took a quick look, and I see both the Danvy/Danvy-Lawall "Back to Direct Style I/II" papers and also the Sabry/Felleisen papers; I skimmed the Back to Direct Style papers and didn't immediately see anything like "now what if we perform this cps-\>ds transformation on functions of multiple arguments?". Was this part of the work with Amr? Or is it later, with Dybvig or Clinger or someone else?

... okay, back to main point ...

Anyhow, my claim is that the origin of `values` in Scheme is probably related to the train of thought relating to "what if we allow continuations to accept more than one argument? Hey, everything works out, that's pretty cool!"

Unfortunately, multiple values appear to represent an "orthogonal dimension" for most Scheme/Racket code; that is, the vast majority of Scheme/Racket contexts expect exactly one value, so using multiple values nearly always creates a minor headache on the part of the receiver. On the other hand, values do very clearly express the idea that you don't want to use any more memory or create a new compound value, you just want to return two values....

---

<div class="post-metadata">

**Author:** ![xiaoyu2006](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/xiaoyu2006/32/1682_2.png) [@xiaoyu2006](https://racket.discourse.group/u/xiaoyu2006)\
**Post date:** [March 4, 2024, 12:12am UTC](https://racket.discourse.group/t/how-to-check-equality-of-values/2758/12 "2024-03-04T00:12:54Z")

</div>

If this is the case should I use it? I see values being used in racket standard library too, such as `quotient/remainder`

---

<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:** [March 4, 2024, 5:44pm UTC](https://racket.discourse.group/t/how-to-check-equality-of-values/2758/13 "2024-03-04T17:44:59Z")

</div>

I find multiple values very useful. More convenient than packing stuff up in a list/vector/struct and extracting it later.

---

<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:** [March 6, 2024, 12:47am UTC](https://racket.discourse.group/t/how-to-check-equality-of-values/2758/14 "2024-03-06T00:47:55Z")

</div>

> [@shawnw](#):
>
> One of the things I'm not sure if I like about Common Lisp is that extra values returned over the number expected are silently discarded (And if not enough are returned, the extras become `nil`). So `(equal (values 1 2) (values 3 4))` is `nil` in CL, not an error.
> 
> There are times I find myself wondering if it'd be possible to emulate that behavior with a `#lang` in Racket by replacing `#%app` etc.

It is definitely possible to create a Racket language with these semantics. Basically, you would wrap every expression from which you want to discard extra values with something like this:

```scheme
#lang racket
(define (call-as-single-valued thunk)
  (call-with-values thunk
    (case-lambda
      [(v)
       v]
      [()
       #f]
      [(v . more)
       v])))
(define-syntax-rule (as-single-valued expr)
  (call-as-single-valued (λ () expr)))

```

Replacing `#%app` would let you handle function argument expressions, which may be the most important case, but it wouldn't be quite enough in general. For example, in:

```scheme
(let-values ([(a b) e])
  body ...+)

```

a replacement for `#%app` wouldn't have enough information to know that `e` is actually expected to evaluate to two values.

Instead, I think you would want to replace `#%module-begin` to first [fully expand](https://docs.racket-lang.org/reference/syntax-model.html#%28part._fully-expanded%29) the module, then insert wrappers as needed (for example, _not_ around `e1` in `(begin e1 e2)`).

> [@soegaard](#):
>
> I think, it would be difficult to make a `#lang` based solution without affecting the speed of the compiled code.

That is definitely an open question, but it seems possible that the speed penalty might not be severe in common cases. In particular, the compiler has a certain amount of support for recognizing procedures that are known to return a single value, so hopefully it might be able to optimize away `as-single-valued` wrappers in many cases.
