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];
-
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
.