jolt/test/conformance/known-divergences.edn
Yogthos e66a91750e Numbers-style category dispatch for binary numeric ops
Arithmetic and comparisons lowered to raw Chez ops, so an operand outside
Chez's tower (BigDecimal) crashed with a raw condition, and Chez contagion
leaked: (* 1.0 0) gave exact 0 where the JVM gives 0.0, (* ##Inf 0) gave 0
instead of ##NaN, (/ 1 0) raised an untyped error.

One seam now (host/chez/seq.ss): call position emits jolt-n* macros with the
both-Chez-numbers fast path open-coded; value position folds through the same
binary ops. Anything outside the tower falls to per-op slow hooks that
java/bigdec.ss extends, so bigdec arithmetic works in every position (the old
static-only :bigdec typing limitation is gone). JVM rules patched into the
fast path: a double operand wins, an exact zero divisor throws
ArithmeticException while a double zero divisor yields Inf/NaN, quot/rem/mod
cover ratios and doubles, min/max return the original operand with NaN
winning, a nil operand is NPE and a non-number CCE, zero-arg -// throw
ArityException at runtime instead of failing expansion.

Also: with-precision now binds *math-context* and bigdec results round with
real RoundingMode semantics (UNNECESSARY throws; division rounds to precision
instead of throwing); rationalize goes through the shortest decimal print
like BigDecimal.valueOf (the identity stub is gone); ratios coerce to bigdec
like Numbers.toBigDecimal; min/max int-literal operands no longer coerce to
flonum in the numeric pass.

Perf neutral: fib and seq benches unchanged (the fast path is two type checks
the optimizer folds); hinted fl/fx paths untouched. 19 JVM-certified corpus
rows; cts baseline 5614->5730 pass, 192->88 errors, 84->79 baselined
namespaces.
2026-07-02 06:41:45 -04:00

62 lines
5.2 KiB
Clojure

{:doc
"Rows of test/chez/corpus.edn whose :expected differs from reference JVM Clojure. The corpus is JVM-sourced (regen-corpus.clj), so this list is only the rows whose JVM value is an opaque host object that cannot round-trip to readable source — Java arrays, transients, atoms, beans, proxies, and chunks print as #object[..@addr] with a per-run identity — plus the (fn* foo) strictness case. For that the corpus keeps jolt's value. certify.clj gates on NEW (unlisted) divergences and STALE entries. Keyed by [suite label].",
:legend
{:numeric-model
"jolt has the full numeric tower (exact integer / Ratio / double / BigDecimal); binary ops dispatch by operand category with JVM contagion rules",
:host-model
"no JVM host: classes->name strings, type->symbol, *in* is a map, inline-impl extenders, duck-typed with-open close",
:reader-model
"jolt reader features (:jolt) + syntax-quote literal collapse (spec 2.4 S25); map source-order preserved",
:printer-model
"jolt printer renders transients/atoms/print-method overrides differently from JVM #object",
:strictness
"jolt is intentionally stricter: throws on odd assoc! args / defn with no param vector",
:impl-detail
"representation detail: syntax-quote yields a list? (JVM yields a Cons)",
:seq-type-model
"jolt models every seq as PersistentList (eager) or LazySeq (deferred); JVM reifies a specialized class per producer (Cons/Iterate/LongRange/Repeat/Cycle/ChunkedSeq/StringSeq/KeySeq/RSeq/ArraySeq/SubVector). Values and laziness are correct, only (class …) differs. jolt-aei7",
:chunking-model
"jolt now chunks range/vector seqs through map/filter like the JVM (forcing one element realizes the whole ~32-element chunk). What remains finer-grained: mapcat/dedupe realize 0 at construction where the JVM's (apply concat …) / sequence transformer force the first chunk just to build the seq. jolt-mm6v",
:integer-box-model
"jolt unifies every integer as one exact-integer type. A Chez fixnum is an immediate identical to the plain integer (no distinct identity to tag, no metadata on numbers), so (byte/short/int n) report Long, not Byte/Short/Integer. Value/arithmetic/equality are correct; a faithful narrow box would crash raw compiled (+ …) or de-optimize all arithmetic. jolt-k9sw"},
:entries
[{:suite "forms / fn",
:label "no param vector",
:category :strictness}
{:suite "io / cold tagged types via print-method",
:label "atom override fires nested",
:category :reader-model}
{:suite "io / cold tagged types via print-method",
:label "transient map",
:category :printer-model}
{:suite "io / cold tagged types via print-method",
:label "transient vector",
:category :printer-model}
{:suite "untested / JVM-shape stubs (documented jolt behavior)",
:label "bean is the map",
:category :host-model}
{:suite "untested / JVM-shape stubs (documented jolt behavior)",
:label "proxy resolves nil",
:category :host-model}
{:suite "untested / chunk family (eager equivalents) + cat",
:label "chunk round-trip",
:category :host-model}
{:suite "seq-type-model / specialized seq classes collapse", :label "cons over a vector", :category :seq-type-model}
{:suite "seq-type-model / specialized seq classes collapse", :label "iterate", :category :seq-type-model}
{:suite "seq-type-model / specialized seq classes collapse", :label "range", :category :seq-type-model}
{:suite "seq-type-model / specialized seq classes collapse", :label "repeat", :category :seq-type-model}
{:suite "seq-type-model / specialized seq classes collapse", :label "cycle", :category :seq-type-model}
{:suite "seq-type-model / specialized seq classes collapse", :label "vector seq", :category :seq-type-model}
{:suite "seq-type-model / specialized seq classes collapse", :label "string seq", :category :seq-type-model}
{:suite "seq-type-model / specialized seq classes collapse", :label "keys", :category :seq-type-model}
{:suite "seq-type-model / specialized seq classes collapse", :label "rseq", :category :seq-type-model}
{:suite "seq-type-model / specialized seq classes collapse", :label "sort", :category :seq-type-model}
{:suite "seq-type-model / specialized seq classes collapse", :label "subvec", :category :seq-type-model}
{:suite "seq-type-model / specialized seq classes collapse", :label "drop over a vector", :category :seq-type-model}
{:suite "chunking-model / unchunked realization granularity", :label "mapcat is fully lazy at construction", :category :chunking-model}
{:suite "chunking-model / unchunked realization granularity", :label "dedupe is fully lazy at construction", :category :chunking-model}
{:suite "integer-box-model / narrow int class collapses to Long", :label "byte class", :category :integer-box-model}
{:suite "integer-box-model / narrow int class collapses to Long", :label "short class", :category :integer-box-model}
{:suite "integer-box-model / narrow int class collapses to Long", :label "int class", :category :integer-box-model}
{:suite "integer-box-model / narrow int class collapses to Long", :label "instance? Byte is false", :category :integer-box-model}
{:suite "integer-box-model / narrow int class collapses to Long", :label "instance? Long is true", :category :integer-box-model}]}