Reflect

Module reflect

import reflect

What a program can learn about itself while running.

reflect reads the structure a program declared: the members of a module, the fields of a data type, the members of a union, and the type of a value.

It is what makes attribute-driven libraries possible. coding decides how to encode a type by walking its Field values and reading the attributes written on each one — and attributes are read off a Field exactly as off any other value, so coding.Name(field).text and field is @coding.Ignore both work.

TypeRef describes a type hint as it was written, which is not the same as what a value turns out to be. Hints are not enforced at runtime, so a TypeRef tells you what a declaration promises.

Contents


Unions

DeclarationKind

`reflect/types.zirr:42`
union DeclarationKind {
	DataDecl
	UnionDecl
	AttrDecl
	TypeDecl
	FuncDecl
	ConstDecl
	VarDecl
	UnknownDecl
}

The form a declaration was written in, which is the keyword that introduced it.

Cases

Case Interpretation
DataDecl A data declaration.
UnionDecl A union declaration.
AttrDecl An attribute declaration.
TypeDecl An extern type declaration.
FuncDecl A function, declared with fn or extern fn.
ConstDecl A constant, declared with const or extern const.
VarDecl A variable, declared with var.
UnknownDecl A declaration in a form reflection does not describe.

TypeRef

`reflect/types.zirr:81`
union TypeRef {
	NamedType
	ArrayType
	OptionType
	ResultType
	DictType
	FuncType
	AttrsType
	UnknownType
}

A type hint as it was written.
Hints are not enforced at runtime, so a TypeRef describes what a declaration promises rather than what a value turns out to be.

Cases

Case Interpretation
NamedType A type referred to by name, e.g. String or Person.
ArrayType An array type, e.g. [String].
OptionType An optional type, e.g. String?.
ResultType A result type, e.g. String!.
DictType A dict type, e.g. [String: Int].
FuncType A function type, e.g. fn(String) -> Int.
AttrsType An attribute constraint, e.g. @Iterable @Countable.
UnknownType No type hint was written.

Data

ArrayType

`reflect/types.zirr:91`
data ArrayType {
	element: TypeRef
}

An array type, e.g. [String].

Fields

Field Description
element

AttrDecl

`reflect/types.zirr:50`
data AttrDecl

An attribute declaration.


AttrsType

`reflect/types.zirr:122`
data AttrsType {
	attributes: [TypeRef]
}

An attribute constraint, e.g. @Iterable @Countable.

Fields

Field Description
attributes One NamedType per required attribute.

ConstDecl

`reflect/types.zirr:59`
data ConstDecl

A constant, declared with const or extern const.


DataDecl

`reflect/types.zirr:44`
data DataDecl

A data declaration.


Declaration

`reflect/types.zirr:28`
data Declaration {
	name: String
	docs: String
	kind: DeclarationKind
	signature: String
	source: Source
}

A public declaration of a module, carrying the attributes written on it.
Attributes are read off a Declaration exactly as off any other value, so tests.Comment(declaration).text and declaration is @Deprecated both work, even for a declaration whose value can carry none, such as a const holding an Int.

Fields

Field Description
name The name it was declared under, which is the name member takes.
docs The comment written above it, or the empty String when none was.
kind The form it was written in.
signature The declaration as it was written, without its body, e.g. “extern fn typeName(t: Any) -> String”.
source Where it was written.

DictType

`reflect/types.zirr:108`
data DictType {
	key: TypeRef
	value: TypeRef
}

A dict type, e.g. [String: Int].

Fields

Field Description
key
value

Field

`reflect/types.zirr:70`
data Field {
	name: String
	docs: String
	declaredType: TypeRef
}

A field of a data type, carrying the attributes written on it.
Attributes are read off a Field exactly as off any other value, so coding.Name(field).text and field is @coding.Ignore both work.

Fields

Field Description
name The name the field was declared under.
docs The comment written above the field, or the empty String when none was.
declaredType The type hint written on the field, which is an UnknownType when none was.

FuncDecl

`reflect/types.zirr:56`
data FuncDecl

A function, declared with fn or extern fn.


FuncType

`reflect/types.zirr:114`
data FuncType {
	parameters: [TypeRef]
	returns: TypeRef
}

A function type, e.g. fn(String) -> Int.

Fields

Field Description
parameters One TypeRef per parameter, UnknownType where a parameter had no hint.
returns The declared result, which is an UnknownType when the function declares none.

Module

`reflect/types.zirr:5`
data Module {
	name: String
	docs: String
	imports: [String]
	sources: [String]
	declarations: [Declaration]
}

What a module is, as metadata: everything reflection can say about it without reaching into the values it exports.
AnyModule is the module itself, which members are looked up on; this is what it declared.

Fields

Field Description
name The canonical name, e.g. “reflect.packages”.
docs The comment written above each of its mod declarations, joined in file name order.
imports The name of every module it imports, ordered by name.
sources The path of every file it was read from, ordered by name.
declarations Every public declaration, ordered by name and so aligned with members and memberNames.

NamedType

`reflect/types.zirr:83`
data NamedType {
	name: String
	resolved: Option
}

