Skip to content

Commit ca0bb89

Browse files
Add SEQUENCE built-in function (#1645)
## Problem HyperFormula was missing the SEQUENCE dynamic array function for generating sequential number arrays. ## Fix Implements `SEQUENCE(rows, [cols], [start], [step])` as a new `SequencePlugin`: - Returns a rows×cols array of sequential numbers, filled row-major - Parse-time array size prediction via `sequenceArraySize()` — handles NUMBER and STRING literals; non-literal args (cell refs, formulas) return `#VALUE!` (architectural limitation: array size must be known at parse time) - Error types match Excel: negative dims → `#VALUE!`, zero dims → `#NUM!` (mapped from Excel's `#CALC!`) - `emptyAsDefault: true` on optional params — empty args like `=SEQUENCE(3,,,)` use declared defaults - i18n for all 17 languages with proper Excel-localized names ## Changed files | File | Change | |------|--------| | `src/interpreter/plugin/SequencePlugin.ts` | New plugin: `sequence()` + `sequenceArraySize()` | | `src/interpreter/plugin/index.ts` | Plugin registration | | `src/i18n/languages/*.ts` (17 files) | SEQUENCE translations | | `docs/guide/built-in-functions.md` | SEQUENCE row in Array functions table | | `docs/guide/release-notes.md` | Unreleased section | | `CHANGELOG.md` | Added entry | | `test/smoke.spec.ts` | 3 smoke tests | | `test/fetch-tests.sh` | Robustness fix for `git pull` | ## Tests Regression tests in `handsontable/hyperformula-tests` (branch `feature/SEQUENCE`): | Group | Tests | Coverage | |-------|-------|----------| | Core sanity | #1#8 | Basic usage, MS docs examples | | Default parameters | #9#13 | Omitted cols/start/step | | Empty args | #14#21 | emptyAsDefault behavior | | Step variants | #22#28 | Zero, negative, fractional step | | Truncation | #29#35 | Fractional dims, trunc-to-zero | | Error conditions | #36#48 | Zero/negative dims, text, arity, propagation | | Type coercion | #49#59 | Booleans, strings, cell refs, empty cells | | Large sequences | #60#63 | 100×100, 1000×1, 1×1000 | | Fill order | #64#69 | Row-major verification | | Function combos | #70#74 | SUM, AVERAGE, MAX, MIN, COUNT | | Behavioral | #75#80 | Max dims, spill | | Dynamic args | #81#82 | Architectural limitation (cell ref → #VALUE!) | - 82/82 PASS confirmed in Excel desktop (Microsoft 365) - 3 smoke tests in `test/smoke.spec.ts` <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Adds a new array-producing built-in (`SEQUENCE`) with parse-time size prediction rules; mistakes here can affect array vertex creation and spill/error behavior across formulas. Remaining changes are documentation/i18n updates plus a minor test script tweak. > > **Overview** > Adds the `SEQUENCE(rows, [cols], [start], [step])` built-in via a new `SequencePlugin`, generating row-major numeric arrays and enforcing dimension/max-sheet limits with appropriate errors. > > Introduces parse-time result sizing (`sequenceArraySize`) that only accepts literal `rows`/`cols` (non-literal dimensions now yield `#VALUE!` due to unknown output size), and wires the plugin into the interpreter exports. > > Updates changelog and docs to list `SEQUENCE`, adds function name translations across all language packs, and adjusts `test/fetch-tests.sh` to pull explicitly from `origin` for the current branch. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit b08cd79. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent 04180f8 commit ca0bb89

File tree

23 files changed

+198
-1
lines changed

23 files changed

+198
-1
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
1111

1212
- Added `maxPendingLazyTransformations` configuration option to control memory usage by limiting accumulated transformations before cleanup. [#1629](https://github.com/handsontable/hyperformula/issues/1629)
1313
- Added a new function: TEXTJOIN. [#1640](https://github.com/handsontable/hyperformula/pull/1640)
14+
- Added a new function: SEQUENCE. [#1645](https://github.com/handsontable/hyperformula/pull/1645)
1415

1516
### Fixed
1617

docs/guide/built-in-functions.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ Total number of functions: **{{ $page.functionsCount }}**
5858
| ARRAYFORMULA | Enables the array arithmetic mode for a single formula. | ARRAYFORMULA(Formula) |
5959
| FILTER | Filters an array, based on multiple conditions (boolean arrays). | FILTER(SourceArray, BoolArray1, BoolArray2, ...BoolArrayN) |
6060
| ARRAY_CONSTRAIN | Truncates an array to given dimensions. | ARRAY_CONSTRAIN(Array, Height, Width) |
61+
| SEQUENCE | Returns an array of sequential numbers. | SEQUENCE(Rows, [Cols], [Start], [Step]) |
6162

6263
### Date and time
6364

docs/guide/known-limitations.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,3 +37,4 @@ you can't compare the arguments in a formula like this:
3737
* For certain inputs, the RATE function might have no solutions, or have multiple solutions. Our implementation uses an iterative algorithm (Newton's method) to find an approximation for one of the solutions to within 1e-7. If the approximation is not found after 50 iterations, the RATE function returns the `#NUM!` error.
3838
* The INDEX function doesn't support returning whole rows or columns of the source range – it always returns the contents of a single cell.
3939
* The FILTER function accepts either single rows of equal width or single columns of equal height. In other words, all arrays passed to the FILTER function must have equal dimensions, and at least one of those dimensions must be 1.
40+
* Array-producing functions (e.g., SEQUENCE, FILTER) require their output dimensions to be determinable at parse time. Passing cell references or formulas as dimension arguments (e.g., `=SEQUENCE(A1)`) results in a `#VALUE!` error, because the output size cannot be resolved before evaluation.

docs/guide/list-of-differences.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,3 +99,4 @@ To remove the differences, create [custom implementations](custom-functions.md)
9999
| DEVSQ | =DEVSQ(A2, A3) | 0.0000 | 0.0000 | NUM |
100100
| NORMSDIST | =NORMSDIST(0, TRUE()) | 0.5 | Wrong number | Wrong number |
101101
| ADDRESS | =ADDRESS(1,1,4, TRUE(), "") | !A1 | ''!A1 | !A1 |
102+
| SEQUENCE | =SEQUENCE(0) | VALUE | N/A | CALC |

src/i18n/languages/csCZ.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,7 @@ const dictionary: RawTranslationPackage = {
188188
SEC: 'SEC',
189189
SECH: 'SECH',
190190
SECOND: 'SEKUNDA',
191+
SEQUENCE: 'SEQUENCE',
191192
SHEET: 'SHEET',
192193
SHEETS: 'SHEETS',
193194
SIN: 'SIN',

src/i18n/languages/daDK.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,7 @@ const dictionary: RawTranslationPackage = {
188188
SEC: 'SEC',
189189
SECH: 'SECH',
190190
SECOND: 'SEKUND',
191+
SEQUENCE: 'SEKVENS',
191192
SHEET: 'ARK',
192193
SHEETS: 'ARK.FLERE',
193194
SIN: 'SIN',

src/i18n/languages/deDE.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,7 @@ const dictionary: RawTranslationPackage = {
188188
SEC: 'SEC',
189189
SECH: 'SECHYP',
190190
SECOND: 'SEKUNDE',
191+
SEQUENCE: 'SEQUENZ',
191192
SHEET: 'BLATT',
192193
SHEETS: 'BLÄTTER',
193194
SIN: 'SIN',

src/i18n/languages/enGB.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,7 @@ const dictionary: RawTranslationPackage = {
190190
SEC: 'SEC',
191191
SECH: 'SECH',
192192
SECOND: 'SECOND',
193+
SEQUENCE: 'SEQUENCE',
193194
SHEET: 'SHEET',
194195
SHEETS: 'SHEETS',
195196
SIN: 'SIN',

src/i18n/languages/esES.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,7 @@ export const dictionary: RawTranslationPackage = {
188188
SEC: 'SEC',
189189
SECH: 'SECH',
190190
SECOND: 'SEGUNDO',
191+
SEQUENCE: 'SECUENCIA',
191192
SHEET: 'HOJA',
192193
SHEETS: 'HOJAS',
193194
SIN: 'SENO',

src/i18n/languages/fiFI.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,7 @@ const dictionary: RawTranslationPackage = {
188188
SEC: 'SEK',
189189
SECH: 'SEKH',
190190
SECOND: 'SEKUNNIT',
191+
SEQUENCE: 'JAKSO',
191192
SHEET: 'TAULUKKO',
192193
SHEETS: 'TAULUKOT',
193194
SIN: 'SIN',

0 commit comments

Comments
 (0)