Subject: Bug in srfi-11 (?)

From: Tim Gesthuizen <[email-masked]>
Date: Mon, 18 Nov 2019 21:01:17 +0100

Hi,
I was tinkering with srfi-11 and was wondering whether the following
is correct:

> scheme@(guile-user)> ,expand (let-values (((a b c) (values 1 2 3))
> 				  ((d . e) (values 4 5)))
> 		       (list a b c d e))
> $26 = ((@@ (srfi srfi-11) call-with-values)
>  (lambda () (values 1 2 3))
>  (lambda (t-1dff1b83541ce327-16e
>           t-1dff1b83541ce327-16f
>           t-1dff1b83541ce327-170)
>    ((@@ (srfi srfi-11) call-with-values)
>     (lambda () (values 4 5))
>     (lambda (d . e)
>       (let ((t-1dff1b83541ce327-171 d)
>             (t-1dff1b83541ce327-172 e)
>             (a t-1dff1b83541ce327-16e)
>             (b t-1dff1b83541ce327-16f)
>             (c t-1dff1b83541ce327-170))
>         (list a b c d e))))))

This differs from what the comment above the macro definition claims
to expand to.
It seems like the author forgot that he matched the temporaries before
the variables in srfi-11.scm:94.

> diff --git a/module/srfi/srfi-11.scm b/module/srfi/srfi-11.scm
> index 22bda21a2..13a2ffc4d 100644
> --- a/module/srfi/srfi-11.scm
> +++ b/module/srfi/srfi-11.scm
> @@ -95,13 +95,13 @@
>                                 (let lp ((vars (syntax vars)))
>                                   (syntax-case vars ()
>                                     ((id . rest)
> -                                    (acons (syntax id)
> -                                           (car
> +                                    (acons (car
>                                              (generate-temporaries (syntax (id))))
> +                                           (syntax id)
>                                             (lp (syntax rest))))
> -                                   (id (acons (syntax id)
> -                                              (car
> +                                   (id (acons (car
>                                                 (generate-temporaries (syntax (id))))
> +                                              (syntax id)
>                                                '())))))
>                                ((id ...) ids)
>                                ((tmp ...) tmps))

The code "works" anyhow because the lambdas are all nested and the
inner ones capture the parameters of the outer ones.
Which got me thinking why all the messing with temporaries is
neccessary at all. Why is

> (define-syntax let-values
>   (lambda (x)
>     (syntax-case x ()
>       ((_ (clauses ...) b0 b1 ...)
>        (let lp ((clauses #'(clauses ...)))
> 	 (if (null? clauses)
> 	     #'(begin b0 b1 ...)
> 	     (syntax-case (car clauses) ()
> 	       ((args exp)
> 		(with-syntax ((inner (lp (cdr clauses))))
> 		  #'(call-with-values (lambda () exp)
> 		      (lambda args inner)))))))))))

not sufficient? I would not consider my self a Scheme expert and it
could be that I just missed something.
It would be nice if someone could verify whether this is a bug or not.
I am using Guile 2.2.6 on Guix.

Tim.