Skip to content

Releases: ibrahimkteish/SwiftRandomKit

2.1.0

Choose a tag to compare

@ibrahimkteish ibrahimkteish released this 10 Jul 19:54

No library changes — SPM consumers are unaffected.

The test suite (37 suites, 179 tests) is migrated from XCTest to Swift Testing: @Test functions with #expect/#require, value-type suites, per-test seeded RNGs, and parallel execution by default. Availability-gated suites (Zip) carry @available per test function, specific-error expectations use #expect(throws: SomeError.case), and the Sudoku validity helper threads sourceLocation so failures point at the calling test.

Validated on Swift 6.0.2 (macOS + Linux), the current Xcode toolchain, and the latest Swift Linux image.

2.0.0

Choose a tag to compare

@ibrahimkteish ibrahimkteish released this 10 Jul 18:59

A major release: critical correctness fixes, a rework of the library's concurrency
story, removal of APIs that didn't make sense, and a batch of new generators. If you are
coming from 1.x, build against 1.3.0 first — it deprecates everything 2.0 removes, with
messages naming the replacements.

Concurrency: RandomGenerator no longer requires Sendable

Generators are ordinary values, confined to the isolation domain where they are built
and run:

  • The protocol requires neither Sendable nor Element: Sendable. Conformers may hold
    non-Sendable state and produce non-Sendable values.
  • Transform closures (map, flatMap, filter, retry, tryMap, ...) are plain
    closures — they can capture anything the surrounding context can.
  • Leaf generators (IntGenerator, FloatGenerator, BoolGenerator, Always,
    Character, UnicodeScalar, the seeded RNGs, and all ready-made generators) declare
    Sendable explicitly, and closure-free combinators (Array, Collect, Concat,
    Dictionary, Element, Frequency, OneOf, OrNil, Print, Shuffled, Tuple,
    Zip, ...) propagate it conditionally — so leaf-only compositions remain shareable.
  • RemoveDuplicates drops its lock and @unchecked Sendable; the compiler now enforces
    its single-domain confinement.
  • AttemptBounded.FallbackStrategy is no longer Sendable (it carries a closure).

Migration: pipelines containing closures are no longer Sendable. Move one into a
Task and region isolation checks the transfer; to use a pipeline from several tasks,
build one per task.

Fixed

  • AnyRandomGenerator never advanced the caller's RNG — erased generators (including
    the character presets) replayed the same value forever under a seeded RNG. Seeded
    sequences involving erased generators change with this fix.
  • Zip(...).map { a, b, c in } compiles again on Swift 6.3 via a pack-argument overload.
  • compactMap/retryMap could crash on a force-unwrap when the attempt budget was
    exhausted; they now produce Optional (nil on exhaustion). retryThrowing produces
    Result (the last failure on exhaustion), runs its transform once per candidate, and
    no longer backstops with fatalError.
  • uiColor(alpha:)/swiftUIColor(alpha:) silently ignored their alpha parameter; the
    parameter is removed and the generator's init(alpha:) visibly governs.
  • UnicodeScalar/Character generation over ranges spanning the surrogate gap
    (U+D800–DFFF) no longer biases toward the lower bound or traps; the gap is skipped
    uniformly.
  • Frequency no longer materializes a sum-of-all-weights array on every run (cumulative
    bounds + one draw), and fails fast with clear preconditions on empty or all-zero
    distributions.
  • AttemptBounded counts the initial run toward maxAttempts (previously
    maxAttempts: 3 ran the upstream up to 4 times); maxAttempts must be ≥ 1.
  • IntGenerator(in: 0..<0) traps with a clear message instead of a confusing
    ClosedRange precondition.
  • The package declared iOS 13 but could not compile for iOS at all (Zip's parameter
    packs require the iOS 17 runtime). Platforms are now honestly declared —
    iOS 13 / macOS 10.15 / tvOS 13 / watchOS 6 — with only Zip and its operators gated
    behind @available(macOS 14, iOS 17, tvOS 17, watchOS 10).
  • IPAddressGenerator imports Foundation explicitly.

Added

  • RandomGenerators.Bernoulli / .bool(probability:) — biased coin.
  • orNil(probability:) — produce nil with a given probability.
  • RandomGenerators.Normal (Box–Muller) and RandomGenerators.Exponential
    distributions, with .normal(mean:standardDeviation:) / .exponential(rate:) sugar.
  • RandomGenerators.oneOf(...) — uniform pick across 2–4 generators of different
    concrete types sharing an element type.
  • RandomGenerators.string(of:count:) and characterGen.string(count:).
  • Seeded RNGs: Xoshiro256 (xoshiro256++), SplitMix64, PCG (independent streams via
    sequence:).
  • Dice(sides:) with d4/d6/d8/d10/d12/d20/d100 presets.
  • Dot-syntax statics: .int(in:), .float(in:), .bool.
  • RandomGenerators.sudoku(difficulty:) convenience.
  • DocC catalogs for both modules and the swift-docc-plugin.
  • A runnable example target exercising the whole API.

