<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>