[racket] Multiple return values

From: Neil Toronto (neil.toronto at gmail.com)
Date: Thu Dec 15 17:32:33 EST 2011

On 12/15/2011 05:03 AM, Markku Rontu wrote:
> Named return values, ah the dream of symmetry.

I think my mad-scientist advisor did something like this once. I think 
it would be awesome to have this, and of course keyword arguments, as 
first-class constructs in Racket.

(As far as I understand, the macros that expand lambdas with keyword 
arguments would be a major PITA to write in C, and would be almost 
certainly buggy for years. We'll need a bootstrapping compiler first.)

Anyway, back to the question. Symmetry + GENERALITY is one main reason. 
A first-class continuation acts a lot like a procedure. Generalizing a 
bit, continuations should take multiple arguments. Invoking a 
multiple-argument continuation is equivalent to returning multiple 
values to the spot it was captured; we therefore need multiple values if 
we want to generalize continuations.

Another reason is efficiency. I'm writing a simple ray tracer for 2D 
image + depth-map effects. (Think shiny icons, logos and slideshows.) 
Here's my code for extracting the min and max values from a depth map:

(define (flimage-extrema img)
   (match-define (flimage vs d w h) img)
   (for/fold ([v-min 0.0] [v-max 0.0]) ([v  (in-flvector vs)])
     (values (unsafe-flmin v-min v)
             (unsafe-flmax v-max v))))

This, like all the other ray tracer code, has to run fast. In general, 
getting good speed means 1) no boxing flonums; and more generally 2) no 
allocating. If I didn't have multiple values I'd have three options:

   A. Use mutation. Fast enough but undesirable. Makes code harder for
      me and the compiler to reason about.
   B. Put them in a pair or list. Slow. Allocates a container and boxes
      the flonums `v-min' and `v-max' in every iteration.
   C. Make two passes. Duplicates code and computations. Makes me cranky.

As it is, I believe Racket's JIT can prove that no flonums need boxing, 
so this loop avoids allocation entirely.

Neil T

Posted on the users mailing list.