[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Scheme-reports] [scheme-reports-wg1] Erratum for letrec* definition

Alex Shinn writes:

> On Sun, Dec 1, 2013 at 12:00 PM, John Cowan wrote:
> > Alex Shinn scripsit:
> >
> > > I'm not sure we need bother clarifying this.  Interleaving
> > > assignment is both the most natural and only realistic
> > > interpretation of the existing text.  You have to stretch
> > > it quite a lot to think that it allows the <init>s to be
> > > evaluated outside the order of the assignments.
> >
> > Well, someone on #scheme was complaining about it being unclear,
> > and when I looked at it, I realized that I had never really
> > understood letrec* before.  He was under the impression that
> > letrec* is to letrec as let* is to let; that is, that letrec*
> > expands to nested letrecs.
> If that is the misconception, then your clarification
> doesn't help - in nested letrecs the order of <init>
> evaluation and variable assignment would be the
> same as it is now.
> Perhaps instead we could just add some more
> examples?  This should help understanding better
> than lengthening the prose.

Not sure what there is already but I donate the following.

;;; Since letrec* was introduced to have the desired top-levelish
;;; meaning of internal definitions, a best example will consist of
;;; internal definitions that are not equivalent to any other _let_
;;; family syntax.

;;; I think the following is reasonable and not too contrived. It
;;; returns the arithmetic, geometric, and harmonic means of a tree (a
;;; list structure) of numbers (positive numbers, and there must be at
;;; least one in the tree). Of the internal definitions, _sum_ is
;;; recursive, the other two (_n_, _mean_) depend on _sum_, and _sum_
;;; must be initialized before _n_. Hence only a _letrec*_ will do.

;;; (Rearranged to define _mean_ before _sum_ so a straightwordard
;;; nesting of _letrec_'s would not work. Mutual recursion would be a
;;; stronger example.)

(define (means ton)
  (define (mean f g)
    (f (/ (sum g ton) n)))
  (define (sum g ton)
    (if (null? ton)
	(if (number? ton)
	    (g ton)
	    (+ (sum g (car ton))
	       (sum g (cdr ton))))))
  (define n (sum (lambda (x) 1) ton))

  (values (mean values values)
	  (mean exp log)
	  (mean / /)))

;;; scheme@(guile-user)> (means '(3 (1 4)))
;;; $42 = 8/3
;;; $43 = 2.28942848510666
;;; $44 = 36/19

Scheme-reports mailing list