Discarding values

37 views
Skip to first unread message

Jens Axel Søgaard

unread,
Oct 22, 2015, 11:52:29 AM10/22/15
to d...@racket-lang.org
Hi All,

This is an old issue, but as far as I know, there is no convenient to
discard extra values in a context where multiple values are received.

I propose we add first-value, second-value, and, nth-value:

    > (first-value (values 'a 'b 'c))
    'a

    > (second-value (values 'a 'b 'c 'd))
    'b

    > (nth-value    (values 'a 'b 'c 'd) 2)
    'c

The most common use-case for me is discarding extra values from for/fold.

These operations could be implemented like this:

    (define-syntax-rule (first-value expr)
      (call-with-values (λ () expr) (λ (a . _) a)))

    (define-syntax-rule (second-value expr)
      (call-with-values (λ () expr) (λ (a b . _) b)))

    (define-syntax-rule (nth-value expr n)
      (call-with-values (λ () expr)
                        (λ vs
                          (unless (>= (length vs) n)
                            (error 'nth-value (~a "expected at least " n "values")))
                          (list-ref vs n))))

However thinking about the efficiency - it feels wrong to use call-with-values.
Does the optimizer handle call-with-values so well, that first-value and second-value becomes efficient?

/Jens Axel




Sam Tobin-Hochstadt

unread,
Oct 22, 2015, 12:06:34 PM10/22/15
to Jens Axel Søgaard, d...@racket-lang.org
The optimizer doesn't make the `call-with-values` free, but the cost isn't huge. This program: https://gist.github.com/3e306257338f2ec44854 shows about 15% slowdown using your versions over using `let-values` (and requiring a specific number of values).

Sam

--
You received this message because you are subscribed to the Google Groups "Racket Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email to racket-dev+...@googlegroups.com.
To post to this group, send email to racke...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/racket-dev/CABefVgy%2Bzfu0N730TYFXtTsk2kOKsOFrHX6v4B%2B43Zm-ZUkuHw%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

Matthias Felleisen

unread,
Oct 22, 2015, 5:13:19 PM10/22/15
to Sam Tobin-Hochstadt, Jens Axel Søgaard, d...@racket-lang.org, Vincent St-Amour, Leif Andersen

Strange that you're asking.

Last night I ran an experiment of using N values in a for/fold vs running a let-loop approach with N accumulators (handing values only down). The values approach for a program that runs about 20s is basically "free." So I'd use it and check whether it slows things down in an end-to-end measurement. If so, I'd use Vincent's feature-specific profiler to check the cost of call-with-values. It looks like a good candidate.
> To view this discussion on the web visit https://groups.google.com/d/msgid/racket-dev/CAK%3DHD%2BZ8GaGrXyFrfzbCWZTmNi9dXZ2eHjG3eGNAetg83GS4ng%40mail.gmail.com.
Reply all
Reply to author
Forward
0 new messages