Note: This website is archived. For up-to-date information about D projects and development, please visit

Base Library

The base library is a set of functions dealing with some language aspects which aren't covered by the syntax of the language.

assert(condition [, message])

assert will test the given condition. If it is true, nothing happens. If it is false, an exception will be thrown. If there is an optional message string, it will be appended to the exception message if an exception is thrown.


getTraceback gets a string representing the call stack that was unwound during the last exception being thrown. You can use this to print out more meaningful errors if you catch an exception in your MiniD code, i.e.

	// ...
	writefln("caught exception: ", e);

If there is no traceback information available, this simply returns an empty string.


This will get the type of the passed-in value and return it as a string. Possible return values are "null", "bool", "int", "float", "char", "string", "table", "array", "function", "class", "instance", "namespace", and "thread".


This returns a string representation of the given value depending on its type, as follows:

  • null: the string "null".
  • bool: "true" or "false".
  • int: The decimal representation of the number.
  • float: The decimal representation of the number, to about 7 digits of precision.
  • char: A string with just one character, the character that was passed in.
  • string: The string itself.
  • table: A string in the format "table 0x00000000" where 0x00000000 is the address of the table.
  • array: A string in the format "array 0x00000000" where 0x00000000 is the address of the array.
  • function: If the function is native code, a string formatted as "native function <name>"; if script code, a string formatted as "script function <name>(<location>)".
  • class: A string formatted as "class <name>".
  • instance: A string formatted as "instance of class <classname>".
  • namespace: A string formatted as "namespace <names>", where <name> is the hierarchical name of the namespace.
  • thread: A string formatted as "thread 0x00000000", where 0x00000000 is the address of the thread.


This is like rawToString(), but it will call any toString metamethods defined for the value. Arrays have a toString metamethod defined for them if the array stdlib is loaded, and any toString methods defined in tables and instances will be used.


This will convert a value into an integer. Only the following types can be converted:

  • bool: Converts true to 1 and false to 0.
  • int: Just returns the value.
  • float: Truncates the fraction and returns the integer portion.
  • char: Returns the UTF-32 character code of the character.
  • string: Attempts to convert the string to an integer, and assumes it's in base 10. Throws an error if it fails.


This will convert a value into a float. Only the following types can be converted:

  • bool: Converts true to 1.0 and false to 0.0.
  • int: Returns the value cast to a float.
  • float: Just returns the value.
  • char: Returns a float holding the UTF-32 character code of the character.
  • string: Attempts to convert the string to a float. Throws an error if it fails.


This will convert an integer value to a single character. Only integer parameters are allowed.


Functions much like Tango's tango.text.convert.Layout class. The "{}" style format specifiers are used. It differs from Tango's formatting in a few key ways, though:

  • Tango requires the first parameter to formatting functions to be a format string, and the rest of the parameter list is inserted into the string using the format specifiers. MiniD is more like Phobos' formatting in that you can simply format anything, which will use the "{}" format specifier by default, and any string in the parameter list can be a format string. So you can write something like "format(5, " hi {} ", "bye", 4)" which will result in the string "5 hi bye 4".
  • Tango formatting allows you to specify the index of the parameter to format in a format specifier (like "{1}"). In MiniD, this is still allowed, using the following rules: formatting indices are relative to the position of the format string, so "{1}" will use the second item after the format string, regardless of where the format string is. Formatting an item causes it to be skipped over when format scans the rest of the parameters. So, something like "format(5, " hi {1} ", "two ", "bye", 7)" will format the 5, then it'll insert "bye" into the string, format "two ", skip "bye" because it was formatted, and format 7, resulting in "5 hi bye two 7". This "skipping" rule is a logical extension of when you use a non-indexed formatting specifier.
  • By default, when you format an item, it will call any toString metamethod defined for it. If you want to use the "raw" formatting for a parameter instead, write a lowercase 'r' immediately after the opening brace of a format specifier. So something like "format("{r}", [1, 2, 3])" will call rawToString on the array parameter, resulting in something like "array 0x00000000" instead of a string representation of the contents of the array.

