Skip to content

Releases: leifericf/mino

v0.100.33

09 May 07:48

Choose a tag to compare

Add MINO_FLOAT32 tier; split float? and double?

double_qmark.cljc asserts (double? (float 0.0)) is false. mino had
one float tier so (float x) and (double x) produced
indistinguishable values. Introduce MINO_FLOAT32 sharing the same
`as.f` storage (32-bit narrowing happens at mino_float32
construction) so double? can distinguish 64-bit from 32-bit.
float? matches both tiers; double? matches only MINO_FLOAT.
(type x) returns :float for 64-bit, :float32 for 32-bit.

Arithmetic always promotes to MINO_FLOAT (matching JVM where Float
arithmetic yields Double): tower_to_double, classify_or_throw,
is_compare_number, tower_cmp, has_nan, prim_inc / prim_dec fast
paths, unary -, extract_integer_for_cast, narrow_cast,
prim_NaN_p, prim_infinite_p, GC clone, hash, print all dispatch
through both tags. Equality between MINO_FLOAT and MINO_FLOAT32
is false even when values match (matches JVM (= 5.0 (float 5)) =
false).

New prim_double registered alongside int / long / short / byte;
replaces the (def double float) alias. prim_float now returns
MINO_FLOAT32.

Internal 1476 / 7091 / 0. double_qmark.cljc 43/46 -> 46/46.
External suite 211 -> 212 OK.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

v0.100.32

09 May 07:48

Choose a tag to compare

Add MINO_MAP_ENTRY value type

JVM Clojure's MapEntry is vector-shaped but distinct: (key [1 2])
throws because a plain vector isn't a Map.Entry. mino conflated
the two, so key.cljc and val.cljc failed on the throw assertions.

Add a distinct MINO_MAP_ENTRY type carrying (k, v). seq of a map /
sorted-map / record now produces MAP_ENTRY values; find /
clojure.lang.MapEntry/create likewise. key / val accept only
MAP_ENTRY. vector? / coll? / counted? / associative? /
reversible? / sequential? return true on it. Equality with
[k v] is element-wise via the cross-type sequential path; hash
matches a 2-vector so it round-trips through hash maps.
first / rest / nth / get / count / empty? / vector destructuring
/ compare / into-map / conj-map / conj-of-MAP_ENTRY all dispatch
through it. New C primitive `map-entry` constructs one.

aset is intentionally not implemented for MAP_ENTRY (entries are
immutable in JVM Clojure too).

Internal 1476 / 7089 / 0. key.cljc 8/17 -> 17/17, val.cljc 7/16 ->
16/16, plus merge / sort / sort_by / zipmap / seq fixes for the
MAP_ENTRY contagion through into / conj / compare / hash. External
suite 209 -> 211 OK.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

v0.100.31

09 May 06:32

Choose a tag to compare

Numeric tower: (float x) narrows to 32-bit float precision

