FunctionalScriptCLIPRsReleasesPlaygroundGitHub ↗

root / changelog / 0.51.0

← Previous: 0.50.0 · Next: 0.52.0 →
  • BREAKING CHANGES: fsc: an import specifier starts with ./, ../ or / and is percent-decoded — spell a % in a file name %25. A bare specifier, a raw ?, # or \, and a file name holding : are refused. (#2111, #2112, #2122)
  • BREAKING CHANGES: fsc: a module loads through its real path, symlinks followed, and diagnostics name that absolute path, not the caller's spelling. A custom effect runner for compilation must implement resolveFileModule. (#2116, #2117)
  • BREAKING CHANGES: fjs compile takes exactly two arguments — one more is refused, unexpected argument, where it was ignored — and a source that is not UTF-8 (a module, a .json input, a JSON import) is refused, not UTF-8 text. (#2292)
  • BREAKING CHANGES: fsc: a module denotes its export object, { default: value }, in transpile results, linked EDAGs and a compiled .rs module, and an unresolved EDAG import is one too. JSON, DataJS and FunctionalScript outputs are unchanged. (#2129, #2131)
  • BREAKING CHANGES: edag: a function node is ['=>', length, frame, body], not ['=>', frame, body], and reads its arguments as ['arg', N] and ['rest']. Recompile source, or migrate a zero-arity graph by scope. (#2237)
  • BREAKING CHANGES: fsc/parser: in Node, => holds a ParameterList where it held a token, a block is ['block', statements] of ['const', …] entries and a last ['return', …], and operators add variants. (#2099, #2106, #2120, #2192, #2237)
  • BREAKING CHANGES: fsc/parser: Module.consts holds { declaration, exported } records and Module.exported may be null; Import has bindings, not name; exportStatement is a rule function; ParseContext.complete holds ModuleDenotations. (#2131, #2248)
  • BREAKING CHANGES: fsc/parser/grammar: the rules are re-cut around (, parameters and operators — func starts after its ( and is reached through paren, Func holds Parameters, and Value and Body carry paren and a Tail. (#2090, #2099, #2106, #2192)
  • BREAKING CHANGES: fsc/ast: AstArgs is renamed AstRest, AstImport requires name (null for an empty list), AstFunction carries its length, and AstConst gains operator, argument and frame nodes. (#2106, #2192, #2197, #2237, #2248)
  • BREAKING CHANGES: fjs compile … .rs: module() returns Result<Any<A>, Any<A>>, the Err a thrown value; a module holding a function takes A: IStaticFunction; the literal helpers come from nanvm_lib::vm::unstable. (#2150, #2158, #2171)
  • BREAKING CHANGES: edag/rust: expExpr and nodeExpr print a read as Any::dot(…).end(), a number as f64_any(bits), a function as an IStaticFunction closure and a call as Any::call, and a nullish read is not refused. (#2146, #2159, #2171, #2181, #2186)
  • BREAKING CHANGES: media/rust: stringLiteral and i64Literal return Result<string, unknown>, refusing a lone surrogate and a bigint outside i64; f64Literal is replaced by f64Bits, a number's bits as a u64 literal. (#2140, #2146)
  • BREAKING CHANGES: effects/node: NodeOp gains resolveFileModule, writeExclusive and rmdir, which a runner built on NodeOperationMap must add, and writeFromStream needs Rm to delete a file it failed to write. (#2115, #2117, #2226, #2315)
  • BREAKING CHANGES: effects/node: writeFile and writeBytes refuse a Vec that is not whole bytes with invalid buffer size, where the node runner padded the last byte and reported success; cas's write refuses such a chunk too. (#2280)
  • BREAKING CHANGES: effects/node/virtual: State's memoryNext and memoryValues fields are replaced by one memory: MemoryState field. (#2279)
  • BREAKING CHANGES: fjs mcp: cas_get's uri is the opaque cas:<hash>, not the blob's path on the server. A client that opened that path uses npx functionalscript cas get <hash> <path>. (#2311)
  • BREAKING CHANGES: media/html: htmlUtf8 takes the document's language first, htmlUtf8(lang)(...head)(...body), and writes it as <html lang>. (#2209)
  • BREAKING CHANGES: text: import CodePoint from text/code_point/types.ts — text/utf16/types.ts no longer exports it and text/utf8/types.ts no longer exports I32; ByteOrEof is gone, spell it U8 | null. (#2235)
  • BREAKING CHANGES: types: list's Entry<T> is renamed Indexed<T> and range_map's is renamed RangeEntry<T>; object's Entry<T> re-exports ordered_map's, unchanged in shape. (#2256)
  • BREAKING CHANGES: types/bit_vec: BitOrder has a required tryConcat, so code that builds or mocks a BitOrder must supply it; msb.tryConcat and lsb.tryConcat answer null past maxLength. (#2234)
  • BREAKING CHANGES: crypto/secp: Init's a is renamed c — c[0] the constant term, c[1] the linear coefficient; curve callers pass c: [c0, c1]. (#2223)
  • BREAKING CHANGES: rtti/common: undeclaredMembers(declared, value) takes a membership test (k: string) => boolean in place of a name list — build one with declaredTest(names), or pass noDeclared. (#2267)
  • BREAKING CHANGES: ebnf/lib/js: the token grammar's string branch is a variant, { double, single }, so a string node gains a level, ['string', ['double' | 'single', …]]. The js/tokenizer token stream is unchanged. (#2251)
  • BREAKING CHANGES: js/keywords: keywords is typed as a readonly array of the keyword union, not an as const tuple; its value and (typeof keywords)[number] are unchanged. (#2285)
  • BREAKING CHANGES: nanvm/rust: generate answers the [name, content] files of gen.corpus/, one per group, where it answered one file's text; directory is that directory, and path is gone. (#2304, #2318)
  • BREAKING CHANGES: media/datajs/vectors/matrix: the generated matrix is gen.matrix.md, and the module's path export names it — read the path from it. (#2304)
  • BREAKING CHANGES: website/page: page takes a Build, { commit, branch }, where it took a commit. (#2342)
  • BREAKING CHANGES: website/demo: the demo runtime sends a click only from a named <button> or <input type="button">, markup inside one included; a demo that listened for clicks on another element uses an input event or a button instead. (#2340)
  • BREAKING CHANGES: nanvm-lib: the VM computes on vm::Number, which holds one canonical NaN; Unpacked, Numeric and Primitive hold it and IVm requires From<Number> — x.to_any() on an f64 becomes Number::from(x).to_any(). (#2152, #2154)
  • BREAKING CHANGES: nanvm-lib: IVm::InternalFunction is bound by IFunction, not IContainer; FunctionHeader and Function::name are gone; ptr_eq moves to IComplex. A VM that constructs functions implements IStaticFunction. (#2164)
  • BREAKING CHANGES: nanvm-lib: Any::member_access(receiver, key) is removed; replace each call with Any::dot(receiver, key).end(). (#2181)
  • BREAKING CHANGES: nanvm-lib: Any::logical_and, logical_or, nullish_coalescing and conditional take each lazy operand as impl FnOnce() -> Result<Any<A>, Any<A>> instead of an Any<A>. (#2162)
  • BREAKING CHANGES: nanvm-lib: JsonError drops IntegerLikeObjectKey — Any::to_json writes an object with array-index keys in ECMAScript's order, integer keys first, where it refused it. (#2102)
  • BREAKING CHANGES: nanvm-harness: run(module) is run(module, export, action), reading or calling the named export, and answers a RunError; migrate run(m) to run(m, "default", Action::Read). Fixtures move under fixtures::. (#2158, #2291, #2308)
  • fsc: the language grows its operators — + - * / % **, === !== < <= > >=, & | ^ ~ << >> >>> and the lazy &&, ||, ?? and ?:, with JavaScript's precedence — and grouping, (x). (#2090, #2106, #2192)
  • fsc: a function takes (), fixed parameters and a rest parameter — a =>, (a, b, ...x) =>, at most 16 fixed — and its body may name an outer parameter, const or import, which it captures. (#2099, #2197, #2237, #2297)
  • fsc: named exports and imports — export const, import { a, b as c, default as d } — single-quoted strings, and method calls on the built-ins js/prototype's allowedCalls names. (#2131, #2183, #2248, #2251)
  • fjs compile … .rs compiles every operator, functions with their captures, calls, method calls and a read on any base, spells a control or bidirectional character \u{…}, and creates the output's directory. (#2096, #2138, #2159, #2162, #2171, #2181, #2186, #2197, #2308)
  • nanvm-lib: a compiled method call answers the built-in toString on every type, and an array's at, includes, indexOf, lastIndexOf, slice, concat, toReversed, with and toSpliced. (#2184, #2191, #2319, #2320)
  • nanvm-lib: Any::call; the chain entry points Any::dot, option_dot and option_call; vm::unstable's strict_eq and strict_ne; BigInt::div_mod; a public Object::own_property. (#2157, #2170, #2180, #2271, #2288)
  • nanvm: a corpus group can be a method call, { method, cases }, compared structurally; nanvm/methods generates the table of every type's prototype names that nanvm-lib asserts complete. (#2318)
  • types/function/length: new — callable builds a function of a given length from factories, lengths 0 through maxLength, 16. (#2237, #2294, #2297)
  • git/refstore/write: new — tryWrite writes a ref and tryDelete deletes one, under Git's own locks; git/ref gains tryPackedWithout. (#2115, #2315)
  • media/markdown: new — a parser for the changelog entry subset, its grammar in ebnf/lib/markdown. (#2166)
  • path/import: new — resolves and decodes an import specifier; text/percent decodes percent escapes. path exports isDriveLetter, isDriveRoot and isBareDrive. (#2111, #2117, #2229)
  • effects: finallyStep; effects/node gains writeExclusiveUtf8File and the port checks maxPort, isPort, badPortCode and badPortMessage; effects/memory exports its synchronous interpreter. (#2115, #2238, #2279, #2315)
  • types: result's okList, list's someBy and none, and bit_vec's bytesIn, byteLength, isWholeBytes, isWholeBytesIn, tailPaddedUintChunkList, u8ListMsb and u8ListToVecMsb. (#2227, #2231, #2236, #2242, #2253)
  • text: code_point's tryToSurrogatePair, tryFromSurrogatePair and restart, and ascii's lowerHexDigitValue, isCanonicalDigits and digitsValue. (#2252, #2259, #2275, #2278)
  • git: oid's isOidOf and refname's sameBytes and lockSuffix; git/store reads a drive-rooted alternates entry of 1:/… or :: as relative. (#2115, #2225, #2229, #2281)
  • ebnf: repeat, repeatFrom, times and option refuse bounds outside their domain when the rule is built, and set, range, literals and byte's ascii refuse a lone surrogate. ebnf/data exports the checks. (#2246, #2264, #2274)
  • effects/node/virtual: mkdir, rm, createExclusive and writeExclusive answer the error codes a host does, where mkdir replaced a file in its path or acted on the root. nodeProgramOptions is exported. (#2115, #2250, #2270, #2276, #2315)
  • rtti reads a dense tuple in linear time, crypto/sign hashes the message once per signature, and ebnf/ll1 computes follow sets without deep recursion. (#2254, #2257, #2267)
  • website: the release history; JSON, DataJS and EDAG demos, the last two drawn as graphs; a header on every page, naming a preview's build; and an "fjs" favicon, a page language, section headings, titles, a wider column and 24px tap targets. (#2101, #2110, #2126, #2127, #2147, #2167, #2204, #2205, #2208, #2209, #2210, #2211, #2212, #2324, #2332, #2339, #2340, #2341, #2342, #2344)
  • spec/README.md specifies every feature the compiler accepts and what each output writes. (#2292, #2307)
Support FunctionalScript: GitHub Sponsors ↗ · Open Collective ↗ · Patreon ↗