Standard ML of New Jersey
Release Notes


Version 2026.3
October 19, 2026


Summary

This release contains over 100 (mostly minor) bug fixes for issues identified by Claude and reported by Skye Soss. There are also a number of other bug fixes and improvements.

Details

Compiler

  • Added constant folding for the rotation operators

  • Switch to using mixed records for live variables in InvokeGC.

  • Switch to using mixed records to represent closures that contain both uniform and raw free variables.

  • Switch to using mixed records when spilling excess function arguments to the heap.

  • Add sanity checking for the various integer controls in the Control.Print structure. For example, the REPL will now always print the top-most part of a value, even when the Control.Print.printDepth flag is less than 1.

  • for the amd64 (a.k.a. x86-64) target, we now assume a Haswell processor.

Runtime System

  • Changed the heap layout to include an arena for "mixed" records.

  • The codegen library now zeros the padding in the object-file, which should make builds more deterministic (and fixes the problem of not being able to compile to a fixed point).

Basis Library

A large number of *Basis Library bugs were fixed (see the list below for details).

SML/NJ Library

A large number of SML/NJ Library bugs were fixed (see the list below or the smlnj-lib/CHANGES file for details).

  • The original HTML library has been renamed to HTML3 (the CM tilf is now html3-lib.cm). The modules in the library have not been renamed.

  • Added listKeys function to HASH_TABLE and MONO_HASH_TABLE signatures.

  • Added the Timestamp module to the Utility library. This module supports generating timestamps that respect the SOURCE_DATE_EPOCH environment variable.

