A Body That Does Not Terminate Is Refused

Status: refused by design

{} is not FunctionalScript. () => {} is valid JavaScript, and fjs compile refuses it by design: the demo below shows what it prints.

A JavaScript function whose block can fall through its closing brace answers undefined, silently. FunctionalScript requires an explicit result or an end that cannot be reached by normal completion: return, throw, a terminating switch, or a terminal unconditional loop. What a function answers is still explicit (functions).

The row st.body-end of refused constructs registers the refusal, and functions gives its reason.

Examples

/** @type {() => undefined} */
const f = () => {};
export default f();

The demo on this page compiles sample.mjs, the module above, with this build's fjs compile, and shows the line it prints and the token it refuses. Below that it shows what JavaScript answers for the same module: undefined.

What to Write Instead

End the block with what the function answers, as alternative.f.js does:

/** @type {() => undefined} */
const f = () => {
    return undefined;
};
export default f();

It answers undefined. The answer is the same; now it is written.

A Better Message

Today fjs compile prints unexpected token at the refused token. The demo proposes what it should print instead: the reason at the same token, what JavaScript does there, and the allowed spelling, the line alternative.f.js writes, as help. The page compiles the alternative too, so the suggestion is one the compiler accepts.

Reference

Demo

Not allowed in FunctionalScript

This is valid JavaScript, and fjs compile refuses it, by design: it is not a FunctionalScript module.

What fjs compile sample.mjs output.js prints:

sample.mjs:2:18 - error: unexpected token
2 | const f = () => {};
  |                  ^

What it should print instead, pointing to what FunctionalScript allows (proposed):

sample.mjs:2:18 - error: this body does not end in `return` or `throw`: FunctionalScript writes what a function answers
2 | const f = () => {};
  |                  ^ JavaScript answers `undefined` when the block ends here
  = help: end the block with what the function answers:
              return undefined;
  = note: refused by design, see spec/functions/body-end/README.md

JavaScript source, sample.mjs:

/** @type {() => undefined} */
const f = () => {};
export default f();

What JavaScript answers for the same module, its default export:

undefined

What to write instead

The FunctionalScript spelling, alternative.f.js:

/**
 * The FunctionalScript spelling of [`sample.mjs`](./sample.mjs): the same function, its answer written
 * ([`README.md`](./README.md)).
 *
 * @module
 */

/** @type {() => undefined} */
const f = () => {
    return undefined;
};
export default f();

What fjs compile alternative.f.js output.js writes:

const $0=()=>undefined;export default $0();

What it answers, its default export:

undefined

Emergent Testing

Idle. Press Run to start the suite.

  • ./proof.f.mjs