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];
-
foo
is eithernull
or ani64
. -
bar
is avec
whose entries are eithernull
orstr
. -
baz
is eithernull
or amap
withstr
keys andi64
values.
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;
-
foo
is a callable that takes no parameters. -
bar
is a callable that takes no parameters and returns abool
. -
baz
is a callable that takesi64
andstr
parameters. -
bam
is a callable that takesi64
andstr
parameters and returns abool
.
The callable
type is nullable, e.g.
var foo: callable?; var bar: callable?(i64) -> bool;
-
foo
is eithernull
or a callable. -
bar
is eithernull
or a callable that takes takes ani64
parameter 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
.