<div dir="ltr"><div>thank you! that explains it.<br><br></div>-- vyzo<br></div><div class="gmail_extra"><br><div class="gmail_quote">On Sun, Mar 25, 2018 at 3:05 PM, Marc Feeley <span dir="ltr"><<a href="mailto:feeley@iro.umontreal.ca" target="_blank">feeley@iro.umontreal.ca</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">The body of ##force in lib/_std.scm is actually dead code (because ##force is an inlined primitive), and as you have noticed the body contains a bug.<br>
<br>
The actual implementation of ##force is in include/<a href="http://gambit.h.in" rel="noreferrer" target="_blank">gambit.h.in</a> :<br>
<br>
#define ___FORCE1(n,src) \<br>
if (___TYP((___temp=(src)))==___<wbr>tSUBTYPED&&___SUBTYPE(___temp)<wbr>==___FIX(___sPROMISE)){___ps-><wbr>temp1=___LBL(n);___ps->temp2=_<wbr>__temp;___JUMPEXTPRM(___<wbr>NOTHING,___GSTATE->handler_<wbr>force);<br>
#define ___FORCE2 ___temp=___ps->temp2;}<br>
#define ___FORCE3 ___temp<br>
<br>
and lib/_kernel.scm :<br>
<br>
…<br>
  (##c-code #<<end-of-code<br>
<br>
   /*<br>
    * ___LBL(10)<br>
    *<br>
    * This is the force handler.  It is invoked when a promise is forced.<br>
    */<br>
<br>
   ___SCMOBJ ra;<br>
   ___SCMOBJ promise;<br>
   ___SCMOBJ result;<br>
<br>
   ra = ___ps->temp1;<br>
   promise = ___ps->temp2;<br>
   result = ___FIELD(promise,___PROMISE_<wbr>RESULT);<br>
<br>
   if (promise != result)<br>
     {<br>
       /* promise is determined, return cached result */<br>
<br>
       ___COVER_FORCE_HANDLER_<wbr>DETERMINED;<br>
<br>
       ___ps->temp2 = result;<br>
       ___JUMPEXTPRM(___NOTHING,ra)<br>
     }<br>
   else<br>
     {<br>
       /* promise is not determined */<br>
<br>
       /* setup internal return continuation frame */<br>
<br>
       int fs;<br>
<br>
       ___RETI_GET_CFS(ra,fs)<br>
<br>
       ___ADJFP(___ROUND_TO_MULT(fs,_<wbr>__FRAME_ALIGN)-fs)<br>
<br>
       ___PUSH_REGS /* push all GVM registers (live or not) */<br>
       ___PUSH(ra)  /* push return address */<br>
<br>
       ___ADJFP(-___RETI_RA)<br>
<br>
       ___SET_R0(___GSTATE->internal_<wbr>return)<br>
<br>
       /* tail call to ##force-undetermined */<br>
<br>
       ___PUSH_ARGS2(promise,___<wbr>FIELD(promise,___PROMISE_<wbr>THUNK))<br>
<br>
       ___COVER_FORCE_HANDLER_NOT_<wbr>DETERMINED;<br>
<br>
       ___JUMPPRM(___SET_NARGS(2),<br>
                  ___PRMCELL(___G__23__23_force_<wbr>2d_undetermined.prm))<br>
     }<br>
<br>
end-of-code<br>
…<br>
<br>
;;; Implementation of promises.<br>
<br>
(define-prim (##make-promise thunk))<br>
(define-prim (##promise-thunk promise))<br>
(define-prim (##promise-thunk-set! promise thunk))<br>
(define-prim (##promise-result promise))<br>
(define-prim (##promise-result-set! promise result))<br>
<br>
(define-prim (##force-undetermined promise thunk)<br>
  (let ((result (##force (thunk))))<br>
    (##c-code #<<end-of-code<br>
<br>
     if (___PROMISERESULT(___ARG1) == ___ARG1)<br>
       {<br>
         ___PROMISERESULTSET(___ARG1,__<wbr>_ARG2)<br>
         ___PROMISETHUNKSET(___ARG1,___<wbr>FAL)<br>
       }<br>
     ___RESULT = ___PROMISERESULT(___ARG1);<br>
<br>
end-of-code<br>
<br>
     promise<br>
     result)))<br>
<br>
))<br>
<span class="HOEnZb"><font color="#888888"><br>
<br>
Marc<br>
</font></span><div class="HOEnZb"><div class="h5"><br>
<br>
<br>
> On Mar 25, 2018, at 3:45 AM, Dimitris Vyzovitis <<a href="mailto:vyzo@hackzen.org">vyzo@hackzen.org</a>> wrote:<br>
><br>
> Marc,<br>
><br>
> in _std.scm you have the following code implementing force:<br>
><br>
> (define-prim (##force obj)<br>
>   (if (##promise? obj)<br>
>       (let ((result (##promise-result obj)))<br>
>         (if (##eq? result obj)<br>
>             (let* ((r ((##promise-thunk obj)))<br>
>                    (result2 (##promise-result obj)))<br>
>               (if (##eq? result2 obj)<br>
>                   (begin<br>
>                     (##promise-result-set! obj r)<br>
>                     (##promise-thunk-set! obj #f)<br>
>                     r)<br>
>                   result2))))<br>
>             ;; XXX -- value is unspecified when (not (##eq? result obj))<br>
>       obj))<br>
><br>
> I find it very strange that the first if eq test of the result to the promise is lacking the else part;<br>
> that's where I marked with XXX.<br>
> Shouldn't the code return result in this case?<br>
> What am I missing here?<br>
><br>
> -- vyzo<br>
<br>
</div></div></blockquote></div><br></div>