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's intended interface.
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.