Changed (breaking)

  • BoolRandomGenerator is renamed BoolGenerator (deprecated typealias retained).
  • compactMap/retryMap produce Output?; retryThrowing produces
    Result<Output, Error>.
  • Frequency is constructed via RandomGenerators.frequency(_:); the receiver-ignoring
    instance method is removed.
  • UnicodeScalar and Character are standalone generators constructed from a range;
    the combinator forms (whose upstream was ignored) are removed.

Removed

  • ZipArrayGenerator, zipAll(), zipGenerators(...) — exact duplicates of Collect;
    use [generators].collect().
  • gen.always(_:), gen.colorGenerator(alpha:) — receiver-ignoring factories; construct
    Always(_:) / ColorGenerator(alpha:) directly.
  • CreditCardGenerator.Generated — use Element.

1.3.0

Choose a tag to compare

@ibrahimkteish ibrahimkteish released this 10 Jul 18:56

The final planned release of the 1.x line. It backports the features and critical fixes
from the upcoming 2.0 and deprecates every API that 2.0 removes, so migrating is mostly
a matter of following compiler warnings.

Fixed

  • AnyRandomGenerator never advanced the caller's RNG. Erased generators — including
    the built-in number, uppercaseLetter, lowercaseLetter and character(in:)
    presets — replayed the same value forever under a seeded RNG. Seeded sequences that
    involve erased generators will change with this fix; the first draw is unaffected.
  • Zip(...).map { a, b, c in } failed to compile on Swift 6.3 (pack-expansion tuples are
    no longer destructured into multi-parameter closures). A map overload on Zip that
    receives the values as separate arguments restores the spelling, and CI now also builds
    with the current Xcode toolchain and the latest Swift Linux image.
  • IPAddressGenerator imports Foundation explicitly (required under
    MemberImportVisibility).
  • Shuffled no longer requires Element.Element: Equatable; shuffling never compares
    elements.

Added

  • RandomGenerators.Bernoulli / .bool(probability:) — biased coin.
  • orNil(probability:) — produce nil with a given probability.
  • RandomGenerators.Normal (Box–Muller) and RandomGenerators.Exponential distribution
    generators, with .normal(mean:standardDeviation:) / .exponential(rate:) sugar.
  • RandomGenerators.oneOf(...) — uniform pick across 2–4 generators of different
    concrete types sharing an element type.
  • RandomGenerators.string(of:count:) and characterGen.string(count:) — build strings
    directly from a character generator.
  • Seeded RNGs: Xoshiro256 (xoshiro256++), SplitMix64, and PCG (with independent
    streams via sequence:). LCRNG documents its statistical weakness and points
    simulations at these.
  • RandomGenerators.frequency(_:) static factory (the 2.0 spelling).
  • BoolGenerator typealias (the 2.0 name for BoolRandomGenerator).

Deprecated (removed in 2.0)

  • ZipArrayGenerator, zipAll(), zipGenerators(...) → use [generators].collect().
  • gen.always(_:) → construct Always(_:) directly (the receiver was ignored).
  • gen.colorGenerator(alpha:) → construct ColorGenerator(alpha:) directly.
  • gen.frequency(_:)RandomGenerators.frequency(_:) (the receiver was never part of
    the distribution).
  • gen.character(in:) / gen.unicodeScalar(in:)RandomGenerators.character(in:)
    (the upstream generator was ignored).
  • uiColor(alpha:using:) / swiftUIColor(alpha:using:)uiColor(using:) /
    swiftUIColor(using:) (the alpha parameter was silently ignored; set alpha at
    initialization).
  • CreditCardGenerator.GeneratedElement.

1.2.0

Choose a tag to compare

@ibrahimkteish ibrahimkteish released this 22 Mar 02:06
7a2912c

What's Changed

Full Changelog: 1.1.0...1.2.0

1.1.0

Choose a tag to compare

@ibrahimFever ibrahimFever released this 18 Mar 08:49
cfa75e6

What's Changed

Full Changelog: 1.0.0...1.1.0

1.0.0

Choose a tag to compare

@ibrahimkteish ibrahimkteish released this 17 Mar 20:22
8585771

Full Changelog: 1.0.0...1.0.0