[gambit-list] Somehow missing force call

Marc Feeley feeley at iro.umontreal.ca
Tue Apr 30 21:10:16 EDT 2013


On 2013-04-30, at 8:36 PM, Jason Felice <jason.m.felice at gmail.com> wrote:

> I haven't been able to separate the code from my repo and make it still break, but I found what I imagine is an inlining bug when --enable-auto-force is enabled.
> 
> My repo: https://github.com/maitria/scheme-stuff.git
> 
> $ make
> $ gsi
> > (load "scheme-stuff.o1")
> > (for-each pp (delay (cons 1 (delay (cons 2 '())))))
> 1 2>
> 
> Change lib/iteration.scm:14 and replace end-position? with null? and repeat:
> 
> > (for-each pp (delay (cons 1 (delay (cons 2 '())))))
> *** ERROR IN iteration#for-each -- (Argument 1) PAIR expected
> (car '())
> 1> 
> 
> The definition of end-position? is:
> 
> (define end-position? null?)
> 
> Adding an extraneous force call -- (loop (force (cdr position))) -- will prevent the problem.
> 

Indeed the expansion of your example shows the problem :

% gsc -c -expansion example.scm 
Expansion:

(define for-each
  (lambda (proc iterable)
    (letrec ((loop (lambda (proc position)
                     (if (if ('#<procedure #2 ##eq?> null? '#<procedure #3 null?>)
                             ('#<procedure #4 ##null?> position)
                             (null? position))
                         #!void
                         (let ((begin-temp.0
                                (proc (if (and ('#<procedure #2 ##eq?>
                                                car
                                                '#<procedure #5 car>)
                                               ('#<procedure #6 ##pair?>
                                                position))
                                          ('#<procedure #7 ##car> position)
                                          (car position)))))
                           (loop proc
                                 (if (and ('#<procedure #2 ##eq?>
                                           cdr
                                           '#<procedure #8 cdr>)
                                          ('#<procedure #6 ##pair?> position))
                                     ('#<procedure #9 ##cdr> position)
                                     (cdr position))))))))
      (loop proc (first-position iterable)))))

The problem is the speculative inlining of the null? primitive which calls ##null?, the primitive which tests for an empty list *without* forcing its argument.

That needs to be fixed.

The workaround is to disable the inlining of primitives with the declaration : (declare (not inline-primitives)) .

Marc




More information about the Gambit-list mailing list