Type Annotations
Pyro supports optional type annotations for variable, function, and method declarations, e.g.
var foo: i64 = 123; var bar: f64 = 1.0; def is_long(text: str) -> bool { return text:byte_count() > 100; } def increment(value: i64, inc: i64 = 1) -> i64 { return value + inc; }
Pyro doesn't (currently) do anything with these type annotations, apart from verifying their syntax, but they're useful for documenting your code.
Future versions of Pyro may support optional type-checking or automatic documentation generation using type annotations.
Builtin Types
Annotations for builtin types are as follows:
-
any -
bool -
buf -
char -
class -
err -
f64 -
file -
func -
i64 -
instance -
iter -
iter[type] -
map -
map[key_type, value_type] -
method -
module -
null -
queue -
queue[type] -
set -
set[type] -
stack -
stack[type] -
str -
tup -
tup[type1, type2, ...] -
vec -
vec[type]
The annotations below describe interfaces rather than concrete types:
-
callable -
callable(type1, type2, ...) -> type -
iterable -
iterable[type] -
iterator -
iterator[type]
A callable value is callable;
an iterable value has an :$iter() method that returns an iterator;
an iterator value has a :$next() method that returns the next item from a sequence.
Type annotations beginning with a lowercase letter are reserved for language builtins.
Syntax
Specify a variable's type by following its name with a colon and a type declaration:
var name: type; var name: type = value;
The same syntax works for function and method parameters:
def func_name(arg1: type, arg2: type) { ... }
Functions and methods can declare their return type by following their parameter list with an arrow, ->, and a type declaration:
def func_name() -> type { ... }
Container types can optionally specify their content types in square brackets, e.g.
var foo: vec[str]; var bar: map[str, i64]; var baz: tup[i64, bool, str];
Where a type can be one of a discrete set of options, separate the options with a |, e.g.
var foo: i64|f64; var bar: map[str, i64|f64];
Type declarations can be nested as required, e.g.
var foo: vec[map[str, i64|f64]];
Nullable Types
You can indicate that a type is nullable — i.e. can be either the specified type or null — by appending a ? to the type name, e.g.
var foo: i64?; var bar: vec[str?]; var baz: map?[str, i64];
-
foois eithernullor ani64. -
baris avecwhose entries are eithernullorstr. -
bazis eithernullor amapwithstrkeys andi64values.
Callable Values
You can indicate that a value is callable — i.e. that the value is a function, method, class, or callable instance — using the callable type, e.g.
var foo: callable;
You can optionally specify the callable's return type, e.g.
var foo: callable -> bool;
You can optionally specify the callable's parameter types, e.g.
var foo: callable(); var bar: callable() -> bool; var baz: callable(i64, str); var bam: callable(i64, str) -> bool;
-
foois a callable that takes no parameters. -
baris a callable that takes no parameters and returns abool. -
bazis a callable that takesi64andstrparameters. -
bamis a callable that takesi64andstrparameters and returns abool.
The callable type is nullable, e.g.
var foo: callable?; var bar: callable?(i64) -> bool;
-
foois eithernullor a callable. -
baris eithernullor a callable that takes takes ani64parameter and returns abool.
Type Names
A type name should specify either one of the builtin types or a user-defined type, possibly imported from a module, e.g.
var foo: UserType;
Here, foo is an instance of the class UserType. Type names can include a module path, e.g.
var bar: mod1::mod2::UserType;
Here, bar is an instance of the class UserType defined in the module mod1::mod2.
Type Aliases
You can define an alias for a type using a typedef statement, e.g.
typedef Token tup[str, i64, bool]; def makes_token() -> Token { return $tup("FOO", 123, true); }
Variadic Functions
A type annotation in a variadic function specifies the type of the individual parameter values, e.g.
def add(*args: i64|f64) { return args:iter():sum(); } assert add(1, 2.0) == 3.0;
Here, add() is a function that takes a variable number of arguments; each argument can be an i64 or an f64.