Re: [Rd] Bug in the parser (?) (PR#13504)

From: Wacek Kusnierczyk <Waclaw.Marcin.Kusnierczyk_at_idi.ntnu.no>
Date: Thu, 05 Feb 2009 15:17:07 +0100

johnc.deva_at_yahoo.com wrote:
> Full_Name: John C. Deva
> Version: 2.8.1
> OS: Fedora Linux 8, 64 bit
> Submission from: (NULL) (193.200.150.189)
>
>
> I notice that it is possible to redefine 'if' as a function of an arbitrary
> number of arguments. Such redefined 'if' can then be used as any other user
> function, except for that the parser still demands exactly three arguments to be
> given to if. Furthermore, even if 'if' is defined with three arguments, its
> application must still be made with the original syntax, and not the usual
> syntax of function application:
>
>
>> `if` <- function(a,b,c)
>>
> + {
> + assign(deparse(substitute(a)), b+c, envir=parent.frame()
> + }
>
>
>> if (x) 1 else 2
>> x
>>
> [1] 3
>
>
>> if(x, 1, 2)
>>
> Error: unexpected ',' in "if(x,"
>
> The later expression above should be the only valid when 'if' is redefined as
> above, but it is not the case.
>

i've had a similar question discussed with peter dalgaard (i think) offline (i think), with a close, though less tricky and exotic example. the issue is, when you redefine if, it does not propagate to the parser, which still treats every occurrence of 'if' to be a keyword with the usual syntactic constraints. thus, the only way to apply such redefined if is to use the original if syntax.

arguably, the parser could be parsing 'if' as a regular name in some syntactic contexts, thus making you happily apply it as you want:

if(x) 1else 2 # parse as the conditional keyword 'if', since '1 else 2' is present
if(x) 1 # likewise, since otherwise '1' after 'if(x)' would be syntactically invalid

if() # parse as a function name, in a 0-argument call
if(x) # likewise, a 1-argument call
if(x, 1) # likewise, a 2-argument call
if(x, 1, 2) # likewise, ...

...

now you could redefine and use if as follows, for example (for whatever reason might you wish to have if perform such weird actions):

if = function(...)

    assign(deparse(substitute(a)), sum(...), envir=parent.frame()) # note, no need to quote 'if' for the assignment # if the parser would not force 'if' to be a keyword here

x = 0
if(x) 1 else 2
# 2
if(x) 1
# NULL, invisibly
if(x)
# x is sum()
if(x, 1)
# x is 1
if(x, 1, 2)
# x is 3

or maybe

if = function(if, x) if(if(x)) x else if if(is.integer, 2)
# .Primitive("is.integer")
if(is.integer, 2L)
# 2

you probably don't really need to redefine if this way, or any other way, but the point is valid, imho, and applicable to any other reserved word. it's rather weird that you *can* redefine if and use it as a regular function but with the original syntax, as in your example.

you'll certainly get bashed for the bug report; it's not a bug, rather a design issue, and not necessarily a problem.

vQ



R-devel_at_r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel Received on Thu 05 Feb 2009 - 14:25:00 GMT

Archive maintained by Robert King, hosted by the discipline of statistics at the University of Newcastle, Australia.
Archive generated by hypermail 2.2.0, at Thu 05 Feb 2009 - 14:30:18 GMT.

Mailing list information is available at https://stat.ethz.ch/mailman/listinfo/r-devel. Please read the posting guide before posting to the list.

list of date sections of archive