Functions & Methods
Introduction
In Vapour functions are declared much differently than they are in R, methods even more so. This is both to make it more readable and easier to parse, R has some oddities with how methods are declared.
In R functions are declared like so:
foo <- function(x) {
  x + 1
}
Whilst this works great for functions it becomes confusing when declaring methods, e.g.:
foo.data.frame <- function(x) {}
In the above, it is actually impossible to tell whether we are declaring:
- A function called 
foo.data.frame - A method 
fooondata.frame - A method 
foo.dataonframe 
Either method declarations should have been done differently,
or R should not have allowed . in function names, and other
identifiers.
Hence, Vapour changes the way functions and methods are declared. The way functions and methods are declared is taken from Go. This is because the way methods are declared and dispatched in Go is very similar to R.
Return
In Vapour return is a keyword rather than a function and is
mandatory.
Inplicitely returning the last the last line is confusing.
Take for instance the function below, it's very hard for anyone to guess what it actually returns.
foo <- function(){
  x <- list()
  x$name <- 2
}
The above actually returns 2.
Confusion only increases when the function makes use of branching.
foo <- function(x = FALSE){
  x <- list()
  if(!x) {
    x$valid <- 1
  } else {
    x$valid <- "hello"
  }
}
Therefore, we make the return keyword mandatory in Vapour.
Functions
Functions are declared with the func keyword,
we indicate the types of each argument as well as the type
the function returns.
In Vapour return is a keyword and is mandatory, this is what
the language uses to know what is returned by functions.
- Vapour
 - R
 
func add(x: int, y: int): int {
  return x + y
}
add = function(x, y) {
  return(x + y)
}
In R functions always return something there is no void,
so use null instead.
- Vapour
 - R
 
func add(x: char): null {
  print(x)
}
add = function(x) {
  return(x)
}
Anonymous Functions
Anonymous functions are declared as shown below, inspired from Javascript,
unlike Javascript Vapour expects curly braces ({}).
- Vapour
 - R
 
lapply(1..10, (x: int): int => {
  return x + 1
})
lapply(1:10, function(x) {
  return(x + 1)
})
Methods
You can define methods on your custom types.
- Vapour
 - R
 
type car struct {
  int,
  name: char
}
func (c: char) print(name: char): car {
  c$name = 1
}
add = function(x) {
  return(x)
}
Class Decorator
You can use the decorator @class to customise the class assigned to your
object if you are not happy with the above.
- Vapour
 - R
 
@class(a, thing, on, wheels)
type vehicle: struct {
  bool,
  name: char
}
let train: vehicle = vehicle(
  false,
  name = "tchoo tchoo"
)
train = structure(
  FALSE,
  name = "tchoo tchoo",
  class = c("a", "thing", "on", "wheels")
)
Generic Decorator
You can use the decorator @generic to define a generic
- Vapour
 - R
 
type user: object {
  id: int,
  name: char
}
@generic
func (u: any) set_id(id: int): any
func (u: user) set_id(id: int): user {
  u$id = id
  return u
}
set_id <- function(u, id) {
  UseMethod("set_id")
}
set_id.user <- function(u, id) {
  u$id = id
  return(user)
}