An Import After an Export Is Refused

Status: refused by design

export const a = 1; import b from is not FunctionalScript. An import after an export is valid JavaScript, and fjs compile refuses it by design: the demo below shows what it prints.

A module reads in one order: imports first, then constants, then export default, last. JavaScript hoists every import above the module's other statements, so where an import is written says nothing about when it is read; FunctionalScript keeps the one order, so a module's imports, its parameters (a module is a function), are where a reader looks for them, at its top.

The row mod.import-after-export of refused constructs registers the refusal, and module structure gives its reason.

Examples

export const a = 1;
import b from "./a.f.js";
export default [a, b];

The demo on this page compiles sample.mjs, the module above, with a.f.js beside it, using 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: 1,1, the import read before the export it follows.

What to Write Instead

Move the import to the top of the module, as alternative.f.js does:

import b from "./a.f.js";
export const a = 1;
export default [a, b];

It answers [1, 1].

A Better Message

Today fjs compile prints unexpected token at the import. 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 | import b from "./a.f.js";
  | ^

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

sample.mjs:2:1 - error: imports come first in a FunctionalScript module
2 | import b from "./a.f.js";
  | ^^^^^^ JavaScript hoists this import above the export
  = help: move the import to the top of the module:
          import b from "./a.f.js";
  = note: refused by design, see spec/modules/import-after-export/README.md

JavaScript source, sample.mjs:

export const a = 1;
import b from "./a.f.js";
export default [a, b];

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

1,1

What to write instead

The FunctionalScript spelling, alternative.f.js:

/**
 * The FunctionalScript spelling of [`sample.mjs`](./sample.mjs): the same
 * import and exports, the import first ([`README.md`](./README.md)).
 *
 * @module
 */

import b from "./a.f.js";
export const a = 1;
export default [a, b];

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

export const a=1;export default [1,{"default":1,"x":1}.default];

What it answers, its default export:

1,1

Emergent Testing

Idle. Press Run to start the suite.

  • ./proof.f.mjs