[Rd] PROTECT and OCaml GC.

Simon Urbanek simon.urbanek at r-project.org
Mon Nov 30 20:16:01 CET 2009


On Nov 30, 2009, at 13:14 , Guillaume Yziquel wrote:

> Simon Urbanek a écrit :
>>> Because I've been unable to find what exactly applyClosure or eval  
>>> requires, when it comes to the structure of the argument LANGSXP.  
>>> For example.
>>>
>> LANGSXP is simply a pairlist representing the expression, e.g. to  
>> look at "a+2" expression:
>> > .Internal(inspect(quote(a+2)))
>> @1183698 06 LANGSXP g0c0 []
>>  @101080c 01 SYMSXP g0c0 [MARK,gp=0x4000] "+"
>>  @1130394 01 SYMSXP g0c0 [MARK] "a"
>>  @1c384e8 14 REALSXP g0c1 [] (len=1, tl=0) 2
>> I would suggest you learn more about R first - this is all  
>> accessible at the R/S language level:
>> > x
>> a + 2
>> > x[[1]]
>> `+`
>> > x[[2]]
>> a
>> > x[[3]]
>> [1] 2
>
> I've gathered that LANGSXP and LISTSXP are structured in this way.  
> By reading the header files. Please see:
>
> https://stat.ethz.ch/pipermail/r-devel/2009-November/055813.html
>
> Now to continue one the topic of the top paragraph:
>
> I've tried sending a LANGSXP where the CAR element is a SYMSXP. eval  
> workd. I've tried sending a LANGSXP where the CAR element is a  
> CLOSXP. eval doesn't work. This is what I meant about the "structure  
> of the argument LANGSXP". And it's contained in the link above.
>
> 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

 > .Internal(inspect(function(x) x + 1))
@19e376c 03 CLOSXP g0c0 [ATT]
FORMALS:
   @19e399c 02 LISTSXP g0c0 []
     TAG: @1029840 01 SYMSXP g0c0 [MARK,NAM(2)] "x"
     @1007378 01 SYMSXP g0c0 [MARK,NAM(2)] ""
BODY:
   @19e3948 06 LANGSXP g0c0 []
     @101080c 01 SYMSXP g0c0 [MARK,gp=0x4000] "+"
     @1029840 01 SYMSXP g0c0 [MARK,NAM(2)] "x"
     @19e1248 14 REALSXP g0c1 [] (len=1, tl=27187120) 1
CLOENV:
   @1023c38 04 ENVSXP g0c0 [MARK,NAM(2),gp=0x8000]
ATTRIB:
   @19e3750 02 LISTSXP g0c0 []
     TAG: @1006ee0 01 SYMSXP g0c0 [MARK,gp=0x4000] "source"
     @19e1228 16 STRSXP g0c1 [] (len=1, tl=16806832)
       @150cdc8 09 CHARSXP g0c3 [gp=0x20] "function(x) x + 1"


> This does not seem documented in R-ints.pdf, R-exts.pdf or R-lang.pdf.
>
>>> Suppose I have an OCaml (or pure C if you wish) linked list of  
>>> OCaml value wrapping SEXP values. Is it possible, using only the  
>>> API, to create a LANGSXP / LISTSXP list out of these SEXPs?
>> Of course - see CONS/LCONS.
>
> Great. That's the kind of fruitful interaction that could have made  
> me gain a few days and not bypass the API. Thanks.
>

... or reading R-ext:

"There are a series of small macros/functions to help construct  
pairlists and language objects (whose internal structures just differ  
by SEXPTYPE. Function CONS(u, v) is the basic building block: is  
constructs a pairlist from u followed by v (which is a pairlist or  
R_NilValue). LCONS is a variant that constructs a language object.  
Functions list1 to list4 construct a pairlist from one to four items,  
andlang1 to lang4 do the same for a language object (a function to  
call plus zero to three arguments). Function elt and lastElt find the  
ith element and the last element of a pairlist, and nthcdr returns a  
pointer to the nth position in the pairlist (whose CAR is the nth  
item)."


>>> The "general" aspect of my request therefore concerns bindings to  
>>> languages with 'inferred polymorphic static typing'. Please  
>>> understand what these languages are about before dismissing my  
>>> remarks as "my way". You may not care, you wouldn't be the first.
>> You're missing my point - "your way" was to hack into the internals  
>> of how R represents SEXPs (going down to each pointer inside the  
>> SEXP headers). None of the above applies to my remark.
>> Cheers,
>> Simon
>
> You're also missing my point. "my way" is the only way I've come up  
> with to examine how to make sure that the static typing system I'm  
> putting in place fits with the internal structure of SEXPs. I do  
> need to know the internal structure of sexps and the way they evolve  
> under the influence of function such as eval, install, applyClosure,  
> in order to statically type my code. Same link expressing this  
> concern:

No, you don't - you do care what the *types* are (i.e. TYPEOF) and how  
they behave, but you should *not* care how they are implemented in the  
internals. That is deliberately hidden by the API.


> https://stat.ethz.ch/pipermail/r-devel/2009-November/055813.html
>
> Documentation is terse on precise structure of sexps. You get  
> description of individual sexps, not a *precise* description of how  
> they are assembled, which is what the typing will have to express.

Hopefully not - again, see above comment.

Cheers,
Simon


> Much in the same spirit as the link below, which I really entice you  
> to read:
>
> http://ocsigen.org/eliom/manual/1.2.0/1#p1baseprinciples
>
> Statically typing the internal structure of assembled sexps is no  
> different than statically typing XHTML.
>
> Glad that we're heading somewhere...
>
> All the best,
>
> -- 
>     Guillaume Yziquel
> http://yziquel.homelinux.org/
>
>



More information about the R-devel mailing list