An Array Hole Is Refused

Status: refused by design

[1, , 2] is not FunctionalScript. [1, , 2] is valid JavaScript, and fjs compile refuses it by design: the demo below shows what it prints.

In JavaScript [1, , 2] has a hole: an index with no element, which is not the same as an element holding undefined, since 1 in [1, , 2] is false and forEach skips it. FunctionalScript arrays have no holes, so the empty slot is refused at its comma (array hole). The same comma in a pattern is an elision, and stays (destructuring).

The row lit.array-hole of refused constructs registers the refusal, and arrays gives its reason.

Examples

export default [1, , 2].length;

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: 3.

What to Write Instead

Write the element, undefined if that is what it holds, as alternative.f.js does:

export default [1, undefined, 2].length;

It answers 3. Every index holds an element, so nothing skips it.

A Better Message

Today fjs compile prints array hole 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:1:20 - error: array hole
1 | export default [1, , 2].length;
  |                    ^

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

sample.mjs:1:20 - error: an array hole is not FunctionalScript: every index holds an element
1 | export default [1, , 2].length;
  |                    ^ JavaScript leaves index `1` empty here
  = help: write the element, `undefined` if that is what it holds:
          export default [1, undefined, 2].length;
  = note: refused by design, see spec/values/arrays/holes/README.md

JavaScript source, sample.mjs:

export default [1, , 2].length;

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

3

What to write instead

The FunctionalScript spelling, alternative.f.js:

/**
 * The FunctionalScript spelling of [`sample.mjs`](./sample.mjs): the element the hole leaves out, written as `undefined`
 * ([`README.md`](./README.md)).
 *
 * @module
 */

export default [1, undefined, 2].length;

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

export default [1,undefined,2].length;

What it answers, its default export:

3

Emergent Testing

Idle. Press Run to start the suite.

  • ./proof.f.mjs