More Than 16 Fixed Parameters Are Refused

Status: refused by design

17 parameters is not FunctionalScript. (a, b, …, q) => q is valid JavaScript, and fjs compile refuses it by design: the demo below shows what it prints.

A function has at most 16 fixed parameters, a language limit approved so that every valid function can be written, with the right length, by every backend. A 17th fixed name is refused; a rest parameter takes any number of arguments (parameters).

The row decl.parameter-limit of refused constructs registers the refusal, and parameters gives its reason.

Examples

/** @type {(...p: number[]) => number} */
const f = (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q) => q;
export default f(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17);

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

What to Write Instead

Take many arguments with a rest parameter, or pass one object, as alternative.f.js does:

/** @type {(...p: readonly number[]) => number | undefined} */
const f = (...p) => p[16];
export default f(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17);

It answers 17.

A Better Message

Today fjs compile prints more than 16 fixed parameters 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:60 - error: more than 16 fixed parameters
2 | const f = (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q) => q;
  |                                                            ^

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

sample.mjs:2:60 - error: a 17th fixed parameter is not FunctionalScript: a function has at most 16
2 | const f = (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q) => q;
  |                                                            ^ JavaScript binds the 17th argument here
  = help: take many arguments with a rest parameter, or pass one object:
          const f = (...p) => p[16];
  = note: refused by design, see spec/functions/parameters/limit/README.md

JavaScript source, sample.mjs:

/** @type {(...p: number[]) => number} */
const f = (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q) => q;
export default f(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17);

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

17

What to write instead

The FunctionalScript spelling, alternative.f.js:

/**
 * The FunctionalScript spelling of [`sample.mjs`](./sample.mjs): the same function, its arguments taken by a rest parameter
 * ([`README.md`](./README.md)).
 *
 * @module
 */

/** @type {(...p: readonly number[]) => number | undefined} */
const f = (...p) => p[16];
export default f(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17);

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

const $0=(...$1)=>$1[16];export default $0(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17);

What it answers, its default export:

17

Emergent Testing

Idle. Press Run to start the suite.

  • ./proof.f.mjs