Forum OpenACS Development: ANNOUNCE: Next Scripting Framework 2.5.0 (NX/XOTcl) — Tcl 9.0 and 9.1 support

Dear Community,

We are pleased to announce the availability of the Next Scripting
Framework (NSF) 2.5.0, including NX 2.5.0 and XOTcl 2.5.0. This
release completes the Tcl 9 compatibility work for the Tcl 9.0 and 9.1
series while retaining support for Tcl 8.5 and 8.6 on Linux, Windows,
and macOS. Highlights include return-value checking for nsf::proc,
introspection of constant object variables, improved argument
validation, and fixes for method dispatch, memory management, and
interpreter shutdown. The MongoDB binding has also been updated for Tcl 9.

Special thanks are due to the following adopters and supporters (in
alphabetical order): Oleg Checkulaev, Jan Nijtmans, Antonio Pisano,
Héctor Romojaro, and Maksym Zinchenko.

With this release, NSF and its predecessors have been available and
supported for more than 27 years. In May 1999, the first paper on
XOTcl was presented at the 5th USENIX Conference on Object-Oriented
Technologies and Systems (COOTS '99):

Gustaf Neumann & Uwe Zdun: Filters as a Language Support for Design
Patterns in Object-Oriented Scripting Languages, in: Proc. of
COOTS'99, San Diego, California, USA, May, 1999, URL:
https://www.usenix.org/legacy/events/coots99/full_papers/neumann/neumann.pdf

The work leading to this release was presented at the 10th OpenACS
conference and the 22nd European Tcl/Tk Users Meeting in July 2026 in
Vienna, Austria:

https://openacs.km.at/evaluate/org/129998253/conferencenews/

Diff stats since 2.4.0:

130 files changed, 9157 insertions(+), 6217 deletions(-)

The main changes are:

  • Tcl 9.1 compatibility (stubs and TIP 626/627 Command layout): Tcl 9.1
    removed the legacy objProc/objClientData fields from the Command
    struct, replacing them with objProc2/objClientData2. NSF added a set
    of version-neutral accessor macros (TCL_COMMAND_OBJPROC, etc.) and
    supporting CPP machinery. Stub headers and stub vector
    initialisation for 9.1 were also added.

    Binary compatibility: NSF uses internal Tcl interfaces and data
    structures that changed between Tcl 9.0 and 9.1. Separate NSF builds
    are therefore required for Tcl 9.0 and Tcl 9.1. When distributing
    binaries, provide builds for the Tcl versions you support.

    Background:
    https://core.tcl-lang.org/tips/doc/trunk/tip/626.md
    https://core.tcl-lang.org/tips/doc/trunk/tip/627.md

  • Tcl 9 size-type support: Updated collection lengths, indexes,
    argument counts, and related formatting to use Tcl_Size-compatible
    types and APIs throughout the NSF core. These changes address
    remaining assumptions about int-sized values while preserving
    compatibility with Tcl 8.

    Background:
    https://core.tcl-lang.org/tips/doc/trunk/tip/494.md
    https://core.tcl-lang.org/tips/doc/trunk/tip/660.md

  • Method dispatch: Fixed a crash and missing error reporting when a
    nonexistent method is called and all registered filter guards reject
    execution. Such calls now follow the unknown-method dispatch path.

  • Hashtable-lookup version-agnostic idiom: Introduced
    NsfFindHashEntry() to do lookup-only access using Tcl_FindHashEntry
    on 9.1+ instead of Tcl_CreateHashEntry(..., NULL), preventing
    accidental creation of empty command-table entries when using
    Tcl_CreateHashEntry() in modern Tcl (post TIP 626). Applied across
    method lookup, precedence lists, resolvers, filter/variable/forward
    listings, etc.

  • Scripting improvements:
    • nx::Object "info consts" (nx.tcl): New introspection method that
      lists only unmodifiable (constant) variables, similar to "info
      vars" but restricted to constants created via the Tcl 9 "const"
      command. The method accepts an optional pattern for filtering. On
      Tcl 8, it returns an empty list.

    • "nsf::proc" return-value checkers (nsf.c + tests): You can now
      write "nsf::proc ... -returns /spec/ ..." and introspect it
      with "nsf::cmd::info returns". The underlying Tcl "string is" checker
      was also fixed so it no longer clobbers the result when used as a
      return-value checker (save/restore of the original result).

    • "nsf::parseargs": Now enforces "required" flags when passed an
      empty argument list, reporting missing required arguments.

    • NX parameter validation: Malformed property and variable
      specifications, such as ":property {fiscalyear:integer,
      required}", now produce an explicit error.

    • "nsf::parseargs": Better error handling for malformed parameter
      specs. Stray spaces like in ":property {fiscalyear:integer,
      required}" now raise a proper error.

    • Script-level refinements to NX and XOTcl 2 object systems (nx.tcl,
      xotcl.tcl):

      The "delete" accessor now rejects single-valued properties and
      variables, consistently with add. Additional tests document
      per-slot accessor behaviour.

      Incremental slot operations now correctly preserve custom
      "value=add" and "value=delete" methods, while avoiding repeated
      computations.

      "info" introspection for object parameters now returns "switch"
      correctly

      Tcl 9 "trace variable removal" (testo.xotcl) — trace variable
      (deprecated since 8.4) was removed by TIP 673 in Tcl 9; tests
      updated accordingly.

    • File encoding (Script.xotcl): Switched to UTF-8 for robustness
      across Tcl 9 variants (e.g. TIP 657).

    • Serializer verbosity (serializer.tcl): Reduced log noise

    • ZIP downloads: nx::zip now flushes buffered output between files
      to avoid excessive buffering and potential integer overflows on
      slow connections. The ns_returnZipFile method accepts an optional
      -channel argument for downloads using an existing NaviServer
      connection channel, including background operations.

  • MongoDB: Updated the NSF/NX binding for Tcl 9, including size-type
    corrections that fix stack corruption in collection queries. JSON
    generation now uses Canonical Extended JSON through
    bson_as_canonical_extended_json(), replacing the deprecated
    bson_as_json() call. Applications consuming generated JSON should
    account for the changed representation.

    Added ::mongo::oid::gettimestamp to extract the timestamp embedded
    in an ObjectId, and updated the build instructions and tests.

    Testing covered MongoDB C driver/libbson 1.30.8 and MongoDB
    Community Server 8.0.28 on macOS and Linux. MongoDB C driver 2.x
    has not been integrated or tested.

  • Bug fixes & hardening (selection):
    • Thread-safe exit handling (POSIX, other than WIN native):
      ExitHandler reworked to call Tcl_Release(interp) only from the
      interp-owning thread (i.e., the one registered during Nsf_Init()),
      avoiding "Tcl_AsyncDelete: async handler deleted by the wrong
      thread" crashes and a memory leak.

    • Safe interpreters: Fixed NSF initialisation in Tcl 9 safe
      interpreters by skipping access to the unavailable
      ::tcl::unsupported::disassemble command.

    • Simplified memory management: Removed the "canFree" flag from the
      "nsfParam" struct, in favour of pure refcounts, fixing a memory leak
      on Tcl_DupInternalRep.

    • Worked around a Tcl 9 memory leak involving an NX method-context object.

    • MongoDB client pool: guarded "mongoc_client_pool_push/pop" with a
      mutex to prevent races.

    • XOTcl2: fixed handling of leading "~" in file paths under Tcl 9.

    • Robust parallel package installs (e.g., avoid overwriting of the
      package index files)

    • Runtime hardening: Selected internal consistency checks now remain
      active in release builds and produces explicit diagnostics when an
      invariant is violated. Additional checks improve error handling in
      method dispatch, command-list maintenance, and variable resolution.

    • Build improvements: Compiler-specific warning detection improves
      portability across GCC and Clang. Generated NSF stub declarations
      now include printf-format annotations, allowing compilers to
      detect format-string mismatches. Warning groups and Tcl source
      directories used for stub generation can be overridden.

  • Documentation:

    Object.man: Added fragment about "info consts"

  • NSF has been built and tested with Tcl 9.0.4 and the Tcl 9.1b1 RC1
    prerelease. Build and test results are available at:

    https://github.com/nm-wu/nsf/actions
    https://ci.appveyor.com/project/mrcalvin/nsf-2ylk0/history
    Important: As for Tcl 8.5, NSF is only tested with (unreleased) Tcl
    8.5 revisions taken from `core-8-5-branch` at https://core.tcl-lang.org/tcl/.

The detailed changelog is available at

https://next-scripting.org/xowiki/download/file/ChangeLog-2.4.0-2.5.0.log

The Next Scripting Framework version 2.5.0 (containing NX 2.5.0 and XOTcl
2.5.0) can be obtained from https://next-scripting.org/. Please report
issues and wishes by opening a ticket at:

https://sourceforge.net/p/next-scripting/tickets/

Best regards
- Gustaf Neumann
- Stefan Sobernig