A throw Beside an Export Is Refused

Status: refused by design

throw 1; export default 2; is not FunctionalScript. A throw before or after a module's exports is valid JavaScript, and fjs compile refuses it by design: the demo below shows what it prints.

A module is a function (module structure), and a body ends in return or in throw, not in both. So a module's throw stands where its export default would, in place of it: after its imports and every const, and with nothing after it. JavaScript runs the statements in order, so throw 1; export default 2; fails at every load, and the export after it is one no importer can read.

The row mod.throw-position of refused constructs registers the refusal, and module structure gives its reason.

Examples

throw 1;
export default 2;

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: none, since importing it throws 1.

What to Write Instead

Keep one ending: the export, as alternative.f.js does, or the throw alone, for a module meant to fail.

export default 2;

It answers 2.

A Better Message

Today fjs compile prints unexpected token at the export. 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:1 - error: unexpected token
2 | export default 2;
  | ^

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

sample.mjs:2:1 - error: a module ends in `throw` or in its exports, not both
2 | export default 2;
  | ^^^^^^ JavaScript never reaches this export: the module throws first
  = help: keep one ending, the export or the `throw` alone:
          export default 2;
  = note: refused by design, see spec/modules/throw-position/README.md

JavaScript source, sample.mjs:

throw 1;
export default 2;

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

none: importing it throws 1

What to write instead

The FunctionalScript spelling, alternative.f.js:

/**
 * The FunctionalScript spelling of [`sample.mjs`](./sample.mjs): the module
 * keeps one of its two endings, here the export
 * ([`README.md`](./README.md)).
 *
 * @module
 */

export default 2;

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

export default 2;

What it answers, its default export:

2

Emergent Testing

Idle. Press Run to start the suite.

  • ./proof.f.mjs