Skip to content

nabla v2.1.0

Choose a tag to compare

@ryanduguid ryanduguid released this 18 Aug 11:51
· 57 commits to main since this release

v2.0.0 renamed every function. This one fixes what three of them compute, and stops two more from claiming to be something they are not.

Nothing is renamed, so formulas written against v2.0.0 keep working. Three functions do return different numbers, and only for the inputs they were handling wrongly.

Three functions did not do what they said

  • nb.OverLapDaysλ compared its dates as text. It converts all four arguments, so that a date written as text becomes a serial number, and then compared the raw arguments anyway. The four conversions were never read. Text dates compared as strings, which ranks "7/1/2025" after "17/1/2025", so the function took the wrong start and end and the subtraction that follows coerced them back to dates. Its own third example claimed 12 shared days for two January 2025 periods that share 2. Numbers and real dates were never affected.
  • nb.Periodsλ could not return a negative. Its description promises "Returns negative values if Date1 is after Date2" and two of its four examples show one, but the difference was floored at 1 before SIGN saw it. =nb.Periodsλ("15/5/2025", "31/3/2025") returned 1 where it should return -1.
  • nb.VDBλ ignored its No_Switch argument. It declares the argument and defaults it to FALSE, then called Excel's VDB without it, so passing TRUE did nothing. =nb.VDBλ(1000, 100, 5, 1.5, TRUE) now gives 300.00, 210.00, 147.00, 102.90 and 72.03, against the 121.50, 121.50 tail that switching to straight line produces. Calls that omit the argument are unaffected, including nb.Depreciateλ's VDB method.

Two of the three were hidden by their own worked example, which printed the answer the bug produced, so those examples are corrected with them. Every other cached value in the workbook is byte-identical to v2.0.0; the one cell that moved is the corrected example result on nb.OverLapDaysλ's sheet.

The depreciation helpers no longer claim to be ATO methods

nb.DiminishingValueλ described itself as the ATO 200% diminishing value method and nb.PrimeCostλ as the ATO prime cost method. Neither is one. They take a cost and an effective life and nothing else: no acquisition date, no income year, no days held, no disposal. nb.DiminishingValueλ also writes the entire undeducted residual off in its final period, so for a cost of 1,000 over five years it returns 400, 240, 144, 86.40 and 129.60, where a diminishing-balance calculation deducts 51.84 that year and carries the rest forward.

The schedules are unchanged and still useful for modelling. What changes is that they are described as modelling schedules rather than tax calculations, in the function help, the method codes on nb.Depreciateλ, the Data Validation sheet, the Australian tax worksheet and the README. The worksheet says so on its face, and the README says plainly not to use them to prepare a return.

Help that had drifted from the code

  • Three worked examples called a different function than the one they document: nb.RollingMinλ's called nb.RollingMaxλ, nb.RollingSumλ's called nb.RollingMinλ, and nb.ScheduleValuesByItemsλ's called nb.ScheduleRatesByItemsλ. Each claimed result was correct for the function it wrongly called.
  • nb.RollingAvgλ claimed 1,3,6,9,12, the running total. Excel gives 1,1.5,2,3,4.
  • nb.Amortiseλ's help pointed at LableAmortiseλ, a transposition of a function that does exist.

Gates

Five now, four of them in CI.

  • tools/verify_signatures.py reads the worked examples as well as the signatures and parameter tables: 117 signatures, 122 parameter tables, 76 example blocks. Run against the source before these fixes it names all four example defects.
  • tools/verify_previous_names.py is new. It checks the published functions.csv against tools/released-names-v1.2.6.txt, which records the 130 names the last release before the rename shipped. Counting alone proves a bijection, not the right one, so it also requires each new bare name to begin with the old one, which is the only shape the rename ever took.
  • previous_name is pinned to that released baseline rather than to the build's own intermediate names. A function whose predecessor is not in the file records nothing rather than a plausible-looking guess.
  • The build's help corrections can no longer reach a live formula. That refresh was a blanket text replace across the whole worksheet, and it once rewrote a real formula on a neighbouring sheet and spilled #SPILL! across it. It is now confined to cached values.

Known and not fixed

  • nb.Periodsλ counts complete intervals where its examples count boundaries crossed, so its forward example returns 1 against the 2 it claims and its W example 52 against 53. Its demonstration sheet also ships five cached #VALUE! cells, which Excel replaces with the right answers the moment the file opens.

    Corrected 18 August 2026: this bullet first said the function returns #VALUE! for range arguments. It does not. That came from a probe naming a worksheet that does not exist; the cached errors are stale, not live.

  • Four functions ignore their date conversions the way nb.OverLapDaysλ did: nb.PeriodLabelλ, nb.ScheduleRatesλ, nb.ScheduleValuesλ and nb.Timelineλ.

Full detail in CHANGELOG.md. nabla.xlsx is attached below.