[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