[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