chickadee » scheme » base » letrec*

(letrec* <bindings> <body>) syntax

Syntax: <Bindings> has the form ((<variable[1]> <init[1]>) ...), and <body> is a sequence of zero or more definitions followed by one or more expressions as described in section 4.1.4. It is an error for a <variable> to appear more than once in the list of variables being bound.

Semantics: The <variable>s are bound to fresh locations, each <variable> is assigned in left-to-right order to the result of evaluating the corresponding <init> (interleaving evaluations and assignments), the <body> is evaluated in the resulting environment, and the values of the last expression in <body> are returned. Despite the left-to-right evaluation and assignment order, each binding of a <variable> has the entire letrec* expression as its region, making it possible to define mutually recursive procedures.

If it is not possible to evaluate each <init> without assigning or referring to the value of the corresponding <variable> or the <variable> of any of the bindings that follow it in <bindings>, it is an error. Another restriction is that it is an error to invoke the continuation of an <init> more than once.

 ;; Returns the arithmetic, geometric, and
 ;; harmonic means of a nested list of numbers
 (define (means ton)
   (letrec*
      ((mean
         (lambda (f g)
           (f (/ (sum g ton) n))))
       (sum
         (lambda (g ton)
           (if (null? ton)
             (+)
             (if (number? ton)
                 (g ton)
                 (+ (sum g (car ton))
                    (sum g (cdr ton)))))))
       (n (sum (lambda (x) 1) ton)))
     (values (mean values values)
             (mean exp log)
             (mean / /))))

Evaluating (means '(3 (1 4))) returns three values: 8/3, 2.28942848510666 (approximately), and 36/19.