Standard Library Naming Policy
Public API in the Zynx standard library should prefer short, concrete, action-oriented names.
Names should feel like small primitives: clear, direct, and mechanical. Prefer common English words with strong meaning over long abstract terms.
Standard Library Scope
The standard library should provide the essential, composable building blocks for common work, without trying to become the entire ecosystem.
Keep APIs that are:
- core runtime or language adapters
- primitive owned data types or borrowed views
- small cross-module capability interfaces
- thin wrappers over platform primitives where safety or ownership matters
Remove or avoid APIs that:
- mainly save a short user-written loop
- hide allocation behind a generic convenience
- duplicate another clear spelling
- imply codec, protocol, framework, or application policy
Prefer
- short verbs:
read,write,open,close,fetch,yield - concrete nouns:
file,path,clock,task,buffer,slice - small namespaces:
io,fs,os,net,mem,time,arith
Avoid
- enterprise-style verbs:
perform,executeOperation,utilize,processData - vague nouns:
manager,handler,processor,service,object - redundant prefixes:
file_open,memory_alloc,time_duration - long abstract names when a simple word exists
Examples
Prefer:
io.read(...)
io.write(...)
fs.open(...)
net.fetch(...)
async.sleep(try time.ms(10))
async.reschedule()
await fetch()
await with async.Scope.local() as tasks { ... }
clock.now()
math.sqrt(...)Exact Public Mutation Vocabulary
Public target APIs in std use one verb for each mutation shape:
| Verb | Exact public meaning |
|---|---|
push | Add one element at the sole obvious end of an ordered sequence or bounded output session. |
append | Concatenate a complete str or rune suffix to owning text. |
insert | Add one element at an explicit position in an ordered sequence. |
put | Create or update one key-to-value association. |
add | Add one non-positional member, such as a set representative or arena entry. |
pop | Total removal from the sole obvious sequence end, returning an optional element. |
remove | Remove the entity selected by an index, key, handle, or path. |
clear | Remove all logical content while retaining reusable storage or resources. |
merge | Transfer owners between collections of the same kind under their explicit conflict contract. |
Do not add parallel mutation aliases such as collection append/extend, delete, erase, take, remove_entry, map insert, set insert, put_all, or add_all. Bulk iterator ingestion remains an explicit loop whose put or add result is handled on every iteration. A future bulk sequence move needs its own ownership, overlap, and partial-progress contract rather than an extend convenience spelling.
The vocabulary classifies semantic operations; it does not create a common mutation interface or require equal receiver, error, or result types. It also does not reserve these ordinary words in user programs. Domain operations keep their own meanings: iter.take bounds a cursor, MaybeUninit.take extracts a proven initialized value, arith.*.add performs arithmetic, filesystem remove affects an external object, and stream write remains an I/O operation even when a concrete in-memory writer places bytes at its end.
When the mutable json.Value API is retained, object association uses put and array-tail insertion uses push. This naming classification alone does not ratify the DOM API's ownership, replacement, ordering, or failure semantics.
Conversion And View Names
Use constructors when an API creates a destination typed value from existing data or a handle:
let stream = try io.MemoryStream(bytes.Bytes("abc"));
let key = try cipher.Key(raw);
let addr = ipaddr.Ipv4Addr(127, 0, 0, 1);Use noun methods for semantic views or checked typed accessors:
let text = try value.string();
let child = try value.object("metadata");
let bytes = string.utf8();Reserve to_* for owned, copying, formatting, or transcoding output where the destination representation is the point of the operation, such as addr.to_string() or Unicode to_utf16le.
Clarity Over Brevity
Short names are preferred, but not at the cost of clarity.
If a term is not universally understood, it must be written in full.
Abbreviations are only allowed when they are widely understood and already act as common technical words. Examples: io, fs, os, and net.
Keep Primitives Composable
Modules should expose the smallest operation that composes naturally with the rest of std.
For byte streams, std.io keeps byte primitives:
reader.read(buffer)may return a short read and uses0for EOF.io.write(writer, data)writes a borrowedbytes.Bytesview completely or returns an error.io.read(reader, buffer)fills the whole buffer or returns an EOF error.- stream copying and read-to-end allocation are explicit user loops.
Avoid adding public helpers when the operation is only a small loop over existing primitives.
Protocol operations keep protocol semantics. A stream read may complete shortly and a datagram receive preserves exactly one datagram boundary. Public portable APIs expose nominal resources, never raw integer handles or generic descriptor adapters. Readiness remains private to each resource implementation; raw interop requires a separate target-specific owned/borrowed resource contract.
Semantic Modifiers Must Be Explicit
Operations that change semantics must use full, descriptive names. Plain arithmetic operators are checked and trap on overflow; helper modules that intentionally choose nullable, wrapping, saturating, or overflowing semantics must say so in their path.
Prefer:
arith.saturating.add
arith.wrapping.add
arith.checked.add
arith.overflowing.add
Avoid:
arith.sat.add
arith.wrap.add
arith.chk.add
Abbreviations are only allowed if they are universally understood.
Measurements And Visible Cost
Public measurement names have one meaning each:
lengthis an exact logical element, entry, or item count;sizeis an exact byte extent for text, C strings, files, and other byte-sized resources;byte_sizedisambiguates a byte extent inside compound metadata that also carries another coordinate;capacityis the logical bound of an owner or bounded session, in the same unit as that value'slengthorsize;countnames an action that traverses, validates, consumes, or otherwise performs work. It is never a property.
The abbreviation len is not a public Zynx API spelling. Generated raw foreign bindings may preserve a foreign name, and private implementation details may use their local representation vocabulary, but neither creates a public alias.
A direct readonly field is reserved for authoritative exact state that is stored or maintained with the value and is total, O(1), allocation-free, and effect-free. Reading such a field performs no host call, lock acquisition, or user-code invocation. Zynx has no computed-property or hidden-getter surface. Anything that must scan, validate, dispatch on a dynamic kind, or can fail remains an explicit function or method call:
let arguments = env.args().length;
let byte_extent = text.size;
let buffered = writer.buffered_length();
let members = try value.length();
let items = iter.count(<-cursor);Do not add compatibility synonyms such as len, .count, or both field and method spellings for the same measurement.