LEVIATHAN v962456e · 962456eee1

Declarations

Methods and functions

Declare callables with block or single-statement bodies, overloads, default parameters, named arguments and type parameters.

since 0.1.0-alpha.1linuxwindowswasm

Description

A function is a callable declared in a namespace or at the top level. A method is a callable declared inside a class or struct; it has a this reference to the object it is called on. The syntax is the same for both:

int f(int a, int b) { return a + b; }              // block body
int g(int a, int b) => a + b;                       // arrow body: => means return
void say(string s) console.writeln(s);              // any single statement is a body
void listen(int port = 80, string host = "localhost") { ... }   // default parameters
U remap<U>(U v) => v;                               // type parameters on the callable
string s = remap::<string>("value");                // explicit type arguments

A body is exactly one statement: a block { ... } is one statement that holds many, an arrow body => expr returns the expression, and any other single statement, such as a call, is allowed without braces. Overloads are selected by the types of the arguments, for methods and functions alike. Named arguments and default parameter values work the same way everywhere; see lang.argument-binding for the exact binding rules.

Bodies, overloads, defaults, named arguments and generics

int add(int a, int b) { return a + b; }
int mul(int a, int b) => a * b;
void say(string s) console.writeln(s);
U remap<U>(U v) => v;
string describe(int n) => "int " + n.toString();
string describe(string s) => "string " + s;
string describe(float f) => "float " + f.toString();
void listen(int port = 80, string host = "localhost") {
    console.writeln(host + ":" + port.toString());
}
class Counter {
    int n = 0;
    int bump() { n += 1; return n; }
    T first<T>(Array<T> xs) => xs.at(0);
}
console.writeln(add(2, 3));
console.writeln(mul(2, 3));
say("hi");
string s = remap::<string>("value");
console.writeln(s);
console.writeln(remap(5));
console.writeln(describe(1));
console.writeln(describe("a"));
console.writeln(describe(1.5));
listen();
listen(8080);
listen(host: "example.org");
listen(host: "h", port: 1);
Counter c = Counter();
c.bump();
console.writeln(c.bump());
console.writeln(c.first(["x", "y"]));
console.writeln(c.first::<int>([7, 8]));
5
6
hi
value
5
int 1
string a
float 1.500000
localhost:80
localhost:8080
example.org:80
h:1
2
x
7

Rules

  • A body is one statement. { ... } groups several statements into one; => expr is shorthand for { return expr; }; any other single statement is also a body.
  • A method has this; a function does not. Using this outside a class is a compile error.
  • A declaration with ; in place of a body has no implementation. In an interface this states a requirement that implementing classes must fulfil.
  • Overloads share a name and differ in their parameter types or count. The overload is chosen by the argument types (lang.argument-binding).
  • A callable may declare type parameters after its name: U remap<U>(U v). They are inferred from the arguments when possible.
  • An explicit type-argument list is written name::<T>(args) for a function and object.name::<T>(args) for a method. It is checked first and must supply every type parameter; named, default and injected arguments are then bound as for any other call.
  • A parameter may carry a default value (int port = 80); the default must be a compile-time constant that does not refer to another parameter or to this.
  • Arguments may be named (listen(host: "h")). Positional arguments come first.

Examples

Several statements in a body need braces; without them the following statement is not part of the body:

One statement per body

void g() console.writeln("a"); console.writeln("b");
g();
b
a

console.writeln("b") is a separate top-level statement here, so it runs first; g only prints a.

See also

  • Operator declarations — Define operators on a class or struct by declaring a member with a symbolic selector such as (+), (==) or ([]).
  • Argument binding — How a call's arguments are matched to parameters, filled by defaults or injection, and how overloads are ranked.
  • Constructors — Declare constructors with new, select among them by label and argument types, call base constructors, and construct classes that declare none.