Binding a Built-in's Name Is Refused

Status: refused by design

const String is not FunctionalScript. const String = 1 is valid JavaScript, and fjs compile refuses it by design: the demo below shows what it prints.

Array, Number, Object and String name built-ins the language recognizes: Number(x) is a conversion and Object.is a static function. A module that binds one of these names would make the same text mean something else, so the names are reserved: binding one, or reading one as a value (export default String), is refused.

The row name.intrinsic of refused constructs registers the refusal, and built-ins gives its reason.

Examples

/** @type {(x: number) => string} */
const String = x => "s" + x;
export default String(1);

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

What to Write Instead

Give the function a name of its own, as alternative.f.js does:

/** @type {(x: number) => string} */
const s = x => "s" + x;
export default s(1);

It answers s1.

A Better Message

Today fjs compile prints reserved word 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:7 - error: reserved word
2 | const String = x => "s" + x;
  |       ^

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

sample.mjs:2:7 - error: `String` names a built-in: FunctionalScript does not let a module rebind it
2 | const String = x => "s" + x;
  |       ^^^^^^ JavaScript shadows the global `String` here
  = help: give the function a name of its own:
          const s = x => "s" + x;
  = note: refused by design, see spec/bindings/intrinsic-names/README.md

JavaScript source, sample.mjs:

/** @type {(x: number) => string} */
const String = x => "s" + x;
export default String(1);

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

s1

What to write instead

The FunctionalScript spelling, alternative.f.js:

/**
 * The FunctionalScript spelling of [`sample.mjs`](./sample.mjs): the same function under a name no built-in has
 * ([`README.md`](./README.md)).
 *
 * @module
 */

/** @type {(x: number) => string} */
const s = x => "s" + x;
export default s(1);

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

const $0=($1)=>"s"+$1;export default $0(1);

What it answers, its default export:

s1

Emergent Testing

Idle. Press Run to start the suite.

  • ./proof.f.mjs