From P.Dalgaard at biostat.ku.dk  Thu Dec 21 15:37:18 2006
From: P.Dalgaard at biostat.ku.dk (Peter Dalgaard)
Date: Thu, 21 Dec 2006 15:37:18 +0100
Subject: [Rd] R windows crash (PR#9426)
In-Reply-To: <Pine.LNX.4.64.0612210729290.14440@itasca2.wildberry.org>
References: <20061221113221.976C841EC7@slim.kubism.ku.dk>
	<Pine.LNX.4.64.0612210729290.14440@itasca2.wildberry.org>
Message-ID: <458A9C1E.6070604@biostat.ku.dk>

Luke Tierney wrote:
> On Thu, 21 Dec 2006, P.Dalgaard at biostat.ku.dk wrote:
>
>   
>> Prof Brian Ripley wrote:
>>     
>>> On Thu, 21 Dec 2006, Peter Dalgaard wrote:
>>>
>>> [...]
>>>
>>>
>>>       
>>>> This seems reproducible on  Linux, except that it goes into an infinite
>>>> loop. The lm call seems to be the real culprit:
>>>>
>>>>
>>>>         
>>>>> testfun <- function(aa=aa) return(aa)
>>>>> testfun()
>>>>>
>>>>>           
>>>> Error in testfun() : recursive default argument reference
>>>>
>>>>         
>>>>> testfun <- function(aa=aa) lm(x~y,data=aa)
>>>>> testfun()
>>>>>
>>>>>           
>>>> (*poof*)
>>>>
>>>>         
>>> The difference is in argument evaluation between closures and internal
>>> functions (c() in my example, return() in yours).
>>>
>>>       
>> Er? I'd rather say that the issue is in the semantics of missing():
>>
>>     
>>> f <- function(x) missing(x)
>>> testfun <- function(aa=aa) f(aa)
>>> testfun()
>>>       
>> Error: segfault from C stack overflow
>>
>> which is a bit nasty. AFAICS the thing is that the logic for detection
>> of recursive arguments works by forcing promises (if you at some point
>> need the result of the same promise you are forcing, you know that
>> something is wrong), but missing() tries hard not to force promises. We
>> already have the following anomaly,
>>
>>     
>>> g <- function(v) missing(v)
>>> f <- function(v) g(v)
>>> f()
>>>       
>> [1] TRUE
>>     
>>> f <- function(v=!h, h=!v) g(v)
>>> f()
>>>       
>> [1] FALSE
>>     
>>> f <- function(v=!h, h) g(v)
>>> f()
>>>       
>> [1] FALSE
>>
>> so the fix could be to realize that we cannot detect missingness in a
>> perfectly reliable way and just pretend that arguments are always
>> non-missing when they have a default.
>>     
>
> We could also mark the promise created for default arguments so it can
> be identified as such and use that info in missing().  Probably worth
> deciding what the intended semantics are here and then figuring out
> the implementation.
>
>   
Yes, always a good idea...

Just to be precise: The current semantics seems to be that we stop and
declare missingness to be FALSE if any sort of computation is involved
in the default:

> f <- function(v=h,h=v) g(v)
> f()
Error: segfault from C stack overflow

but

> f <- function(v=(v)) g(v)
> f()
[1] FALSE



-- 
   O__  ---- Peter Dalgaard             ?ster Farimagsgade 5, Entr.B
  c/ /'_ --- Dept. of Biostatistics     PO Box 2099, 1014 Cph. K
 (*) \(*) -- University of Copenhagen   Denmark          Ph:  (+45) 35327918
~~~~~~~~~~ - (p.dalgaard at biostat.ku.dk)                  FAX: (+45) 35327907



[Rd] R windows crash (PR#9426)
Peter Dalgaard