Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Appendix C: Language Constructs

A construct uses function-like syntax, but the compiler applies its own rules. This table lists every construct.

ConstructResultMain rule
assert!($test)voidthrows when a bool test is false
assert!($test, $message)voidadds a string message
clone!($object, ...)objectclones an object and may replace fields
contains!($array, $value)boolchecks array values with strict equality
contains_key!($array, $key)boolchecks an array key or index
debug!(...)nullprints source sites and bounded value details
directory!()stringreturns the current source directory
discard!($value)voidmarks a discarded result as deliberate
drop!($local, ...)voidreleases locals that hold the last strong references
embed!('./file')stringembeds a file’s exact bytes while compiling
exit!()neverexits with status zero
exit!($status)neverexits with the low eight bits of an int
file!()stringreturns the current source file
length!($value)intcounts string bytes or array items
panic!('message')neverprints a trace and exits with status 255
remove!($array, $key)valueremoves and returns one entry
swap_remove!($vec, $index)valueremoves a vec item without keeping order
remove_first!($vec)valueremoves and returns the first item
remove_last!($vec)valueremoves and returns the last item
require!($path)nullloads and runs a source file
require_once!($path)nullloads a resolved path at most once
write!(...)voidwrites to standard output
write_line!(...)voidwrites to standard output, then ends the line
write_error!(...)voidwrites to standard error
write_error_line!(...)voidwrites to standard error, then ends the line

Mutable targets

The remove constructs require a writable array place, not an arbitrary expression. drop! accepts locals and makes them undefined.

$values = vec[10, 20, 30];
$removed = remove!($values, 1);

assert!($removed == 20);
assert!($values == vec[10, 30]);

remove! preserves order when its target is a vec, so removing a non-final item shifts each later item left. remove_first! does the same at index zero. Use either form when later indexes or iteration order must stay predictable. Removing near the front of a vec takes time in proportion to the items that follow it, so repeatedly draining a vec with remove_first! takes quadratic time. Use Whim\DataStructure\Deque for a FIFO queue.

swap_remove! does not shift. It moves the last item into the removed item’s index:

$values = vec[10, 20, 30, 40];
$removed = swap_remove!($values, 1);

assert!($removed == 20);
assert!($values == vec[10, 40, 30]);

Use it for an unordered vec when removal speed matters. Its removal step takes constant time. As with any vec mutation, changing a shared vec may first copy its storage. remove_last! also takes constant time and keeps the order of all remaining items.

remove! also accepts a dict. It removes the requested key without changing the other entries. swap_remove!, remove_first!, and remove_last! accept only vecs. A missing key, invalid index, or empty vec throws OutOfBoundsError.

Output arguments

Write constructs accept any number of string, int, or float expressions. They evaluate arguments from left to right. The line forms add the host line ending after the last argument.

write_line!('count: ', 3);

They reject bool, null, arrays, objects, and callables. Convert such values first.

Debug arguments

debug! accepts any number of values. It writes one source location and value view for each argument to standard error, then returns null.

$value = debug!(42);
assert!($value == null);

The view stops after 64 collection items and 32 nested levels.

Process exit

exit! stops the process. It does not throw. A catch cannot intercept it, and pending finally blocks do not run.

panic! has the same control flow. It takes one literal string, prints the message and current stack trace to standard error, and uses status 255. Trace boundaries and sensitive parameter markers apply. Both forms run shutdown destructors.

Source paths

file!() and directory!() take no arguments. Their values belong to the source file that contains the construct, not the process entry file.

embed! takes one literal relative path. It resolves from that same source directory and reads the file while compiling. It accepts any bytes and performs no file access when the program runs. It rejects absolute paths and source read from standard input.

See Language Constructs for examples and Resources and Cleanup for drop!.