Functions are objects that contain program code (in the form of statements), and can be called (executed) from elsewhere in the program. Here's an example:
hello() { stdout.printf("Hello\n") }
To call this function from another function, the other function might use:
hello();
Functions may take arguments and return values. For example:
square(val: int): int { return val * val }
This function takes an integer and returns another integer (in this case, the square of the argument). One way to calculate the square of 5, then, is to do:
result ::= square(5)
This would assign the square of 5 to a new variable called result
.
If the function has no statements, the body may be omitted. This may be convenient when writing constructors (if the autogenerated code is all you need), and when writing abstract methods and interfaces (which cannot contain code).
nothing()
(This syntax is used outside functions, while the function call syntax earlier is used inside functions, so there's no conflict between them.)
The last statement in a function may omit the return
keyword. Thus, the square function can be written as:
square(val: int): int { val * val }
If a function is defined inside a class definition, it becomes a method. A method has access to other code and data encapsulated by the class.
If a method is declared static
, it becomes a class method, independent of class instances, but cannot directly access non-static members of the class. Otherwise, it becomes an instance method, which has full access to the class, but needs to be called through an instance.
For example:
class HelloClass { name: CString constructor(name: CString) static hello1() { stdout.printf("Hello World\n") } hello2() { stdout.printf("Hello %s\n", name) } }
Here, hello1
is a class method, and can be called without an instance:
HelloClass.hello1() // prints "Hello World"
However, hello2
is an instance method, and requires an instance. For example:
obj ::= HelloClass("Bob") obj.hello2() // prints "Hello Bob"
Class methods can be called through a class instance. However, only the class of the instance is used in such a call. The instance information will not be available to the class method.
obj.hello1() // still prints "Hello World"
In MORTAL, a delegate is a reference type which can refer to function/method objects, possibly along with other contextual data (including references to class instances). A call to a delegate resolves to a call to whatever function it currently refers to. This can be useful for callbacks, i.e., when one class is interacting with another class, and wants the second class to call some method in the first class when certain events occur.
A static delegate is a restricted type of delegate that does not include contextual data. This is similar to function pointers in C/C++, and can thus be used for compatibility with external APIs.
(NOT IMPLEMENTED YET)
The ->
operator can be used to create anonymous functions.
The main function is the function that is called by the system when your program starts. Its name must be main
, it must be public
, and it must return an integer.
The return value of main
is used as your program's exit code. The exit code is mainly useful if your program is called from a script or as part of a batch job. It should be 0 if your program succeeded in its task, or larger than 0 (typically 1) if there was an error.
public main(): int { stdout.printf("Hello World\n") return 0 }