---
title: "Object Oriented Programming with aoos"
date: "`r Sys.Date()`"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{S4SyntacticSugar}
  %\VignetteEngine{knitr::rmarkdown}
  %\usepackage[utf8]{inputenc}
---

## S4 Generics and Methods

`%g%` and `%m%` are two of the three binary operators, which link to the S4
system for generic functions. They provide alternatives to `methods::setGeneric`
and `methods::setMethod`:
  
```{r}
library("aoos")
# Standard definition for a generic without default:
numeric : strLength(x, ...) %g% standardGeneric("strLength")

# A method for x:character
strLength(x ~ character, ...) %m% { nchar(x) }

# Kind of the default method for x:ANY
strLength(x ~ ANY, ...) %m% { strLength(as.character(x)) }

# Check that it works:
strLength(123)
strLength("ab")
```

You may have noticed that we also constrained the return value of any method
belonging to the generic `strLength` to be a *numeric*. There exist methods
for objects of type *character* and *ANY* type.

In S4, methods can have defaults for arguments which are not formals of the
generic. Otherwise the defaults of the generic are passed down to its methods.
This is not changed: Define defaults for the generic. If a method has more
arguments than its generic you can define defaults for them. For the *shared*
argument names provide a class name. One exception to the rule is `...` which
can have no type. 

## S4 Types

The following presents the function `%type%` which is a link to S4s `setClass`. 
`%type%` tries to abstract a typical scenario of using `setClass`. 

In the following We define two types. One is *Test* which has two fields, *x*
  and *y*. *x* is of type *numeric*, *y* is a *list*. Notice that you can either
define a prototype (a default) for a field (for which the class is inferred), or
you state the class explicitly using `~`.

The second is *Child* and inherits the properties from *Test*. Thus it has
also two fields, *x* and *y*, and in addition we say it inherits from type
*character*. So *Child* is basically a character vector with two attributes:
  
```{r}
Test(x ~ numeric, y = list()) %type% {
  stopifnot(length(.Object@x) == 1)
  stopifnot(.Object@x > 0)
  .Object
}

Test : character : Child() %type% .Object

Test(2)
Child("Hej", x = 2)
```

Notice that the right hand side of the expression is more or less the definition
of the initialization method for a type. Arbitrary operations can be made during 
init, in the above example we formulate some assertions (x > 0 and scalar). The
init method for type *Child* just returns the object itself named `.Object`
(see the help page for `methods::initialize` to understand the naming).

## S4 Type Unions

S4 provides also the possibility to construct type unions which are useful to
allow a type to inherit from different types at the same time, e.g. a type which
can either be a *numeric* or *character*. This feature is not yet complete, but
here are some ways you can use it. For the definition of a type:
  
```{r}
'numeric | character' : Either() %type% .Object
Either(1)
Either("Hello World!")
```

In the definition of a field:
  
```{r}
Either(x ~ numeric | character) %type% .Object
Either(1)
Either("Hello World!")
```

In the definition of a generic or method:
  
```{r}
'numeric | character' : complicatedFunction(x = 1) %g% as.character(x)
complicatedFunction(x ~ character | integer) %m% as.numeric(x)
complicatedFunction()
complicatedFunction("1")
complicatedFunction(1L)
```

## Class Definitions with retList

Basically you define constructor functions. There is no *formal* class
definition. The function body will define what members an object will have. You
quit the function defining the return value using `retList` which is a *generic*
constructor function. By default it will look at the environment from which it
is called and convert that environment into a list. That list is returned and is
an object. Names with a "." are not part of the constructed *list* (by default).

```{r}
library("aoos")
Employee <- function(.name, .salary) {
  "Common base class for all employees"
  
  print <- function(x, ...) {
    cat("Name  : ", .self$.name, "\nSalary: ", .self$.salary)
  }
  
  getName <- function() .name
  getSalary <- function() .self$.salary
  
  retList(c("Employee", "Print"))
  
}

peter <- Employee("Peter", 5)
peter
peter$getName()
peter$getSalary()
```

Here every instance is of class *Employee* and also inherits from class *Print*.
This enables us to define the print method in the functions body and is
equivalent to invoking the print method directly:
  
```{r}
peter
peter$print()
```


### Inheritance

You can inherit methods and fields from a super class, or rather an instance,
because there is no *formal* class definition. Methods and fields can be
replaced in the child, all member from the parent are also available for the
methods of the child.

```{r}
Manager <- function(.name, .salary, .bonus) {
  "Extending the Employee class"
  
  bonus <- function(x) {
    if (!missing(x)) .self$.bonus <- x
    .self$.bonus
  }
  
  print <- function(x, ...) {
    cat("Name  : ", .self$.name, "\nSalary: ", .self$.salary, 
        "\nBonus:", .self$.bonus)
  }
  
  retList("Manager", super = Employee(.name, .salary))
  
}

julia <- Manager("Julia", 5, 5 * 1e6)
julia
julia$getSalary()
julia$bonus(10)
julia
```

### Polymorphic Methods

In contrast to the defaults in S4, `%g%` and `%m%` have side effects in the
environment they are called in. That means you can define generics which are 
local to a function or closure. Nice all by itself but it also extends the
`retList`-idea of representing objects in *R* as demonstrated here:
  
```{r}
Class <- function() {
  
  overloaded(x) %g% { 
    cat("This is the default ... \n")
    x 
  } 
  
  overloaded(x ~ numeric) %m% {
    cat("This is the method for 'numeric' values ... \n")
    x
  }
  
  retList("Class")
}

instance <- Class()
instance$overloaded(1)
instance$overloaded("a")
```

The next question is how to inherit or extend an existing generic which is a
member of a class?
  
```{r}
Child <- function() {
  
  # Normally you would make the call to the parents constructor in the call
  # to retList. But here we need to access the elements directly during init...
  .super <- Class()
  
  # This points %m% to the generic (in .super) which should be extended:
  .super$overloaded(x ~ integer) %m% {
    cat("This is the method for 'integer' values ... \n")
    x
  }
  
  retList("Child", super = .super)
  
}

instance <- Child()
instance$overloaded(1)
instance$overloaded("a")
instance$overloaded(1L)
```