Just about everything else works exactly as it does in Tango. You can use any field width and formatting characters that Tango allows.

MiniD's writef and writefln functions use the same internal formatting as this function, so any rules that apply here apply for those functions as well.


Formats the arguments into a string using the same formatting rules as format, then outputs the resulting string to the console. No newline is printed.


Just like writef, but prints a newline after the text has been output.


Prints out all its arguments to the console without any formatting (i.e. strings will not be searched for formatting specifiers). It would be the same as using "{}" for all arguments to writef.


Same as write, but prints a newline after the text has been output.


Note: This function is not available in the current release of MiniD.

Reads values from standard input using the given format string. Returns the read values (as many values as are specified in the format string). The '%r' specifier is also supported; it means the same thing as '%s'.

isNull(value), isBool(value), isInt(value), isFloat(value), isChar(value), isString(value)

isTable(value), isArray(value), isFunction(value), isClass(value), isInstance(value)

isNamespace(value), isThread(value)

These all return a boolean value. They return true if the passed-in value is of the given type, and false otherwise. You can use these to check parameter types, for function overloading, etc.

The advantage of using these functions over "typeof(value) == "type" is that they will be faster, as no string comparison has to be done. However using "value is null" is still the quickest way to determine if something is of the null type.


Returns a namespace that holds the fields of the given class or instance. Note that each instance has a unique namespace instance for its fields. You can then iterate over this namespace, since namespaces have an opApply defined for them.


Similar to fieldsOf(), returns the namespace that holds the methods of the given class or instance. All instances of a class and their owning class will have the same namespace instance for their methods.


This returns the thread object of the currently-executing thread, or null if the current thread is the main thread.

curry(func, param)

This function takes a function and a parameter, and returns a new function which takes one less parameter. The new function, when called, will call the old function with the given parameter as its first parameter, and will pass along any other parameters. Example:

function foo(x, y)
	writefln("foo: ", x, ", ", y);

foo(4, 5); // prints "foo: 4, 5"

local func = curry(foo, 8);
func(9); // prints "foo: 8, 9"

bindContext(func, context)

This is similar to curry(), but instead of returning a function which takes one less parameter, it returns a function which will always use the same context, regardless of how it's called. This allows you to create D-style "delegates", that is, a closure which has an associated object.

loadString(code [, name])

Compiles the given string containing MiniD source code into a function and returns that function. The code string is treated like the body of a function that takes variadic arguments, so the vararg expression is legal. You can optionally pass a name for the function. Because of the way MiniD is implemented, the dynamically-compiled function cannot access any locals or upvalues from the context in which it is loaded. Its environment is set to the same environment as the function which loaded it, so this means it can access globals of the module in which the loading function was defined.


Compiles and evaluates an expression, returning its result. Note that just like loadString, eval can only access globals that its calling function can access, and not locals or upvalues.


JSON is a standard for structured data interchange based on the JavaScript object notation. JSON is so similar to MiniD code that the compiler can parse it with very little modification. This function will take a string containing JSON formatted data, parse it directly into a value, and return the top-level table or array. This is a safe parser: it only accepts strictly conforming JSON data, so you don't have to worry about malicious code being embedded in the data being compiled or executed.

toJSON(value, bool pretty = false)

The opposite of loadJSON, this function will convert either a MiniD table or array into a JSON string which adheres to the specification. The value you pass must be either a table or array, and the only values they can contain are null, bool, int, float, char (these are converted into single-character strings in the output), string, table, and array. Any cycles in the data are detected and are an error. The return value is a string containing the formatted JSON data. If the pretty parameter is false (the default), the string will have as little whitespace as possible while still adhering to the spec; this makes the data slightly smaller for transmission. If pretty is true, it will insert line breaks and tabs as necessary to make it look a little more human-readable.

setModuleLoader(name, func)

Sets a custom loader function for the given module. This way, when the module is imported, if it hasn't already been loaded (which, chances are if you're using this function, it hasn't), it will call this function to load it instead of defaulting to other mechanisms. So, if you call "setModuleLoader("mod", someFunction)", whenever someone else imports "mod" for the first time, it will call that function to load it.