ML-LPT

  • Fixed regression in ml-lex-mode (Issue #463)

  • Fixed a bug in handling grammars where there is no %start declaration, but the first nonterminal is declared as an %entry.

  • Fixed a bug where the code generated by ml-antlr is invalid

Concurrent ML

  • Fixes to the Barrier module.

  • Fixed a scheduling issue in recv.

  • Fixed several issues in the TraceCML module.

  • Fixed the behavior of CML's OS.Process.terminate to match the Basis Library specification.

  • Fixed TextIO.input1, TextIO.inputLine, and BinIO.input1 to restore the mVar on end of file.

Installation

  • A number of changes have been made to improve reproducibility of builds.

Bugs

Here is a list of the issues and pull requests that are closed with this release.

Issue Description

142

Vector pattern causes integer variables to be printed as abstract types

232

Spurious use of polyEqual

339

Build failure - unable to find PerID

361

Make build.sh script more portable

364

Fix Word.countTrailingZeros

365

Fix position calculation of funsig token

366

Fix the printing of vector patterns

367

Fix the pattern match to reference REF dcon

368

compiler throws an error upon invalid opaque signature match

370

The SExp parser re-parses top-level quoted symbols

371

The SExp parser parses negative numbers as symbols

373

JSONParser.parse does not ensure 0 is not followed by a digit

375

UnixEnv.addToEnv does not replace existing keys

376

ThompsonEngine does not implement ^

377

ThompsonEngine can’t match Interval (r, m, SOME m)

378

UTF8.map does not do anything

379

UTF8.exists always returns true

380

CharMap.mkCharMap creates a too-small array

381

Rand48’s incorrect implementation results in periodic results

382

HashSetFn.filter does not reset the number of elements if it removes everything

383

ListMapFn.all always return false

384

IntervalSetFn.add operation doesn’t properly merge consecutive ranges

385

Hash2TableFn.insert can corrupt the table

386

EditDistance.distance uses the wrong stride

387

Controls.mkOptionFlag evaluates toggled value eagerly

388

Format.LEFT justifies text to the right

389

Format.format raises Option instead of BadFormat on invalid format

390

line break cutoff is one character too strict in PP library

391

pretty-printing maxDepth is controlled by maxIndent

392

ANSI background color styles are not properly popped

393

Posix.ProcEnv.uname crashes on syscall failure

394

Int64.int value is sometimes corrupted

398

IntListMap.findAndRemove raises exception on failure

399

HashTable.findAndRemove does not update numItems

400

Word8Buffer.sub allows invalid indices and throws on valid indices

401

Word8Buffer.copy throws exception on valid input

402

Array.tabulate calls its function even on invalid input

403

Substring.isSubstring returns false when given empty strings

404

Date.fmt ignores %% if followed by a letter

405

Real.rem produces incorrect results for non-finite arguments

406

CharVectorSlice.getVec returns a slice containing the entire underlying vector

432

Hash.string' does not hash the first character

433

The hash table in the Atom module is never resized

434

EditDistance.distance treats transposition as free

437

Calling OS.IO.poll function with duplicate descriptors can result in a crash

438

Socket recv can trigger runtime crash

440

ParserComb.skipBefore returns NONE when it reaches EOF

440

Time.scan doesn’t backtrack after seeing .

442

Int64.div constant folding suppresses Overflow exception

443

NetHostDB.scan raises Overflow on parse error instead of returning NONE

444

Int32.abs of Int32.minInt should raise Overflow

445

IntInf.scan StringCvt.BIN accepts hex prefix

446

Real.toDecimal/Real.fromDecimal don’t round-trip

447

StringCvt.skipWS does not skip form feeds, returns, or vertical tabs

448

Vector.update does not raise Subscript on out-of-bounds index

449

TextIO.inputAll fails with 'divide by zero' error on empty stream

450

LargeInt.fmt StringCvt.HEX produces lowercase hex digits

451

Date.fromString does not skip leading whitespace

452

Date.fromTimeUniv o Date.toTime adds 12 hours to the date

453

Math.pow is unusually inaccurate

454

IntInf.pow does not handle negative exponents correctly

456

Timer.checkCPUTimer double-counts garbage collector time

463

ml-ulex --ml-lex-mode generates duplicate yystart_state datatype declaration

465

Unbound exception identifier causes compiler bug

466

Add type info in FLINT/fcontract to generate well-formed FLINT

470

Ignore inherited SMLNJ_HOME during source builds

We also fixed the following bugs that did not have issues associated with them (or were bug fixes ported from the legacy repository):

  • updated the unused-variable checker for changes to the Absyn.exp datatype

  • avoid Overflow exceptions when #line comments are very large (there is now an upper bound on the allowed line/column numbers)

  • fixed various boundary cases in the Array2 structure.

  • Socket.Ctl.getRCVBUF and Socket.Ctl.setRCVBUF controlled the SNDBUF

  • the PackReal64 structures had the byte orders backwards

  • Word.-(0wx7FFFFFFFFFFFFFFF, x) produced incorrect results

  • The Real.scan function was too permissive

  • Fixed dangling pointer bug when SetVMCache frees memory objects

  • Fixed "unbounded" traversal of cyclic values when the printDepth < 0

  • Rewrote Real64.rem to produce exact results.

  • The compiler no longer raises overflow when checking real literals with excessively large exponents

  • The order of the "don’t route", "peek", and "out-of-band" flags for socket I/O operations was backwards in the runtime system.

  • Socket.recvVecFrom can corrupt the address data.

  • Fix edge case of primitive readers/writers with chunk sizes < 1.

  • Fixed Date.fromTimeUniv and Date.fromTimeLocal on negative time values.

  • Fixed an issue where large strings were getting allocated as bytearrays, which broke the REPL printing.

  • (Mostly) fixed the behavior of rounding reals to integers. The ceiling, floor, and truncation functions are correct, but round and realRound do not break ties correctly.

Supported systems

We believe that SML/NJ will build and run on the following systems, but have only tested some of them:

Architecture Operating System Status

AMD64

macOS 11 (Big Sur)

macOS 12 (Monterey)

macOS 13 (Ventura)

macOS 14 (Sonoma)

macOS 15 (Sequoia)

Tested

macOS 26 (Tahoe)

Ubuntu 20.04.6 LTS

Tested

Ubuntu 22.04.2 LTS

Tested

 

ARM64

macOS 11 (Big Sur)

macOS 12 (Monterey)

macOS 13 (Ventura)

macOS 14 (Sonoma)

macOS 15 (Sequoia)

macOS 26 (Tahoe)

Tested

macOS 27 (Golden Gate)

Tested

Linux