Skip to content

Re-evaluate later: a live (computing) native form built on the inert interchange form #87

Description

@dprada

What. This is a decision to re-evaluate later, recorded now so that it is not lost. Once PyUnitWizard's native inert interchange form exists (#82, design in #83), re-evaluate whether a live native form can be built on top of it. A live form would compute (arithmetic, numpy ufuncs, comparisons) and keep every advantage of the inert form. It should also solve problems the existing unit libraries still have.

Context. On 2026-09-24 Diego and the agent working on Sabueso separated two meanings of "a native PyUnitWizard quantity form":

  • A. Inert interchange form. Values plus a verified unit descriptor: canonical name, UCUM code, SI factor/offset/exponents, kind, and optionally a digest. It does not compute; to compute, you convert to pint, openmm.unit, astropy or unyt. PyUnitWizard's "string" form is already an inert form, so there is precedent. Adopted as the direction of QuantityRecord: PyUnitWizard's native inert interchange form (verified quantity records) #82.
  • B. Live form. A quantity class that computes. Not now. The reasons:
    • PyUnitWizard declined a native Rust core on 2026-08-15 (devguide/declined_proposals/rusterization_pyunitwizard_core.md). Of a 38 µs conversion, 16 µs is pint doing the real work.
    • Unit libraries are many and under-adopted (McKeever 2021), and another one adds to the fragmentation.
    • Parsing, definitions, ufuncs and performance are already solved by pint, astropy and unyt. What none of them solves is verified interchange, and that is what A provides.

What a live form would have to offer to be worth building. Beyond what A gives, it must fix problems the existing libraries still have:

Problem in existing libraries Evidence What a live form built on A could do
No quantity kinds: Hz vs Bq, J vs N·m, absolute temperature vs difference pint#676 (closed without implementation) Carry kind through arithmetic, and refuse or warn when kinds are mixed
Quantities from different registries cannot be combined #84; openff-units ships its own registry One descriptor model, independent of any registry
The unit is lost at serialization boundaries Mars Climate Orbiter; uibcdf/molsysviewer#96; uibcdf/molsysmt#240 Always serializable to the verified record, with no conversion step to forget
Per-value overhead for heterogeneous collections OpenFF {"val", "unit"} records Vectorized mixed-unit arrays (TaggedQuantities) that also compute
Readers outside Python need the library CF needs UDUNITS; ASDF needs its library Every live value maps one-to-one onto a record that the standard-library reader understands
Logarithmic scales (pIC50, pKa) are not units UCUM treats them as special or arbitrary; pint has no -log10(M) Named kinds with an explicit definition and conversion to the underlying quantity

Conditions to reopen. All must hold; start from measurements, not from this list.

  1. The inert form (QuantityRecord: PyUnitWizard's native inert interchange form (verified quantity records) #82) has shipped and has real consumers: at least Sabueso and one MolSysSuite member.
  2. A consumer has a measured workflow where converting between the inert form and a computing backend is a material cost, or where a problem in the table above has caused a real error that conversion cannot prevent.
  3. The live form can be built on the same descriptor model, not as a second unit model. Two unit models inside PyUnitWizard would recreate the "several sources of truth" failure recorded in Design record: serializing and exchanging quantities across MOLI and MolSysSuite #83. The arithmetic engine may still delegate to an existing library.
  4. The re-evaluation weighs the cost of maintaining a computing quantity class across Python 3.11–3.14, numpy and pandas against the declined-rusterization evidence.

If these hold, the design question is whether the live form should be a thin computing layer over numpy with the descriptor, a wrapper that delegates arithmetic to pint while keeping kinds and verification, or something else. This issue does not pre-decide it.

Related: #83 (design record), #82 (inert form), #84, #85, #86, #81.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    blockedWaiting on a tracked dependencyproposalDesign or governance proposal

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions