unofficial mirror of guile-devel@gnu.org 
 help / color / mirror / Atom feed
* Re: Do-loop enigma with two variables
       [not found] <5788F2A8.8000803@gmail.com>
@ 2016-07-16  8:55 ` Taylan Ulrich Bayırlı/Kammer
  0 siblings, 0 replies; only message in thread
From: Taylan Ulrich Bayırlı/Kammer @ 2016-07-16  8:55 UTC (permalink / raw)
  To: Pierre Lairez; +Cc: guile-user, guile-devel

Pierre Lairez <pierre.lairez@gmail.com> writes:

> Dear guile users,
>
> When running the following loop:
> (do ((i 1 (+ 1 i))
>      (j 0 i))
>     ((> i 4) (newline))
>   (display (list i j)))
>
> I expect without hesitation to read
> (1 0)(2 1)(3 2)(4 3)
>
> To my surprise, I obtain
> (1 0)(2 2)(3 3)(4 4)
>
> After macro-expansion, the loop above is rewritten in the following:
> (letrec ((loop
>           (λ (i j)
>             (if (> i 4)
>                 (newline)
>                 (begin
>                   (display (list i j))
>                   (loop (+ 1 i) i))))))
>   (loop 1 0))
>
> The equality j = i + 1 is clearly a loop invariant, the function “loop“
> is *never* called with two equal arguments. So I cannot understand why
> (2 2) may possibly appear in the output. What do I not see?
>
> Best regards,
>
> Pierre

I suspect this is a bug in the optimizer; guile-devel CC'd.

Using 2.0.11 (gotta upgrade!):

scheme@(guile-user)> ,expand (do ((i 1 (+ 1 i))
                                  (j 0 i))
                                 ((> i 4) (newline))
                               (display (list i j)))
$5 = (let loop ((i 1) (j 0))
  (if (> i 4)
    (begin (if #f #f) (newline))
    (begin (display (list i j)) (loop (+ 1 i) i))))

;; Looks good to me.  Let's use the interpreter on it:

scheme@(guile-user)> (eval '(let loop ((i 1) (j 0))
                              (if (> i 4)
                                  (begin (if #f #f) (newline))
                                  (begin (display (list i j)) (loop (+ 1 i) i))))
                           ((@ (rnrs eval) environment) '(guile)))
(1 0)(2 1)(3 2)(4 3)

;; Looks good to me as well.  Now the compiler's optimizer:

scheme@(guile-user)> ,optimize (let loop ((i 1) (j 0))
                                 (if (> i 4)
                                     (begin (if #f #f) (newline))
                                     (begin (display (list i j)) (loop (+ 1 i) i))))
$6 = (begin
  (display (list 1 0))
  (begin
    (display (list 2 2))
    (begin
      (display (list 3 3))
      (begin (display (list 4 4)) (newline)))))

;; Beep!

(Note that the Guile REPL compiles the given expressions by default.)

Taylan



^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2016-07-16  8:55 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <5788F2A8.8000803@gmail.com>
2016-07-16  8:55 ` Do-loop enigma with two variables Taylan Ulrich Bayırlı/Kammer

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).