The standard library
You write array<string>, you append to it, you foreach over it. Those aren't compiler builtins. They're ordinary Echo, compiled with your program, written against the same language you are writing. You can turn the whole library off. There is no runtime hiding behind it.
array<string> $ships = ["Prometheus", "Daedalus"];
$ships[] = "Odyssey";
foreach ($ships as $name) {
echo $name;
}The array, the append, and the foreach are all library code.
Three tiers, and the spelling tells you which
Where a name lives is visible in how you write it. No lookup table.
Tier one is the language's own vocabulary. Root namespace, lowercase, spelled like a primitive:
array<int32> $chevrons = [1, 2, 3];
map<string, int32> $power = map<string, int32>();
string $gate = "Abydos";
range<int32> $seven = 0 .. 7;
assert($chevrons->count() == 3);array, fixed_array, map, ordered_map, string, slice, range, result, status, rc, type_id, erased, plus die, assert and dprint. You write these every day, so they cost you no namespace at all.
Tier two is still about the language, but you don't write it every line. A short namespace:
echo mem::size<int32>(); // 4
echo hash::of(42) == hash::of(42); // 1contract:: (interfaces only), mem::, str::, arr::, hash:: and crash::. Container plumbing, mostly. If you're writing a data structure you'll live here. Otherwise you'll visit for mem::size and leave.
Tier three is ordinary utility with nothing to do with the language. Fully qualified under std:
echo std::math::sqrt(9.0); // 3.000000
echo std::env::argc() > 0; // 1std::math::, std::env::, std::io::, std::thread:: and std::time::.
Nothing in the library is special-cased
The library types have no capabilities your own types cannot have. map<K, V> works with foreach because it declares contract::iterable<V>, exactly the way a type of yours would (Contracts is that whole story). range<T> is the clearest case, because 0 .. 7 looks like syntax and is not:
foreach (0 .. 3 as $i) {
echo $i; // 0, 1, 2
}.. is an infix operator declared in the standard library, returning a range<T> that is iterable. So it works anywhere iteration does, and you could have declared it yourself. See Operators.
A handful of library declarations do carry attributes you won't write yourself. That's how the compiler names a type like array<T> when you write $a = [1, 2] with no declared type. You never need to think about them to use the library. Attributes has them if you're curious.
What --no-stdlib takes away
Building without the library is legitimate, and the diagnostics tell you what is missing.
foreach has no protocol to resolve against:
$b = 1;
foreach ($b as $e) {
echo $e;
}
// error: 'foreach' needs the iteration protocol, and nothing in this program declares
// '#[core: iterator]'. it lives in the standard library, which this compilation left out.An untyped array literal has no type to take:
$a = [1, 2];
// error: an array literal with no declared type needs the core array type, and nothing in this
// program declares '#[core: array]'. it lives in the standard library, which this
// compilation left out - write the type, e.g. 'array<int32> $a = [...];'.And 0 .. 3 stops parsing entirely, because without the library the dots are not a symbol:
foreach (0 .. 3 as $j) {
}
// error: Unexpected token 'dot (.)' found. Expected 'as'What survives is everything the language itself gives you. Primitives, structs, methods, control flow, generics, for, closures:
struct Counter
{
int32 $value;
function bump(int32 $by) : int32
{
$this->value = $this->value + $by;
return $this->value;
}
}
$c = Counter(0);
echo $c->bump(2); // 2
echo $c->bump(5); // 7The whole surface
| Namespace | Holds | Page |
|---|---|---|
| root | array, map, ordered_map, string, slice, range, die, assert, dprint | Collections |
| root | result | Results |
| root | atomic<T> | Atomics |
contract:: | iterator, iterable, const_iterable, keyed, unwrappable, failable | Contracts |
mem:: | allocation, type queries, take / init, buffer<T>, mem::atomic:: | Memory |
hash:: | of and the composition primitives | Hashing |
str:: | str::from and the formatting surface, splitting and joining, case conversion, str::buf, the C string boundary | String functions |
arr:: | merge and room | Arrays |
crash:: | set_hook, take_hook, default_hook, info | Crash reports |
std::io:: | writing text out, streams | Input and Output |
std::io:: | std::io::file, open / create / readfile / writefile, foreach over lines | Files |
std::io:: | opendir, dir, dirent, mkdir, rmdir | Directories |
std::io:: | a buffered reader and writer | Readers and writers |
std::math:: | constants and the numeric functions | Math |
std::env:: | arguments, environment, directories, exit | Environment |
std::thread:: | spawn, handle, task<T>, mutex<T>, once | Threads |
std::time:: | duration, instant, timestamp, sleep | Time |