This is the specification of the language that the compiler accepts today. A FunctionalScript module is exactly a module that
fjs compile <input> <output>
compiles to a supported output. Source admission, program evaluation and output serialization are separate steps: the parser may accept a program whose evaluation fails, or whose result a particular output cannot represent.
Features the parser does not recognize yet — among them the remaining unary operator (+) and type annotations in comments — and the design documents for the VM, I/O, serialization, and the rest of the roadmap live in spec/todo/. Loose equality (== !=) is not waiting: it stays refused (operators).
The compiler accepts values (supported value types), the constants and imports that share them, property access, operators, the Number conversion, String conversion, template literals, and functions with their calls, and this document specifies all of them. The outputs differ in what they can write, so one module may compile to one output and be refused by another (output).
spec/datajs/ specifies DataJS, a much narrower interchange format this language contains: JSON with two extensions — values may be shared, so a document denotes a DAG rather than a tree, and the leaf set gains undefined, bigint, NaN and the infinities — and with a ; required after every statement, export default included (where a module here may omit one JavaScript inserts), no import, no comments, no identifier keys and no trailing commas. The language this document describes is wider, and holds functions besides. The compiler bridges the two: to a .data.js output, fjs compile evaluates the module and writes its default export through DataJS's own writer. Functions, calls and operators may compute that data; a function remaining in the selected result cannot be written as DataJS or JSON (output).
The specification is a tree of small pages, one per feature. Each page says what is accepted and what is refused and cites the ECMAScript section it narrows. Pages that have example programs show them with the compiler's real output; the others say under Examples that theirs are still to come (the plan).
- Principles: compatibility, purity, failure
- Lexical grammar: whitespace, comments, identifiers, string escapes
- Values: numbers, bigints, strings, template literals, arrays, objects
- Modules: exports, imports
- Bindings: constants, variables, destructuring
- Operators: grouping,
instanceof,in - Conversions:
Number,String - Property access: optional chaining, entries
- Functions: parameters, captures, calls, names and identity, outputs
- Control flow: guards, loops, switch
- Built-ins: member functions, static functions
- Undecided constructs: the valid JavaScript refused today while its decision is still owed
- Command line: checking, source text, file types, JSON input, output
- Roadmap
| Area | Supported today |
|---|---|
| Modules | Default, named and combined imports; JSON import attributes; local and exported const, local let and assignments; named and default exports; terminal throw |
| Literals | JSON values, undefined, NaN, infinities and arbitrary-width bigints; decimal, hexadecimal and binary integers; numeric separators; single- and double-quoted strings; untagged template literals |
| Containers | Dense arrays, object literals, shorthand members, constant and computed keys, trailing commas, array/call spread and object spread |
| Expressions | Grouping; arithmetic, strict comparison, bitwise and lazy operators; ?:, !, typeof, instanceof Array, Number(...) and String(...) |
| Properties | Own-property reads, numeric computed keys through Number(...), optional reads/calls and the enumerable entry helper |
| Functions | Arrow functions, 0–16 fixed parameters, optional rest, closures, self recursion, body constants, let variables and assignments, terminating if guards, while loops over one variable, the terminating switch, return, throw, ordinary and method calls |
| Built-ins | Pure array, string and numeric member functions, including callbacks and function text (member functions); Object.is, Object.entries, Object.fromEntries and the Number predicates isInteger, isSafeInteger, isNaN, isFinite (static functions) |
| Compiler | JSON/DataJS evaluation; FunctionalScript, EDAG and Rust graph output; import linking and the authored .f.js check |
The sections below give the restrictions and executor-specific limits for each feature. This overview records compiler support; optional chaining's required language-design approval record remains open. TypeScript-only syntax, mutation of a value's contents, loops beyond the one-variable while (loops), classes, numeric key literals and general forward references remain outside the implemented language.
Unimplemented language features and remaining design work — ECMAScript proposals and the like — are tracked in spec/todo/. The designs for I/O effects, the content-addressable VM, object identity, mutability and serialization are in spec/design/. Implemented behavior belongs in this document; a design record may remain open for approval, proofs or follow-up work after its syntax has landed.
For the implementation, see fjs/compiler/README.md, the compiler.