Re: [Rd] PROTECT and OCaml GC.

From: Simon Urbanek <simon.urbanek_at_r-project.org>
Date: Mon, 30 Nov 2009 14:16:01 -0500

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

R-devel_at_r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel Received on Mon 30 Nov 2009 - 19:18:53 GMT

This archive was generated by hypermail 2.2.0 : Wed 02 Dec 2009 - 02:00:54 GMT