The member functions an array answers, one file each, reached from array in ../lambda/method.rs. Each is ECMAScript 2025's algorithm on every input a module can build. Behaviour is pinned by the shared corpus in fjs/nanvm, which runs every case on a JavaScript engine and on this crate. The completeness table fjs/nanvm/methods generates, checked by completeness in method.rs, keeps this set equal to what the compiler admits.
The language decides which names exist, one by one, with a reason each (fjs/js/prototype/README.md). This crate answers exactly allowedCalls ∩ Array.prototype and grows no entry for anything else, so a name the compiler refuses cannot be reached another way:
| names | why |
|---|---|
copyWithin, fill, pop, push, reverse, shift, sort, splice, unshift | Mutate. The pure forms are toReversed, toSorted, toSpliced and with. |
entries, keys, values | Answer an iterator, a type the language lacks. |
forEach | Answers undefined; it exists only for side effects. |
toLocaleString | Reads the host locale. |
constructor | A data property, and it reaches Function. |
Several branches of the ECMAScript algorithms have no input here, and the code does not model them:
- Holes. No expression builds a sparse array, and
Array<A>is dense, so every "skip a hole" branch collapses. - Mutation during iteration. Nothing mutates, so the elements a callback sees are the ones the call started with, and iterating
Array<A>directly is the specified behaviour. - Species and
Symbol.isConcatSpreadable. There are no classes or symbols: every result is a plain array, andconcatspreads exactly the arrays. thisArg. Every function is an arrow that never readsthis, so the argumentmap,filterand the other iterations take is accepted and has no effect, as it has none on a JavaScript arrow. Refusing it would reject a harmless convention for nothing (DESIGN.md §12).- Cycles. An immutable value cannot contain itself, so
joinandflatneed no cycle detection.
Array.from, Array.of and Array.isArray are namespace functions, not member functions.
The EDAG keeps a call's argument count, so f(x) and f(x, undefined) are two calls, and three built-ins answer them differently, as JavaScript does. They read the argument through present in method.rs rather than argument:
lastIndexOf(x)searches from the end;lastIndexOf(x, undefined)from0.reduce(f)andreduceRight(f)throw on an empty array;reduce(f, undefined)answersundefined.toSpliced(s)removes to the end;toSpliced(s, undefined)removes nothing.
ECMAScript leaves the order of toSorted with an inconsistent comparator (() => 1) to the engine, and with it which of two elements a comparator is handed first. That is observable here only through a throw. This crate answers what its stable merge sort answers, deterministic on this VM as V8's answer is on V8, and the corpus pins only comparators whose answer does not depend on the order. Whether the language should do more is fjs/js/prototype/todo/to-sorted-inconsistent-comparator.md.
../position.rs: a position argument, shared with strings —ToIntegerOrInfinitycounted from the end, its clamp into the array, its range check, and the rangeslicereads.callback.rs: the callback checked before any element is visited,visitwith the element, index and array,positionfor the searches,foldfor the reductions.create.rs: a result past2³² − 1elements is theRangeErrorJavaScript throws, never wrapped.
flat and join recurse once per nesting level: array-deep-nesting.