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
foo
ondata.frame
- A method
foo.data
onframe
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)
}