A type referred to by name, e.g. String or Person.

Fields

Field Description
name The name as written, which is qualified when the declaration qualified it, e.g. “String” or “prelude.Option”.
resolved The type the name refers to, or None when it refers to nothing that exists as a value at runtime.

OptionType

`reflect/types.zirr:96`
data OptionType {
	element: TypeRef
}

An optional type, e.g. String?.

Fields

Field Description
element What a present value holds, as written. Zirric has no generic types, so a value only has to be an Option at runtime; the element is what two written hints are told apart by.

ResultType

`reflect/types.zirr:102`
data ResultType {
	element: TypeRef
}

A result type, e.g. String!.

Fields

Field Description
element What a successful value holds, as written, on the same terms as OptionType’s element.

Source

`reflect/types.zirr:19`
data Source {
	path: String
	line: Int
}

Where a declaration was written.

Fields

Field Description
path The file it was read from, named as the module reached it, e.g. “reflect/types.zirr”.
line The line the declaration starts on, counted from 1, or 0 when it was not read from a file at all.

TypeDecl

`reflect/types.zirr:53`
data TypeDecl

An extern type declaration.


UnionDecl

`reflect/types.zirr:47`
data UnionDecl

A union declaration.


UnknownDecl

`reflect/types.zirr:65`
data UnknownDecl

A declaration in a form reflection does not describe.


UnknownType

`reflect/types.zirr:128`
data UnknownType

No type hint was written.


VarDecl

`reflect/types.zirr:62`
data VarDecl

A variable, declared with var.


Functions

construct

`reflect/reflect.zirr:79`
extern fn construct(t: Any, values: [Any]) -> Result

Builds a value of a data type from its fields, in declaration order, or Err if the count does not match.


declaration

`reflect/reflect.zirr:18`
fn declaration(m: Module, name: String) -> Option

The declaration of m called name, or None if m has no public member of that name.
m is the metadata rather than the module itself, so that looking several up costs one pass over the declarations.


docs

`reflect/reflect.zirr:49`
fn docs(value: Any) -> String

The comment written above the declaration a value came from, or the empty String when none was written.
A module, a type, an attribute and a function each answer for their own declaration; a Module, a Declaration or a Field answers for the declaration it describes, which is the only way to reach the documentation of a const, whose value is an ordinary value with no declaration behind it.


fieldValues

`reflect/reflect.zirr:82`
extern fn fieldValues(value: Any) -> [Any]

The field values of a data value, in declaration order and so aligned with fieldsOf, or an empty array for anything else.


fieldsOf

`reflect/reflect.zirr:85`
extern fn fieldsOf(t: Any) -> [Field]

The fields of a data or attribute type, in declaration order, or an empty array for anything else.


hasMember

`reflect/reflect.zirr:41`
fn hasMember(m: AnyModule, name: String) -> Bool

Whether m has a public member called name.


isAttributeType

`reflect/reflect.zirr:72`
extern fn isAttributeType(t: Any) -> Bool

Whether t is an attribute type, and so can be called on a value to read that attribute, as well as having fields to enumerate.


isDataType

`reflect/reflect.zirr:66`
extern fn isDataType(t: Any) -> Bool

Whether t is a data type, and so has fields to enumerate.


isInstance

`reflect/reflect.zirr:76`
extern fn isInstance(value: Any, t: Any) -> Bool

Whether a value is of a type, decided exactly as the is operator decides it.
Unlike is, the type is a value here, so it can come from reflection rather than from source.


isUnionType

`reflect/reflect.zirr:69`
extern fn isUnionType(t: Any) -> Bool

Whether t is a union type, and so has members to enumerate.


member

`reflect/reflect.zirr:30`
fn member(m: AnyModule, name: String) -> Option

The public member of m called name, or None if it has none.


memberNames

`reflect/reflect.zirr:10`
extern fn memberNames(m: AnyModule) -> [String]

The name of every public member of m, in the same order as members.


members

`reflect/reflect.zirr:7`
extern fn members(m: AnyModule) -> [Any]

Every public member of m, ordered by name.


moduleName

`reflect/reflect.zirr:4`
extern fn moduleName(m: AnyModule) -> String

The canonical name of a module, e.g. “code.knabel.dev.zirric_lang.zirric.arrays”.


moduleOf

`reflect/reflect.zirr:14`
extern fn moduleOf(m: AnyModule) -> Module

What m declared, gathered in one value: its name, its documentation, what it imports, the files it was read from, and every public declaration.
A Declaration answers what an exported value cannot: which keyword declared it, where it was written, and the attributes written on it even where the value itself can carry none.


typeName

`reflect/reflect.zirr:63`
extern fn typeName(t: Any) -> String

The declared name of a type, or the empty String for anything that is not a type.


typeOf

`reflect/reflect.zirr:93`
fn typeOf(value: Any) -> Option

The type of a value, or None for a value whose type has no runtime representation.


unionMembers

`reflect/reflect.zirr:88`
extern fn unionMembers(t: Any) -> [Any]

The member types of a union type, in declaration order, or an empty array for anything else.