float.cljc asserts (float r/min-double) equals (float 0.0) because
the value underflows the 32-bit float range, and (float r/max-double)
/ (float ##Inf) / (float ##-Inf) all throw because they exceed it.
mino had (float x) as an identity-on-floats / cast-on-numbers --
no precision narrowing, no range check.

Update prim_float: range-check against [-FLT_MAX, FLT_MAX] (NaN
exempt, passes through; Inf and overflow throw eval/type MTY001),
then narrow precision via (double)(float)d which routes through
the hardware float-cast.

Internal suite 1476 / 7087 / 0. float.cljc 15/0/4 -> 19/0/0.

Partial of the Group C.2 plan: narrows the cast contract without
introducing a distinct MINO_FLOAT32 value type. (float? x) /
(double? x) distinctions remain a JVM-only divergence.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

v0.100.22

09 May 06:32

Choose a tag to compare

Numeric tower: Add (short x) and (byte x) with range checks

clojure.core-test.num exercises (short 1) and (byte 1) in its
:default arm. mino had int and a long alias but no short or byte,
so the test errored on the first (short 1) call. Add prim_short
and prim_byte sharing an extract_integer_for_cast helper that
covers MINO_INT, MINO_FLOAT, MINO_BIGINT, MINO_RATIO, and
MINO_BIGDEC, with NaN / infinity / out-of-long-range checks. The
new primitives then range check against int8 / int16 and throw on
overflow. Result is returned as MINO_INT since mino has no
narrow-int tier; only the contract narrows.

Also relax num to pass nil through (returning nil) instead of
throwing, matching the cross-dialect :default arm of the test.
Non-numeric, non-nil inputs still throw.

Internal suite 1476 / 7071 / 0. num.cljc: errors 1 -> 0, all 26
assertions pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

v0.100.21

09 May 06:32

Choose a tag to compare

Bridge: Expose clojure.lang.MapEntry/create as 2-vector ctor

Cross-dialect tests in jank-lang/clojure-test-suite (key.cljc,
val.cljc, ...) build a map-entry under the :default arm via
(clojure.lang.MapEntry/create k v). mino's map entries are
2-element vectors so the data shape already matches; only the
constructor namespace was missing. Define a clojure.lang.MapEntry
namespace with create alongside the existing JVM bridges.

Internal suite 1476 / 7071 / 0. External suite errors 10 -> 8.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

v0.100.20

09 May 04:55

Choose a tag to compare

Build: Make make clean on gcc-11 (Ubuntu 22.04 release-build)

The release-build workflow runs on ubuntu-22.04, whose default cc
is gcc-11. Two -Werror regressions broke linux-amd64 and
linux-arm64 there (the v0.99.0 - v0.99.4 attempts only added log
capture, never the underlying fix).

src/gc/driver.c named -Wdangling-pointer in a #pragma GCC
diagnostic ignored block, but that flag was added in gcc-12. On
gcc-11 the pragma fires -Werror=pragmas. Both the push and pop
guards now require __GNUC__ >= 12.

main.c's two snprintf(path_buf, sizeof(path_buf), "%s/lib/%s",
dir, name) calls in the .cljc/.cljs/.clj arm tripped
-Werror=format-truncation. The pre-snprintf bound check
(dlen + nlen + 6 < sizeof(path_buf)) is sound but gcc-11 cannot
propagate it through to snprintf. Replaced with a check on the
snprintf return value: a truncated write skips the candidate
rather than silently using a clipped path. Same end result, no
pragma needed.

Verified locally with gcc-11.3 (matches Ubuntu 22.04), gcc-12.4,
and gcc-14.2. All three build clean with -Werror. Internal suite
1476 / 7071 / 0.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

v0.98.6

30 Apr 17:37

Choose a tag to compare

Bump to v0.98.6: bump MINO_VERSION_* constants

The five v0.98 tags (v0.98.0 through v0.98.5) shipped with
MINO_VERSION_MINOR=97 / MINO_VERSION_PATCH=5 left over from v0.97.5
because the version triple wasn't bumped during the cycle. The
release-build workflow asserts the tag matches the header constants
and rejected v0.98.5 on every platform.

Per the no-force-push-tags rule this lands as a fresh patch tag.
No behavioral change; only src/mino.h's version triple moves
forward to 0.98.6.

v0.97.5

30 Apr 08:49

Choose a tag to compare

Bump to v0.97.5: clojure.spec.alpha abbrev/describe

Adds the two canon introspection helpers that the spec.alpha audit
flagged. Generators (gen, exercise) continue to throw :mino/unsupported.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

v0.96.9

30 Apr 04:31

Choose a tag to compare

Bump to v0.96.9 to fire release-build via workflow_dispatch

v0.94.5

29 Apr 12:38

Choose a tag to compare

Bump to v0.94.5: static-link Windows binary

mino.exe failed to start on fresh Windows installs (Scoop install,
PowerShell or cmd) with exit code 0xC0000135 STATUS_DLL_NOT_FOUND.
Mingw-gcc by default emits an exe that imports libgcc_s_seh-1.dll
and libwinpthread-1.dll; the GHA runner has those DLLs available so
the smoke test passed, but a clean Windows desktop doesn't. The
bootstrap Makefile now passes -static to the linker on Windows so
mingw's runtime is baked into the exe. macOS and Linux remain
dynamically linked.

Surfaced because the v0.94.4 stdout-buffering patch couldn't help
when the binary itself never executed; -static makes the patch
actually observable.