From ripley at stats.ox.ac.uk  Fri Mar 14 07:51:40 2008
From: ripley at stats.ox.ac.uk (Prof Brian Ripley)
Date: Fri, 14 Mar 2008 06:51:40 +0000 (GMT)
Subject: [Rd] Making custom unary operators in R
In-Reply-To: <OFCCA59E6A.E6373F4C-ON8525740B.0074C70B-8525740B.0077F346@frbog.frb.gov>
References: <OFCCA59E6A.E6373F4C-ON8525740B.0074C70B-8525740B.0077F346@frbog.frb.gov>
Message-ID: <alpine.LFD.1.00.0803140648540.2165@gannet.stats.ox.ac.uk>

The issue here is the parser:  ? works because the parser knows about it. 
To allow further unary operators would need a parser change.

On Thu, 13 Mar 2008, Trevor.L.Davis at frb.gov wrote:

> Hello,
>
> Is there a way to define a custom unary operator in R (other than making a
> class and 'overloading' the normal unary operators in R)?  The
> documentation seems to suggest that only custom binary operators are
> possible with the ``%abc%``construct but I was wondering whether any one
> has done so.  None of the RSiteSearch or RSeek queries I posed suggested
> that this question had been asked before but if it has, a link to the
> relevant discussion thread would be wonderful.
>
> For example in the J language the ``! `` sign is a unary operator for the
> factorial function and a binary operator for the choose function so I
> would like to be able to define a similar operator like this::
>
>    '%!%' <-  function(e1, e2) {
>           if (missing(e2)) factorial(e1)
>           else choose(e2, e1)
>           }
>
> The binary version of the operator works fine:
>
>    > 2 %!% 4
>    [1] 6
>
> But the unary one doesn't (which is perfectly understandable since there
> is no indication in any documentation I have seen that suggests it
> should):::
>
>    > %!% 4
>    Error: unexpected SPECIAL in "%!%"
>
> The source code for the '?' operator almost seems to suggest that a mixed
> unary / binary non-primitive R function is possible::
>
>    > get('?')
>    function (e1, e2)
>    {
>        e1Expr <- substitute(e1)
>        if (missing(e2)) {
>            if (is.call(e1Expr))
>                return(.helpForCall(e1Expr, parent.frame()))
>            if (is.name(e1Expr))
>                e1 <- as.character(e1Expr)
>            eval(substitute(help(TOPIC), list(TOPIC = e1)))
>        }
>        else {
>            if (is.name(e1Expr))
>                e1 <- as.character(e1Expr)
>            e2Expr <- substitute(e2)
>            if (is.name(e2Expr))
>                e2 <- as.character(e2Expr)
>            else if (is.call(e2Expr) && identical(e1, "method"))
>               return(.helpForCall(e2Expr, parent.frame(), FALSE))
>            topic <- topicName(e1, e2)
>            doHelp <- .tryHelp(topic)
>            if (inherits(doHelp, "try-error")) {
>                stop(gettextf("no documentation of type '%s' and topic
> '%s' (or error in processing help)",
>                    e1, e2), domain = NA)
>            }
>        }
>    }
>    <environment: namespace:utils>
>
> I was playing around with the idea of the ways one could try build a J
> interpreter with R and it seemed like being able to define custom unary /
> binary operators like that could be convenient.
>
> Thanks,
>
> Trevor Davis
> Federal Reserve Board of Governors
>
> ______________________________________________
> R-devel at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel
>

-- 
Brian D. Ripley,                  ripley at stats.ox.ac.uk
Professor of Applied Statistics,  http://www.stats.ox.ac.uk/~ripley/
University of Oxford,             Tel:  +44 1865 272861 (self)
1 South Parks Road,                     +44 1865 272866 (PA)
Oxford OX1 3TG, UK                Fax:  +44 1865 272595



[Rd] Making custom unary operators in R
Prof Brian Ripley