Function Declaration
Components of Function's Declaration
Function's declaration consists of several part:
The name of the function
The arguments of the function
The output type of the function
The body of the function
For instance, to declare a function add
which add up two numbers:
The name of the function is
add
There will be 2 arguments, both of them are
Num
typeThe output type will be
Num
The body part should define the process of addition
def add(x: Num, y: Num): Num do
x + y
end
Declaration Syntax
"Do-Block" Declaration
If the body of the function is a do
block, you should always end it with the keyword end
. On the other hand, the return value of the function will be evaluated by the last line in the body of the function, which means that the example:
def example(x: Num, y: Num): Num do
Num foo = x + y
foo * 2
end
Will be compiled into:
function example(x, y) {
const foo = x + y;
return foo * 2;
}
"One-Liner Arrow" Declaration
Similar to conditional expressions in Wyrd, if the body of the function is simple enough to express the evaluation result using only one line, you can choose to use the arrow syntax:
def add(x: Num, y: Num): Num => x + y
Functions Without Arguments
Sometimes function can declared without input arguments. In this case you don't need to also provide the parentheses, only the output type is needed after the name of the function:
def greet: Str => "Hello world!"
# or
def greet: Str do
"Hello world!"
end
TODO: There's a bug where if you provide with empty parentheses, the compilation will stuck, check out the issue.
Returned Result Type Checking
If the function declared result aren't matched with the definition of the function, it will raise an error:
def shouldReturnNumber: Num => "123"
Return type of function `shouldReturnNumber` should be `Num`, instead got: `Str`
Function Overriding
Function Redeclaration is Prohibited
If a function (along with its argument types and output types) is declared twice, Wyrd will raise the error:
def add(x: Num, y: Num): Num => x + y
# Declare function `add` with same input arguments
def add(a: Num, b: Num): Num => a + b
ParserError: Overriding function `add` with existing input pattern `Num.Num`; to override the function, address it with `override` keyword before `def` token
By inspecting the error message, we can actually instead of declaring the function, we can explicitly overriding it.
Overriding Function
To override a function, we just simply add the override
keyword before the def
keyword:
def add(x: Num, y: Num): Num => x + y
# Declare function `add` with same input arguments
override def add(a: Num, b: Num): Num => a + b
The reason why Wyrd demand this approach is because, not only to express that the function actually has predeclared, but also developer choose to intentionally overriding it.
Before and After Overrode Function
Wyrd will make sure that only after function overriding, the invoked function will be the overrode version.
def greet(msg: Str): Str => msg
# Invokes the original version of the function
greet("I'm Max!")
# => I'm Max!
override def greet(msg: Str): Str do
"Hello! ".concat(msg)
end
# Invokes the overrode version of the function
greet("I'm Max!")
# Hello! I'm Max!
Allows Change of Output Types
One benefit of overriding a function might be the ability of changing the output type of the function:
# Original Function
def add(x: Num, y: Num): Num do
x + y
end
# Override Function
override def add(x: Num, y: Num): Str do
(x + y).toStr()
end
However, you might also need to be cautious about this kind of practice since the change of output type might result modified behavior of program.
Function Overloading
Identical Function Name with Different Arguments Pattern
Similar to function overriding, instead we can declare functions of same name with different input arguments type pattern.
# Input Pattern: Num.Num => Num
def add(x: Num, y: Num): Num do
x + y
end
# Input Pattern Num.Num.Num => Num
def add(x: Num, y: Num, z: Num): Num do
x + y + z
end
This technique is called function overloading. In this case, function can have more possible ways to be invoked:
# Invokes the Num.Num => Num version
add(123, 456)
# Invokes the Num.Num.Num => Num version
add(123, 456, 789)
Overriding Overloaded Function
You can also override the overloaded function, the rule is the same as in overriding normal functions. Whenever there is an overloaded version of the function already been declared, to override it, you should add override
keyword before the def
keyword:
def greet(msg: Str): Str => msg
# Overloaded Version
def greet(prefix: Str, msg: Str): Str do
prefix.concat(", ").concat(msg)
end
# Override the overloaded version
override def greet(prefix: Str, msg: Str): Str do
prefix.concat("! ").concat(msg)
end
Last updated
Was this helpful?