Skip to content

Releases: orelang/ore

v0.5.0

Choose a tag to compare

@github-actions github-actions released this 20 Oct 18:47

Install

curl -fsSL https://raw.githubusercontent.com/orelang/ore/main/install.sh | sh

or brew install orelang/tap/ore; then ore update keeps it up to date.
Each archive carries its LLVM and lld.

For File
Linux x86-64 ore-v0.5.0-linux-amd64.tar.gz
Linux arm64 ore-v0.5.0-linux-arm64.tar.gz
macOS arm64 ore-v0.5.0-darwin-arm64.tar.gz
VS Code extension ore-vscode-v0.5.0.vsix
Zed extension ore-zed-v0.5.0.zip

The editor extensions run ore lsp, so ore must be on PATH. VS Code:
install "Ore" (orelang.ore) from the Marketplace or Open VSX, or
code --install-extension ore-vscode-v0.5.0.vsix. Zed: unzip
ore-zed-v0.5.0.zip and pick its directory in zed: install dev extension
(Zed builds it with Rust, which must be installed with rustup).

What is in 0.5.0

Dictionaries and Object, type predicates, generators and iterators, globalThis, URL, TextEncoder, structuredClone, as const, tuple forms, the this type, and class features.

  • Dictionaries: { [key: string]: V } and Record<string, V> are a type
    of their own, a hash table of string keys in insertion order used with
    the syntax of objects. Object literals create them (computed keys and
    spreads included); d.a and d[k] read an entry as V | null;
    d[k] = v, d[k] ??= v, delete d[k] and k in d work on them, as
    delete and in do on nothing else. console.log prints them as Node
    prints objects, console.table lists them, and JSON converts them to and
    from objects. Object.freeze makes one read-only, and writing it then
    panics with JavaScript's TypeError message. An index signature next to
    other members, or with keys other than strings, is still an error.
  • The namespace Object: keys, values, entries, hasOwn, assign,
    fromEntries, groupBy, freeze and isFrozen, on dictionaries, objects
    and class instances (whose keys are their fields).
  • p["x"] reads and assigns the member x of an object, an interface or a
    class instance, and p[k] with k: keyof P reads the field k names, of
    type P[K].
  • Type aliases inside functions and blocks, generic ones too, scoped to
    their block (they used to be ORE7016).
  • Indexed access and keyof on a union of object types, as in
    TypeScript: U["x"] is the union of the members' field types, and
    keyof U their common names, so Omit<U, "z"> gives one object type of
    the common fields but z (TypeScript's Omit is not distributive).
  • Type predicates, as in TypeScript: x is T and this is T narrow the
    argument or receiver of a call in conditions, filter with such a
    callback gives an array of T, and asserts x is T and asserts x
    narrow after the call. Unlike TypeScript, the body is checked: each
    result must be false or a check that narrows the parameter to T,
    and an assertion function must panic or exit where the assertion does
    not hold. x is T used to be a parse error.
  • Boolean literal types: true and false are types, and boolean is
    their union. A field of such a type discriminates a union of objects, as
    in the Result pattern { ok: true; value: T } | { ok: false; error: E }:
    if (r.ok), if (!r.ok), r.ok === false and switch (r.ok) narrow
    r. An object literal for such a union picks its member by its true
    or false constant, and a while loop without a break narrows by its
    condition after it: after while (!r.done) r = it.next(), r is done.
  • A class can implement an instance of a generic interface
    (implements It<int>).
  • Generators and the iteration protocol, as in TypeScript: generator
    functions, methods and function expressions (function*, *m(),
    *[Symbol.iterator]()) return a Generator<T, TReturn = void, TNext = null> with next(), next(value) and return(value); yield,
    yield value and yield* iterable (of a generator, its return value).
    A generator runs its body on a fiber of its own, the async functions'
    fibers. Symbol.iterator names methods as Symbol.dispose does, and the
    global Iterator, Iterable and IterableIterator interfaces and the
    IteratorResult type describe the protocol. for...of, spread,
    Array.from, new Map and new Set take any iterable; for...of
    calls return() when it leaves a loop early, which ends a generator's
    fiber. keys(), values() and entries() of arrays, maps and sets
    return lazy iterators, as in JavaScript, instead of arrays: code that
    indexed their result or read its length now spreads it,
    [...map.keys()], or passes it to Array.from. Async generators are
    not supported (ORE5013), and there is no
    throw() (Ore has no exceptions).
  • JSON.stringify(value, replacer, space) takes a replacer array, the
    keys of objects to keep, in its order, at every level (maps too), and a
    string space, its first 10 characters indenting each level; a number
    space is at most 10, as in JavaScript.
  • TextEncoder and TextDecoder (UTF-8: encode, encodeInto, decode
    with fatal and ignoreBOM) and atob and btoa (base64 of binary
    strings), global names as in JavaScript, with u8[] for Uint8Array.
  • A RegExpMatch is indexed, destructured and iterated as JavaScript's
    match arrays: m[1], const [, key, value] = s.match(re)!,
    for (const c of m), over its captures (string | null). Assigning to
    m[i] is an error (ORE3084).
  • globalThis: the global names as members of one value, as in
    JavaScript (globalThis.Math.max(1, 2), new globalThis.Date(0),
    globalThis.Promise<int> as a type), resolved at compile time. A
    module's own top-level declarations are not on it, as in ES modules;
    nothing can be added to it, and it is no value itself (const g = globalThis is an error, ORE3091).
  • Promise.withResolvers<T>(): { promise, resolve }, a pending promise
    and the function that resolves it (no reject: promises do not reject).
  • fs.appendFile(path, data), Node's appendFileSync: appends to a file,
    created if missing. process.platform ("darwin", "linux") and
    process.arch ("arm64", "x64"), Node's names for the target.
  • Breaking: task.sleep(ns) and task.after(ns, handler) count
    nanoseconds, as everything in time: task.sleep(10 * time.millisecond)
    (they counted milliseconds). The timers still wait whole milliseconds,
    rounding up.
  • structuredClone(value), JavaScript's deep copy, as a global function:
    numbers, strings, bigints, arrays, tuples, Maps, Sets, Dates,
    object types, classes with only fields and unions, keeping shared
    references and cycles, by code generated for each type. Types holding
    functions (ORE4090), classes with methods (ORE4091), interfaces,
    unknown and channels (ORE4092) are compile-time errors.
  • URL and URLSearchParams are global classes, JavaScript's, written in
    Ore (runtime/core/url.ore) after the WHATWG URL Standard's parser:
    special schemes with their default ports dropped and \ read as /,
    dot segments resolved, the percent-encode sets of each component, IPv4
    hosts in all their forms and IPv6 hosts compressed, file URLs with
    drive letters, opaque hosts and paths of other schemes, and relative
    references resolved against a base (new URL("../x", base)). Every
    property but origin and searchParams has its setter; searchParams
    is linked both ways to the query; URL.canParse and URL.parse;
    new URL panics with TypeError: Invalid URL where JavaScript throws.
    console.log and JSON.stringify write them as Node does. Domains
    outside ASCII are not converted to Punycode.
  • as const: literals keep their literal types, array literals are
    read-only tuples and object literals have read-only fields, so
    (typeof Dirs)[number] of const Dirs = ["n", "s"] as const is the
    union "n" | "s".
  • Interfaces and object types can declare fields with accessor
    signatures, get x(): T (read-only) and set x(value: T).
  • readonly T[] and ReadonlyArray<T> are enforced: the methods that
    change an array and index assignment are errors through them, and a
    read-only array does not convert to a mutable one. readonly [A, B] is a
    tuple of read-only elements. New utility types: InstanceType and
    ConstructorParameters of typeof C (a class's constructor type,
    new (params) => C), and NoInfer.
  • Tuple types take the other forms of TypeScript: named elements
    [x: f64, y: f64] (documentation only), optional elements [int, string?] of type T | null that literals can leave out, rest elements
    that spread tuple types [...A, ...B], and infer with rest elements in
    conditional types (T extends [infer H, ...infer R] ? ...). A rest
    element of array type in the type of a value is reported (ORE2072), as
    tuples have a fixed length.
  • The type this in the non-static members of a class: a method
    add(s: string): this called on a subclass returns the subclass, so
    fluent APIs keep it, and parameters and fields can be of the type this
    (equals(other: this): bool, next: this | null). A method returning
    this must return the receiver (ORE5061); this in a static member or
    outside a class is an error as in TypeScript (ORE5059), and in an
    interface not supported yet (ORE5060).
  • A template literal calls toString(): `${obj}` of a class or an
    interface with a toString(): string method gives what it returns, and
    of an error "Name: message", instead of reporting ORE3060.
  • Error is a class to extend, as in JavaScript: class NotFound extends Error calls super(message) and sets this.name; new Error(message, { cause }) keeps the cause; errors have name, message, cause and
    toString(), instanceof Error is true for the subclasses, and
    console.log prints Name: message. The type Error stays the
    interface that any class with a message implements.
  • Arrow functions in fi...
Read more

v0.4.8

Choose a tag to compare

@github-actions github-actions released this 20 Oct 18:17

Install

curl -fsSL https://raw.githubusercontent.com/orelang/ore/main/install.sh | sh

or brew install orelang/tap/ore; then ore update keeps it up to date.
Each archive carries its LLVM and lld.

For File
Linux x86-64 ore-v0.4.8-linux-amd64.tar.gz
Linux arm64 ore-v0.4.8-linux-arm64.tar.gz
macOS arm64 ore-v0.4.8-darwin-arm64.tar.gz
VS Code extension ore-vscode-v0.4.8.vsix
Zed extension ore-zed-v0.4.8.zip

The editor extensions run ore lsp, so ore must be on PATH. VS Code:
install "Ore" (orelang.ore) from the Marketplace or Open VSX, or
code --install-extension ore-vscode-v0.4.8.vsix. Zed: unzip
ore-zed-v0.4.8.zip and pick its directory in zed: install dev extension
(Zed builds it with Rust, which must be installed with rustup).

What is in 0.4.8

Unterminated strings are errors; a heap that does not fragment.

  • A string in quotes that a line break ends is an error, ORE1009
    ("Unterminated string literal."), as in JavaScript; it was read as if
    closed, and ore fmt printed code it could not read back. Found by
    tests/fuzz/syntax.sh.
  • The collector keeps free runs of pages in bins by size and merges a freed
    run with its free neighbours: a large heap no longer breaks into small
    runs that every new span searched under the heap lock (the test runner,
    building hundreds of programs at once, grew to 7 GB and stalled).

v0.4.7

Choose a tag to compare

@github-actions github-actions released this 20 Oct 17:53

Install

curl -fsSL https://raw.githubusercontent.com/orelang/ore/main/install.sh | sh

or brew install orelang/tap/ore; then ore update keeps it up to date.
Each archive carries its LLVM and lld.

For File
Linux x86-64 ore-v0.4.7-linux-amd64.tar.gz
Linux arm64 ore-v0.4.7-linux-arm64.tar.gz
macOS arm64 ore-v0.4.7-darwin-arm64.tar.gz
VS Code extension ore-vscode-v0.4.7.vsix
Zed extension ore-zed-v0.4.7.zip

The editor extensions run ore lsp, so ore must be on PATH. VS Code:
install "Ore" (orelang.ore) from the Marketplace or Open VSX, or
code --install-extension ore-vscode-v0.4.7.vsix. Zed: unzip
ore-zed-v0.4.7.zip and pick its directory in zed: install dev extension
(Zed builds it with Rust, which must be installed with rustup).

What is in 0.4.7

Regular expressions: one group name in different alternatives, quantified groups around lookarounds.

  • Regular expressions take one group name in different alternatives
    (ES2025, (?<y>\d{4})-\d\d|\d\d\/(?<y>\d{4})): the group that took part
    gives the name's value in groups, \k<name> and $<name>. A quantifier
    on a group around a lookaround ((?:(?<=a))*) is no longer rejected. Both
    found by tests/fuzz/regexp, which now matches tens of thousands of random
    patterns as Node does.
  • ORE_GCVERIFY=1 fills what a collection frees with garbage, so that a use
    of a freed object shows at once; ci/matrix.sh runs the suite's
    programs in release, on 16 threads, and under frequent and verified
    collections.

v0.4.6

Choose a tag to compare

@github-actions github-actions released this 17 Oct 03:13

Install

curl -fsSL https://raw.githubusercontent.com/orelang/ore/main/install.sh | sh

or brew install orelang/tap/ore; then ore update keeps it up to date.
Each archive carries its LLVM and lld.

For File
Linux x86-64 ore-v0.4.6-linux-amd64.tar.gz
Linux arm64 ore-v0.4.6-linux-arm64.tar.gz
macOS arm64 ore-v0.4.6-darwin-arm64.tar.gz
VS Code extension ore-vscode-v0.4.6.vsix
Zed extension ore-zed-v0.4.6.zip

The editor extensions run ore lsp, so ore must be on PATH. VS Code:
install "Ore" (orelang.ore) from the Marketplace or Open VSX, or
code --install-extension ore-vscode-v0.4.6.vsix. Zed: unzip
ore-zed-v0.4.6.zip and pick its directory in zed: install dev extension
(Zed builds it with Rust, which must be installed with rustup).

What is in 0.4.6

Objects show their fields in the order of their declaration; coverage of the suite.

  • Printing, console.table and JSON.stringify show an object type's
    fields in the order of its declaration, or of the literal that made the
    type first, as JavaScript shows properties in the order they were added;
    they were sorted by name. Found by running the suite's programs under
    Node (ci/node-diff.sh).
  • ORE_COVERAGE=1 builds programs that count the runs of every statement
    and write them at exit, a panic included, as lcov to
    $ORE_COVERAGE_DIR/ore-<pid>.lcov; ci/coverage.sh measures the
    coverage of the compiler and the runtime by the test suite.

v0.4.5

Choose a tag to compare

@github-actions github-actions released this 17 Oct 00:14

Install

curl -fsSL https://raw.githubusercontent.com/orelang/ore/main/install.sh | sh

or brew install orelang/tap/ore; then ore update keeps it up to date.
Each archive carries its LLVM and lld.

For File
Linux x86-64 ore-v0.4.5-linux-amd64.tar.gz
Linux arm64 ore-v0.4.5-linux-arm64.tar.gz
macOS arm64 ore-v0.4.5-darwin-arm64.tar.gz
VS Code extension ore-vscode-v0.4.5.vsix
Zed extension ore-zed-v0.4.5.zip

The editor extensions run ore lsp, so ore must be on PATH. VS Code:
install "Ore" (orelang.ore) from the Marketplace or Open VSX, or
code --install-extension ore-vscode-v0.4.5.vsix. Zed: unzip
ore-zed-v0.4.5.zip and pick its directory in zed: install dev extension
(Zed builds it with Rust, which must be installed with rustup).

What is in 0.4.5

Value classes: small immutable classes without allocation.

  • Small immutable classes are values when nothing can tell: a class with no
    base class or subclass and one to eight readonly fields of numbers,
    booleans or other such classes, whose instances the program never
    compares, prints, converts to an interface or unknown, or keeps in an
    array, a map, a set, a channel or a union, has its instances kept in
    registers and inside the objects that hold them instead of on the heap.
    bench/structs, which moves particles with an immutable Vec3, no
    longer allocates in its loop.

v0.4.4

Choose a tag to compare

@github-actions github-actions released this 16 Oct 23:36

Install

curl -fsSL https://raw.githubusercontent.com/orelang/ore/main/install.sh | sh

or brew install orelang/tap/ore; then ore update keeps it up to date.
Each archive carries its LLVM and lld.

For File
Linux x86-64 ore-v0.4.4-linux-amd64.tar.gz
Linux arm64 ore-v0.4.4-linux-arm64.tar.gz
macOS arm64 ore-v0.4.4-darwin-arm64.tar.gz
VS Code extension ore-vscode-v0.4.4.vsix
Zed extension ore-zed-v0.4.4.zip

The editor extensions run ore lsp, so ore must be on PATH. VS Code:
install "Ore" (orelang.ore) from the Marketplace or Open VSX, or
code --install-extension ore-vscode-v0.4.4.vsix. Zed: unzip
ore-zed-v0.4.4.zip and pick its directory in zed: install dev extension
(Zed builds it with Rust, which must be installed with rustup).

What is in 0.4.4

Tagged templates and String.raw.

  • Tagged templates: tag`a${x}b` calls the tag with a
    TemplateStringsArray (the cooked strings, null for an invalid escape,
    and their raw text) and the substitutions, checked as a call against
    the tag's parameters. Each site passes the same strings object every
    time. String.raw works as a tag and as a function of { raw } and
    strings.

v0.4.3

Choose a tag to compare

@github-actions github-actions released this 16 Oct 23:15

Install

curl -fsSL https://raw.githubusercontent.com/orelang/ore/main/install.sh | sh

or brew install orelang/tap/ore; then ore update keeps it up to date.
Each archive carries its LLVM and lld.

For File
Linux x86-64 ore-v0.4.3-linux-amd64.tar.gz
Linux arm64 ore-v0.4.3-linux-arm64.tar.gz
macOS arm64 ore-v0.4.3-darwin-arm64.tar.gz
VS Code extension ore-vscode-v0.4.3.vsix
Zed extension ore-zed-v0.4.3.zip

The editor extensions run ore lsp, so ore must be on PATH. VS Code:
install "Ore" (orelang.ore) from the Marketplace or Open VSX, or
code --install-extension ore-vscode-v0.4.3.vsix. Zed: unzip
ore-zed-v0.4.3.zip and pick its directory in zed: install dev extension
(Zed builds it with Rust, which must be installed with rustup).

What is in 0.4.3

Garbage collection pauses under 0.1 ms.

  • Garbage collection pauses are under 0.1 ms on a 16-thread machine (from
    0.35 + 0.43 ms to 0.065 + 0.01 ms median, worst 1.2 ms to 0.2 ms; Go's are
    0.14 + 0.05 ms): a worker idle in the scheduler waits parked, with its
    registers saved and its stack pointer recorded, so the collector counts it
    as stopped without a signal; stopped threads sleep on a futex (__ulock
    on macOS) until the world runs again; the collector's waits spin before
    they sleep; and the second pause finishes marking on one thread when
    little is left.

v0.4.2

Choose a tag to compare

@github-actions github-actions released this 16 Oct 22:54

Install

curl -fsSL https://raw.githubusercontent.com/orelang/ore/main/install.sh | sh

or brew install orelang/tap/ore; then ore update keeps it up to date.
Each archive carries its LLVM and lld.

For File
Linux x86-64 ore-v0.4.2-linux-amd64.tar.gz
Linux arm64 ore-v0.4.2-linux-arm64.tar.gz
macOS arm64 ore-v0.4.2-darwin-arm64.tar.gz
VS Code extension ore-vscode-v0.4.2.vsix
Zed extension ore-zed-v0.4.2.zip

The editor extensions run ore lsp, so ore must be on PATH. VS Code:
install "Ore" (orelang.ore) from the Marketplace or Open VSX, or
code --install-extension ore-vscode-v0.4.2.vsix. Zed: unzip
ore-zed-v0.4.2.zip and pick its directory in zed: install dev extension
(Zed builds it with Rust, which must be installed with rustup).

What is in 0.4.2

Faster string-keyed maps.

  • String-keyed maps are faster (bench/knucleotide about 1.9x, wordcount
    1.25x, map 1.25x, in CPU time on an M-series Mac). The index of a map
    keeps the high bits of each key's hash beside the entry, so probing
    compares keys only when those match; string keys and 8-byte keys
    (integers, objects by identity) are hashed and compared by the runtime
    itself, strings a word at a time instead of FNV-1a's byte at a time; and
    map.set(key, f(map.get(key))), where f only computes with locals and
    constants (counts.set(w, (counts.get(w) ?? 0) + 1)), hashes and looks
    up the key once. indexOf and split no longer call memcmp for a
    one-byte separator.

v0.4.1

Choose a tag to compare

@github-actions github-actions released this 16 Oct 22:26

Install

curl -fsSL https://raw.githubusercontent.com/orelang/ore/main/install.sh | sh

or brew install orelang/tap/ore; then ore update keeps it up to date.
Each archive carries its LLVM and lld.

For File
Linux x86-64 ore-v0.4.1-linux-amd64.tar.gz
Linux arm64 ore-v0.4.1-linux-arm64.tar.gz
macOS arm64 ore-v0.4.1-darwin-arm64.tar.gz
VS Code extension ore-vscode-v0.4.1.vsix
Zed extension ore-zed-v0.4.1.zip

The editor extensions run ore lsp, so ore must be on PATH. VS Code:
install "Ore" (orelang.ore) from the Marketplace or Open VSX, or
code --install-extension ore-vscode-v0.4.1.vsix. Zed: unzip
ore-zed-v0.4.1.zip and pick its directory in zed: install dev extension
(Zed builds it with Rust, which must be installed with rustup).

What is in 0.4.1

JavaScript's Date as a global class, and checker fixes.

  • Date is a global class, JavaScript's, written in Ore
    (runtime/core/date.ore): the constructors (new Date(), new Date(ms),
    new Date("2024-10-15T12:00Z"), new Date(2024, 9, 15, 12)), the
    statics Date.now(), Date.parse and Date.UTC, the getters and
    setters in local time and in UTC with fields out of range carrying over,
    toISOString, toJSON, toString, toDateString, toTimeString,
    toUTCString and toLocale*String (en-US, the only locale). Invalid
    dates have a NaN time value and toISOString panics with RangeError: Invalid time value. Local time comes from TZ or /etc/localtime,
    read from the TZif files of /usr/share/zoneinfo with their POSIX rules,
    and UTC without them. Date.parse reads the ECMAScript format and, as
    V8, what toString and toUTCString print and the common other forms.
    console.log prints a date as Node does, and JSON.stringify writes it,
    as its ISO string.
    Date.now() is still an int.
  • Generic classes can have static fields, class Box<T> { static count = 0 }:
    one for all instances, as in TypeScript, initialized where the class is
    declared, and read, assigned and updated from anywhere, its static and
    instance methods too. Their types cannot name the class's type
    parameters (ORE3082); ORE3079 is no longer reported.
  • The condition of a for narrows its update clause too, as in TypeScript,
    unless the body assigns the variable: for (let at = list; at !== null; at = at.next) no longer reports that at may be null.
  • typeof of a top-level const works in annotations: after the
    constant for any initializer (let x: typeof name with const name = "ore"), and before it, as in function signatures, when the initializer
    is made of literals, a template literal, new C(...) of a class that is
    not generic, or the name of another such constant.

v0.3.0

Choose a tag to compare

@github-actions github-actions released this 16 Oct 10:46

Install

curl -fsSL https://raw.githubusercontent.com/orelang/ore/main/install.sh | sh

or brew install orelang/tap/ore; then ore update keeps it up to date.
Each archive carries its LLVM and lld.

For File
Linux x86-64 ore-v0.3.0-linux-amd64.tar.gz
Linux arm64 ore-v0.3.0-linux-arm64.tar.gz
macOS arm64 ore-v0.3.0-darwin-arm64.tar.gz
VS Code extension ore-vscode-v0.3.0.vsix
Zed extension ore-zed-v0.3.0.zip

The editor extensions run ore lsp, so ore must be on PATH. VS Code:
install "Ore" (orelang.ore) from the Marketplace or Open VSX, or
code --install-extension ore-vscode-v0.3.0.vsix. Zed: unzip
ore-zed-v0.3.0.zip and pick its directory in zed: install dev extension
(Zed builds it with Rust, which must be installed with rustup).

What is in 0.3.0

Ore's own garbage collector, precise and concurrent; faster tasks, regular expressions and JSON; benchmarks against C, Go, Bun and Node.

  • Benchmarks in plain C next to Ore, Go, Bun and Node: bench/<name>/main.c
    for every benchmark, C17 and libc only (pthreads for channels and
    tasks, POSIX regex.h for regex), built by bench/run.sh with
    $CC -O2 -march=native. The script's markdown now starts with the date,
    the machine (CPU, cores and threads, memory, OS and kernel), the version
    of each toolchain and the timing method; -o path or RESULTS=path
    writes it to a file as well, and the columns are always ore, c, go, bun,
    node.
  • Each worker thread has its own run queue, as in Go: a lock-free ring that
    tasks it spawns or wakes go to, with a slot for the task the running one
    woke last (so two tasks that wake each other run in turn on one thread),
    stolen from by idle workers, half of it moved to the global queue when
    full; the global queue is looked at every 61 tasks. bench/channels runs
    about 1.5–2x faster on 10 threads; bench/tasks is unchanged.
  • Spawning tasks is about ten times faster (bench/tasks, 100000 tasks:
    1.1 s to 0.09 s on a 10-core Mac). A task gets its stack when it first
    runs, not when it is spawned, and gives it back when it ends to a cache
    of the worker and a shared one, so mapping and unmapping stacks is rare;
    the stacks are listed for the collector without its lock. A WaitGroup
    of "ore:sync" counts atomically and locks only when its count drops to
    zero. An idle worker is signalled only when there is one.
  • JSON.parse<T> reads the text straight into a T, with no tree of
    values in between: keys are compared in place with the field names and
    strings without escapes share the bytes of the text. Only when that
    fails is the text parsed into values, to report the same error as
    before. JSON.stringify writes integers into its buffer without a
    string for each. bench/json runs about 3x faster in a quarter of the
    memory.
  • The collector marks alongside the program: two short stops (scanning
    the roots, then finishing) instead of one for the whole collection, with
    a write barrier the compiler emits before stores of pointers into the
    heap. It scans objects precisely, by a pointer map of their type, and
    never scans arrays of numbers; it gives free pages back to the system;
    and its pace is set by ORE_GOGC and ORE_MEMLIMIT. ORE_GCSTW=1
    marks with the world stopped, as before.
  • Regular expressions are faster (bench/regex about 2.6 times): the
    search skips bytes no match can start with and, after a failed try, the
    rest of a leading loop's run; a greedy loop of one character runs as one
    instruction, and keeps no choices when giving characters back could not
    match; exec and test reuse the expression's matcher; a replacement's
    $ patterns are read once. indexOf compares only where the first byte
    is.
  • ore doc [file.ore | dirs...] prints the API of modules: their exported
    functions, classes with their public members, interfaces, type aliases
    and variables, with their signatures as the hover shows them and their
    JSDoc (@param, @returns, @example and other tags), after the //
    comment the module starts with. On a terminal it is a colored listing;
    --md makes Markdown (with -o dir, a file per module and an
    index.md), --json a JSON dump for tools.
  • ore:test grows toward bun:test: describe groups (their names prefix
    their tests', math > adds), the hooks beforeAll, afterAll,
    beforeEach and afterEach, skip, only and todo (Ore functions
    have no properties, so not test.skip), .not, and the matchers
    toEqual (deep), toBeNull, toBeTruthy, toBeFalsy, toContain,
    toHaveLength, toBeGreaterThan(OrEqual), toBeLessThan(OrEqual),
    toBeCloseTo, toMatch and toPanic (Ore's toThrow: the function
    runs in a task whose panic is caught). Failures show the matcher and the
    expected and received values, as a diff of lines when they take several.
    The tests of a file now run when its top-level code ends, so that only
    can apply; a test declared in another task still runs at once. ore test -t <pattern> runs only the tests whose full names match. The summary
    counts skipped and todo tests.
  • The type parameters of generic methods may have defaults
    (size<U = T>(): int), as those of functions do; ORE5019 is no longer
    reported. A generic method is checked only for the calls it has, so such
    a method of a generic class can use what only some of its instances have.
  • unknown as the type of values: any value converts to it, boxed with
    its type, and console.log prints it as that type. It can be compared
    with ===, tested for null and narrowed with typeof (to string,
    f64, bool or bigint) and instanceof (to a class), which unbox it;
    anything else is an error, Object is of type 'unknown'. (ORE3078).
  • Numeric literal types are types of values: const n: 1 | 2 = 1,
    function rotate(d: 0 | 90 | 180 | 270), type Dice = 1 | 2 | 3 | 4 | 5 | 6.
    Their values are numbers held as an f64; they widen to number, and
    arithmetic and comparisons see numbers. A constant fits when it equals a
    member (ORE2067); === and switch narrow them, and a switch with a
    case for each is exhaustive. ORE2066 now concerns only never inside
    tuples and object types.
  • Generic nested functions (function id<T>(x: T): T in a function body)
    and generic function literals of a const (const id = <T>(x: T): T => x): each list of type arguments makes an instance, a closure that
    captures the variables of the enclosing functions like other nested
    functions. They can only be called; used as a value without a call, such
    a function is an error (ORE6071), and one that calls itself needs a
    return type annotation (ORE6072).
  • Getters and setters, of classes and of object literals, implement
    interface fields: a getter a readonly field, a getter and a setter a
    writable one. Reads and writes through the interface (and through a union
    with interface members) call them. Fields of names that no accessor
    implements are read and written through interfaces as before; the others
    test the table entry first.
  • console.log colors follow Node's rules for the terminal too: with no
    TERM, or one Node does not know, a terminal shows no colors, unless
    COLORTERM, TERM_PROGRAM, tmux or a known CI service says it does.
  • The checker parses builtin.d.ore once per process instead of on every
    check, which the language server runs on every change.
  • The language server tries a GitHub repository whose download failed
    again a minute later, or at once when a document importing it is saved,
    instead of never in the session.
  • Math.min() and Math.max() with no arguments are Infinity and
    -Infinity, as in JavaScript (they were ORE4019), or the extreme of the
    integer type expected, as with only empty arrays spread in.
  • Regular expressions of the v flag take string disjunctions
    ([\q{abc|d}x]), longest strings first, in their set operations too; a
    negated class that may hold strings is an error. With u (or v) and
    i, \w, \W, \b and \B count ſ and the Kelvin sign as word
    characters, as in JavaScript.
  • Maps, sets and channels are scanned precisely by the collector: the
    compiler passes the pointer maps of their keys, values and entries, map
    entries and channel buffers are allocated with them (never scanned when
    they hold no pointers), and the arrays of keys() and values() carry
    the pointer map of their elements.