From lgautier at gmail.com  Sun Jan  3 00:35:00 2010
From: lgautier at gmail.com (Laurent Gautier)
Date: Sun, 03 Jan 2010 00:35:00 +0100
Subject: [Rd] R-devel Digest, Vol 83, Issue 2
In-Reply-To: <4B3FCBA0.40908@dbmail.com>
References: <mailman.11.1262430004.8711.r-devel@r-project.org>	<4B3F7625.1080806@gmail.com>
	<4B3F7ACD.2050106@stats.uwo.ca>	<4B3F7F8D.8060701@gmail.com>	<B38057DF-8452-41FC-9D46-B67FBD58E01C@r-project.org>	<4B3FA43B.1070707@stats.uwo.ca>
	<4B3FA9BB.90302@gmail.com> <4B3FC4C0.6060604@stats.uwo.ca>
	<4B3FCBA0.40908@dbmail.com>
Message-ID: <4B3FD824.9060604@gmail.com>

On 1/2/10 11:41 PM, Romain Francois wrote:
> On 01/02/2010 11:12 PM, Duncan Murdoch wrote:
>>
>> On 02/01/2010 3:16 PM, Laurent Gautier wrote:
>>> On 1/2/10 8:53 PM, Duncan Murdoch wrote:
>>>> Simon Urbanek wrote:
>>>>> On Jan 2, 2010, at 12:17 PM, Laurent Gautier wrote:
>>>>>
>>>>>> On 1/2/10 5:56 PM, Duncan Murdoch wrote:
>>>>>>> On 02/01/2010 11:36 AM, Laurent Gautier wrote:
>>>>>>>> [Disclaimer: what is below reflects my understanding from reading
>>>>>>>> the
>>>>>>>> R source, others will correct where deemed necessary]
>>>>>>>>
>>>>>>>> On 1/2/10 12:00 PM, r-devel-request at r-project.org wrote:
>>>>>> (...)
(...)
>>
>> I don't think I would want to review such a patch (I don't know the
>> memory manager well, I don't know that there is really a case where it
>> matters enough to be worth doing), so I'd say if you don't get a message
>> from a core member volunteering to do so, you should assume it won't be
>> accepted. But that doesn't mean you shouldn't write the code for your
>> own internal use and edification, and if you can put together a demo
>> that shows it really makes a big difference in a realistic situation,
>> you might get a different response.
>>
>> Duncan Murdoch
>
>  From what I understand, this has little to do with the memory manager,
> and resumes to the simple problem "how to remove an object from a list".

I would generalize even further, up to: "how to make a tail recursion 
into an interation" (and that often boils down to writing a for loop - 
little edification to get from it, I suppose... one probably wants to 
write it to see it included).

I see below that you are living up to the enthusiasm claimed, and had a 
shot at it (and even did benchmark to demonstrate the expected benefit - 
impressive).

Let's see what happens with it...


L.

> Something like this, using the amazing inline and inspect packages:
>
> require( inline )
> require( inspect )
>
> remover <- cfunction(signature( list = "language", object =
> "environment" ), '
> if( !isNull( list ) ){
> SEXP x = list ;
> SEXP y ;
> while( CAR(x) != object && CADR(x) != R_NilValue ){
> y = x ;
> x = CDR(x) ;
> }
> if( CAR(x) == object ) SETCDR(y, CDR(x) ) ;
> }
> return list ;
> ', Rcpp=FALSE, verbose=FALSE )
>
> e <- new.env()
> call <- call( "foo", e, e, 1:10, 3 )
> call
> # inspect( call )
> result <- remover( call ,e )
> result
> # inspect( result )
>
> gives this :
>
> foo(10, <environment>, 0, <environment>, 1)
> @0x9f4e0d0 06 LANGSXP [NAM(2)]
> @0x9f4e204 01 SYMSXP [] "foo"
> @0xa907b78 14 REALSXP [NAM(2)] (len=1, tl=1763713056)
> @0x9f4d564 04 ENVSXP [NAM(1)]
> FRAME:
> @0x9e94a10 00 NILSXP [MARK,NAM(2)]
> ENCLOS:
> @0x9eb7b4c 04 ENVSXP [MARK,NAM(2),GP(0x8000)]
> HASHTAB:
> @0x9e94a10 00 NILSXP [MARK,NAM(2)]
> @0xa907b58 14 REALSXP [NAM(2)] (len=1, tl=1936941344)
> @0x9f4d564 04 ENVSXP [NAM(1)]
> FRAME:
> @0x9e94a10 00 NILSXP [MARK,NAM(2)]
> ENCLOS:
> @0x9eb7b4c 04 ENVSXP [MARK,NAM(2),GP(0x8000)]
> HASHTAB:
> @0x9e94a10 00 NILSXP [MARK,NAM(2)]
> @0xa907b38 14 REALSXP [NAM(2)] (len=1, tl=543908709)
> NULL
> ==================
> foo(10, 0, <environment>, 1)
> @0x9f4e0d0 06 LANGSXP [NAM(2)]
> @0x9f4e204 01 SYMSXP [] "foo"
> @0xa907b78 14 REALSXP [NAM(2)] (len=1, tl=1763713056)
> @0xa907b58 14 REALSXP [NAM(2)] (len=1, tl=1936941344)
> @0x9f4d564 04 ENVSXP [NAM(2)]
> FRAME:
> @0x9e94a10 00 NILSXP [MARK,NAM(2)]
> ENCLOS:
> @0x9eb7b4c 04 ENVSXP [MARK,NAM(2),GP(0x8000)]
> HASHTAB:
> @0x9e94a10 00 NILSXP [MARK,NAM(2)]
> @0xa907b38 14 REALSXP [NAM(2)] (len=1, tl=543908709)
> NULL
>
>
>
> so it boils down to this as a replacement to RecursiveRelease :
>
> /**
> * Removes the first instance of object with the list
> */
> static SEXP RemoveFromList( SEXP object, SEXP list){
> if( !isNull( list ) ){
> SEXP x = list ;
> SEXP y ;
> while( CAR(x) != object && CADR(x) != R_NilValue ){
> y = x ;
> x = CDR(x) ;
> }
> if( CAR(x) == object ) SETCDR(y, CDR(x) ) ;
> }
> return list ;
> }
>
>
> Romain
>
>



[Rd] R-devel Digest, Vol 83, Issue 2
Laurent Gautier