Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to define operator without %%?

In R user-defined operators are allowed, but it seems that only % % like operators are accepted. Is it possible to walk around this restriction to define operators like, for example, >>, or something that is not like % %?

The operator must be a real operator so that we can use it like 1 >> 2 and do not have to use it like ">>"(1,2).

like image 590
Kun Ren Avatar asked Jul 11 '14 12:07

Kun Ren


People also ask

What is a user-defined operator?

A user-defined operator is a top-level schema object. In many ways, user-defined operators act like the built-in operators such as <, >, and =; for instance, they can be invoked in all the same situations. They contribute to ease of use by simplifying SQL statements, making them shorter and more readable. User-defined operators are:

What does the operator contains () do in Oracle?

If Contains () is used in Example 9-7, the operator invocation Contains (resume, 'Oracle') causes Oracle to execute the function text.contains (resume, 'Oracle') because the signature of the function matches the data types of the operator arguments.

How do I drop an operator from a function?

Example 9-1 creates the operator Contains (), binding it to functions that provide implementations in the Text and Spatial domains. To drop an operator and all its bindings, specify its name with the DROP OPERATOR statement. Example 9-2 drops the operator Contains ().

What happens when an operator is invoked in Oracle?

When an operator is invoked, Oracle evaluates the operator by executing a function bound to it. When several functions are bound to the operator, Oracle executes the function whose argument data types match those of the invocation (after any implicit type conversions).


2 Answers

No. R only allows you to

  1. redefine existing operators (such as `+` or, indeed, `<-`), and
  2. define new infix operators by surrounding them with %…%.

These are the rules we have to play by. However, inside these rules all is fair game. For instance, we can redefine `+` for character strings to perform concatenation, without destroying its normal meaning (addition):

`+`
# function (e1, e2)  .Primitive("+")

This is the old definition, which we want to preserve for numbers:

`+.default` = .Primitive('+')
`+.character` = paste0`1
`+` = function (e1, e2) UseMethod('+')
1 + 2
# [1] 3
'hello' + 'world'
# [1] "helloworld"

This exploits the S3 class system in R to make `+` fully generic on the type of its first argument.

The list of operators that can thus be redefined is quite eclectic. At first count, it contains the following operators:

+, -, *, /, ^, &, |, :, ::, :::, $, =, <-, <<-, ==, <, <=, >, >=, !=, ~, &&, ||, !, ?, @, :=, (, {, [, [[

(From the {modules} source code.)

In this list, one particular operator is noteworthy: `:=` is an overridable operator (and {data.table} for example uses it) but unlike most the other operators in this list it has no default implementation.

Similarly, you can define assignment versions of pretty much every operator, not just those with a predefined assignment (such as `[<-`). For example, `(<-` and `{<-` are also missing a default implementation. This is why the following code fails:

a = 1
(a) = 2
# Error in (a) = 2 : could not find function "(<-"
{a} = 3
# Error in { : could not find function "{<-"

But the code can be made to work by defining the operators:

`(<-` = `{<-` = function (x, value) value

The same works for every function, including almost all operators1, and even control structures (see the comments below this answer).

By contrast, `**` isn’t a real operator: it’s a syntactic alias for `^`. Users can define their own `**` function but it can’t be called via the code a ** b so it’s not an overridable operator (except via overriding `^`).

In the same vein, you can override -> (only) by redefining <-. This seems like it would rarely make sense — but at least one good example of this exists, to define less verbose lambdas:

> sapply(1 : 4, x -> 2 * x)
[1] 2 4 6 8

Implementation as a gist


1 The only exception are the assignment operators: You cannot change the meaning of a <- b <- c by redefining `<-<-` (and the same for `=<-`, `<<-` and `:=`), due to the language’s operator precedence and associativity rules. However, the following code invokes both `(<-` and `<-<-`, and fails if either of these is not defined:

(a <- b) <- c

Messed up.

like image 118
Konrad Rudolph Avatar answered Oct 01 '22 17:10

Konrad Rudolph


You can do things like this, but you may want to assign these objects to a new environment to be safe.

> "^" <- function(x, y) `-`(x, y)  ## subtract y from x
> 5 ^ 3
# [1] 2

> "?" <- function(x, y) sum(x, y)  ## add x and y
> 5 ? 5
# [1] 10
like image 39
Rich Scriven Avatar answered Oct 01 '22 16:10

Rich Scriven