From guillaume.yziquel at citycable.ch  Mon Nov 30 22:07:13 2009
From: guillaume.yziquel at citycable.ch (Guillaume Yziquel)
Date: Mon, 30 Nov 2009 22:07:13 +0100
Subject: [Rd] PROTECT and OCaml GC.
In-Reply-To: <0A1D8E9D-0BD6-40F7-B98C-59075CE04E49@r-project.org>
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>
Message-ID: <4B143401.4050607@citycable.ch>

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.

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

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.
Guillaume Yziquel