From simon.urbanek at r-project.org  Mon Nov 30 22:25:59 2009
From: simon.urbanek at r-project.org (Simon Urbanek)
Date: Mon, 30 Nov 2009 16:25:59 -0500
Subject: [Rd] PROTECT and OCaml GC.
In-Reply-To: <4B143401.4050607@citycable.ch>
References: <4B11B75C.9070806@citycable.ch>
	<8ec76080911281625q5d5b8824hefb14af9b23d29f0@mail.gmail.com>
	<4B11C55E.2060909@citycable.ch>
	<F11B6C18-26EC-41F8-9EEB-A614D16945AC@r-project.org>
	<4B12C417.1050308@citycable.ch>
	<65D411CD-34C3-4B89-8FF0-98C9BD7613FB@r-project.org>
	<4B13FC0F.40604@citycable.ch>
	<F60B92C3-5989-404C-8FEB-1B6002824449@r-project.org>
	<4B140B7A.2080102@citycable.ch>
	<0A1D8E9D-0BD6-40F7-B98C-59075CE04E49@r-project.org>
	<4B143401.4050607@citycable.ch>
Message-ID: <7971A8AF-189B-4955-9E62-4E118E594792@r-project.org>


On Nov 30, 2009, at 16:07 , Guillaume Yziquel wrote:

> Simon Urbanek a ?crit :
>>>
>>> And it goes then to my other question: How can you pass to eval a  
>>> LANGSXP where the CAR is an *anonymous* function, no SYMSXP  
>>> involved?
>> You just pass it as value of the call. I suspect the reason it  
>> doesn't work is in your code, not in the facility (note that the  
>> link above is useless since the construction is mystery - if you  
>> were constructing it right, it would work ;)).
>> Small example:
>> SEXP myEval(SEXP FN, SEXP first_arg) {
>>  return eval(LCONS(FN, CONS(first_arg, R_NilValue)), R_GlobalEnv);
>> }
>> > .Call("myEval",function(x) x + 1, 10)
>> [1] 11
>
> In the eval function in eval.c, you have:
>
>>    case LANGSXP:
>>        if (TYPEOF(CAR(e)) == SYMSXP)
>>            /* This will throw an error if the function is not found  
>> */
>>            PROTECT(op = findFun(CAR(e), rho));
>>        else
>>            PROTECT(op = eval(CAR(e), rho));
>
> So imagine you have a LANGSXP whose CAR is a CLOSXP, the execution  
> goes into the last line of the code snippet above.
> And re-entring eval with a CLOSXP, the code goes into
>
>>    tmp = R_NilValue;           /* -Wall */
>> #ifdef Win32
>>    /* This is an inlined version of Rwin_fpreset (src/gnuwin/extra.c)
>>       and resets the precision, rounding and exception modes of a  
>> ix86
>>       fpu.
>>     */
>>    __asm__ ( "fninit" );
>> #endif
>>    R_Visible = TRUE;
>>    switch (TYPEOF(e)) {
>>    case NILSXP:
>>    case LISTSXP:
>>    case LGLSXP:
>>    case INTSXP:
>>    case REALSXP:
>>    case STRSXP:
>>    case CPLXSXP:
>>    case RAWSXP:
>>    case S4SXP:
>>    case SPECIALSXP:
>>    case BUILTINSXP:
>>    case ENVSXP:
>>    case CLOSXP:
>>    case VECSXP:
>>    case EXTPTRSXP:
>
> so PROTECT(op = eval(CAR(e), rho)) evaluates to R_NilValue.
>

Nope, it simply evaluates to itself (with ref count increased) - see  
tmp = e; ..; return(tmp).


> I figured out that's why evaluating a LANGSXP with CAR a CLOSXP  
> simply fails.
>

Wrong ;). A closure is a constant like any other object so it  
evaluates to itself.

Cheers,
Simon



> I'll have a look at the code snippet you gave, since I do not  
> understand why it doesn't fail the same way mine does.
>
> Thanks a lot.
>
> -- 
>     Guillaume Yziquel
> http://yziquel.homelinux.org/
>
>



[Rd] PROTECT and OCaml GC.
Simon Urbanek