The loader function must take two parameters: the name of the module to load, and a namespace into which the symbols should be inserted. It is not required to return anything.

removeKey(container, key)

Removes the key-value pair with the key key from container. This works with tables and namespaces. You can also remove key-value pairs from tables by assigning a null value to the key-value pair, but this function is the only way to remove a key-value pair from a namespace.

namespace opApply

This is a hidden function that allows you to iterate over all the members of a namespace. You can use this to iterate over the members of a module, for example.

import blah;

foreach(k, v; blah)
	// k is the name, and v is the value.

thread metatable

The base library defines the metatable for thread objects. These functions are all accessed as methods of threads.

Returns a string representing the current state of the thread. Possible return values are "initial", "running", "waiting", "suspended", and "dead".
isInitial(), isRunning(), isWaiting(), isSuspended(), isDead()
These all return boolean values of whether the thread is in that state or not. These are a bit quicker and shorter to type than comparing the result of state() to a string literal.
Once a coroutine is in the 'dead' state, it's pretty much useless. However, you can use this method to reset a dead coroutine, placing it back in the 'initial' state so you can start it over again. Throws an error if the coroutine isn't in the 'dead' state.
This allows threads to be iterated over using a foreach loop. See Functions for info on that.

function metatable

The base library also defines the metatable for function objects. These are accessed as methods of functions.

If passed no parameters, returns the current environment (a namespace) of the function. If passed a namespace parameter, sets the namespace as the function's new environment and returns the function's old environment (the one that was just overwritten).

class StringBuffer

Since MiniD's strings are immutable, this class provides a mutable, resizable string object for building up strings piecewise, or just for having a modifiable string.

constructor([int or string])
There are three ways to construct a StringBuffer. One is to not pass any values to the constructor at all. This creates the string buffer with a small amount of empty space, but with a length of 0. The second way is to pass the constructor an int. This indicates how many characters of empty space to reserve, as a performance enhancement in case you know in advance about how many characters you'll need. The length is still set to 0. The last way is to pass a string, which will become the contents of the new string buffer.
This is the main way to add values to the end of the string buffer. Each value will have toString called on it if it's not a string already, and it will be appended to the end of the buffer. If a value is an instance of StringBuffer, its contents will be appended to the end of this buffer.
This is an overload of the append operator (~=) to allow the appending of items. This actually just calls the append function. So something like "sb ~= a ~ b ~ c" is exactly the same as "sb.append(a, b, c)".
insert(value, position)
This inserts the string representation of the value at the given position in the buffer. The position can be negative, which means an index from the end of the buffer.
remove(start [, end = start + 1])
This removes a sequence of characters from a StringBuffer. The start index is inclusive, the end index noninclusive. Either index can be negative, which means an index from the end of the buffer. The end index defaults to one after the start index, which means calling this function with just a start index will remove one character from the buffer.
Converts the contents of the string buffer to an immutable string value.
This sets the length of the buffer to the given length. If the new length is longer than the old length, the new slots are filled with the UTF-32 character U+00FFFF.
This is an overload of the length operator (#), so the length of the buffer can be retrieved.
An overload of the indexing operator, for getting a character in the buffer. It returns a character. Negative indices mean an index from the end of the buffer.
opIndexAssign(index, value)
An overload of the index-assign operator, for setting a character in the buffer. Negative indices mean an index from the end of the buffer.
opSlice(lo, hi)
An overload of the slicing operator, for retrieving a subset of the buffer. The low and high indices can be negative to indicate an index from the end of the array. This returns a string, not a string buffer.
opSliceAssign(lo, hi, string)
An overload of the slice-assign operator, for setting a subset of the buffer. The low and high indices can be negative to indicate an index from the end of the array. The source string must be the same length as the slice.
This allows you to iterate over a StringBuffer with a foreach loop. The optional reverse parameter will make the iteration go in reverse if you pass in the string value "reverse".
You can improve performance by requesting that the internal buffer be allocated to a certain size. This is similar to constructing a string buffer with an integral size. If the given size is less than or equal to the existing buffer, this function has no effect.