value-lang 1.0.0

Runtime value representation (tagged unions / NaN-boxing).
Documentation
# value-lang v1.0.0 — API Freeze

**The surface is stable.** v0.2.0 delivered the NaN-boxed `Value`; v1.0.0 freezes it. Everything the crate exposes — `Value`, `Unpacked`, the re-exported `Symbol`, the `serde` representation, and the `std` / `serde` feature flags — is now stable under Semantic Versioning and will not change in a breaking way within the `1.x` series. No functional changes from 0.2.0; this release records the promise.

## What is value-lang?

A compact runtime value type for interpreted languages. A dynamically-typed interpreter needs one type to stand for every runtime value — `nil`, a boolean, a number, an interned name — and it copies that type on nearly every instruction. value-lang folds all of them into a single eight-byte `Value` that is `Copy`, register-sized, and free of any discriminant word, because the kind lives in the bit pattern itself (NaN-boxing). It is fully safe (`#![forbid(unsafe_code)]`), `no_std`, and needs no allocator.

## The frozen surface

The whole public API, and all of it is stable as of 1.0.0:

- **`Value`** — the eight-byte NaN-boxed value.
  - Constructors: `nil`, `bool`, `int`, `float`, `sym` (`nil` / `bool` / `int` are `const fn`).
  - Predicates: `is_nil`, `is_bool`, `is_int`, `is_float`, `is_sym`.
  - Accessors: `as_bool`, `as_int`, `as_float`, `as_sym` (each `Option`, never coercing).
  - `bits` and `unpack`.
  - Traits: `Copy`, `Clone`, `Default` (nil), `Debug`, `PartialEq` (IEEE-754 for floats, identity otherwise), and `From<bool | i32 | f64 | Symbol | Unpacked>`.
- **`Unpacked`** — the tagged-union view (`Nil`, `Bool`, `Int`, `Float`, `Sym`) for exhaustive matching; the dual of `Value::unpack` via `From<Unpacked>`.
- **`Symbol`** — re-exported from `intern-lang`; the interned string handle a `Value` can carry.
- **`serde`** (optional) — `Serialize` / `Deserialize` for `Value`, as an externally-tagged enum with symbols written as their raw id.

## The SemVer promise

- Nothing in the frozen surface is removed or changed in a breaking way within `1.x`. A breaking change means a new major version.
- `1.x` releases may **add** to the surface without breaking existing code.
- The **serialized `serde` form** is part of the contract and will not change within `1.x`.
- The **NaN-box bit layout** behind `Value::bits` is an implementation detail and is deliberately *not* promised: treat `bits` as an opaque, self-consistent token (stable within a build), not a wire format — use `serde` for persistence.
- MSRV (Rust 1.85) is a compatibility surface: a raise is a minor, documented change, never a patch.

`docs/API.md` carries the same promise inline, per public item.

## Why freeze now

The surface is deliberately small — one value type, one view enum, one re-exported handle — and it has not needed to grow. Every operation is total (no fallible constructors, no coercion surprises), the invariants are property-tested across randomized inputs, and adding a method later (for example a `from_bits` companion to `bits`) is a non-breaking `1.x` change. There is nothing speculative left to design, so there is nothing to gain by staying pre-1.0.

## Performance

Unchanged from 0.2.0 — every operation is sub-nanosecond. Latest local Criterion means, Linux x86_64 (WSL2 Ubuntu), Rust stable, release build:

| Operation                | Time     |
|--------------------------|---------:|
| Construct `nil`          |  0.09 ns |
| Construct `int` / `bool` |  0.20 ns |
| Construct `float`        |  0.31 ns |
| `is_int` (kind test)     |  0.20 ns |
| `as_int` (read payload)  |  0.29 ns |
| `unpack` (per value)     |  0.32 ns |
| `==` (two ints)          |  0.34 ns |

## Breaking changes

**None.** The 1.0.0 surface is identical to 0.2.0; this release only promises stability.

## Verification

Run on Windows x86_64 with testing on Linux (WSL2 Ubuntu), Rust stable and the 1.85 MSRV; the same commands run in the CI matrix across Linux, macOS, and Windows:

```bash
cargo fmt --all -- --check
cargo clippy --all-targets -- -D warnings
cargo clippy --all-targets --all-features -- -D warnings
cargo test
cargo test --all-features
cargo build --no-default-features
RUSTDOCFLAGS="-D warnings" cargo doc --no-deps
RUSTDOCFLAGS="-D warnings" cargo doc --no-deps --all-features
cargo deny check
```

All green. Counts at this tag:

- Default features: 13 unit + 6 property + 9 doctests.
- `--all-features`: 16 unit + 6 property + 9 doctests.

## Installation

```toml
[dependencies]
value-lang = "1"

# With serde:
value-lang = { version = "1", features = ["serde"] }

# no_std:
value-lang = { version = "1", default-features = false }
```

MSRV: Rust 1.85.

## Documentation

- [README](https://github.com/jamesgober/value-lang/blob/main/README.md)
- [API Reference](https://github.com/jamesgober/value-lang/blob/main/docs/API.md)
- [CHANGELOG](https://github.com/jamesgober/value-lang/blob/main/CHANGELOG.md)

---

**Full diff:** [`v0.2.0...v1.0.0`](https://github.com/jamesgober/value-lang/compare/v0.2.0...v1.0.0).
**Changelog:** [`CHANGELOG.md`](https://github.com/jamesgober/value-lang/blob/main/CHANGELOG.md#100---2026-07-01).