Reflect

Meta Programming

Together with support for first-class type values, and the ability to execute almost any code at compile time, the language facilities described in the following sections enable powerful meta programming schemes, including simple generics, code generation, defining custom checked annotations, and implementing domain specific languages.

Meta Parameters

⚠️ TODO

Generic Aggregate Types

Any of the aggregate types can have an optional list of parameters. These parameters are constant and compile-time and can be used to customize the definitions inside of the aggregate type. Furthermore, the parameters are accessible as properties of the type from the outside.

Generic types are not proper types. In order to use them as an actual type, the type name must be followed by a matching list of arguments to turn them into a concrete type definition.

Example

struct Vector(Scalar: type, dim: size_t) {
	var elements : Scalar[dim];

	meta if (dim >= 1) var x { get => elements[0]; }
	meta if (dim >= 2) var y { get => elements[1]; }
	meta if (dim >= 3) var z { get => elements[2]; }
}

alias Vec3f = Vector(float, 3);

metaAssert (Vec3f.Scalar = float && Vec3f.dim == 3);

Introspection

❌ Not Implemented

Meta Control Flow

⚠️ TODO

Mixins

Mixins are a means to insert declarations or statements directly within an existing scope. The content of the mixin is copied into the place of the instantiation, as if the statements were written there directly, with the exception that block level attributes (e.g. private:) will not be inherited.

Example

void registerFunctionCallTime(func: string, dur: Duration);

mixin benchmark {
	let _benchmark_startTime = MonoTime.currTime;
	scope (exit) {
		let dur = MonoTime.currTime - _benchmark_StartTime;
		registerFunctionCallTime(meta(function).name, dur);
	}
}

function updateGraph()
{
	// insert the benchmark code here
	mixin! benchmark;

	// perform some computations here...
}

Parameters

A mixin has an optional list of compiletime parameters that can be used to customize the generated code:

mixin generateFactoryFunction(S: type) {
	function #("create" ~ meta(S).name)()
	{
		S ret;
		// ...
		return ret;
	}
}

struct Button { /*...*/ }

mixin! generateFactoryFunction(Button);

var btn = createButton();