Collection fns: JVM-faithful return types + laziness (#219)
A type-aware audit (~190 collection expressions vs reference Clojure) found four divergences the corpus missed — value-equality (= [0 1] '(0 1)) hides type and laziness differences. Fixed, with type-predicate + over-infinite corpus rows that pin them. - partition-all [n coll] built vector chunks; JVM chunks are seqs. (The [n step coll] arity was already correct, as is the partition-all transducer, whose chunks are vectors in JVM too.) Now builds seq chunks. - replace always returned a vector (mapv) and was eager; JVM is type-preserving — a vector maps to a vector, any other seqable to a lazy seq. - sequence eagerly realized its source (into-xform), so (first (sequence (map inc) (range))) hung. Rewrote as a transformer iterator: pull one input at a time, buffer the step outputs, emit lazily, run the completion to flush a stateful xform. eduction builds on it (lazy, no longer an eager vector). - mapcat and (apply concat coll-of-colls) hung over an infinite source because jolt-apply seq->lists the trailing arg and mapcat seq->lists the map result. Added lazy-concat-seq (lazily flatten a seq of colls); mapcat uses it directly, and apply special-cases concat (its result is lazy) to route through it. Docs: a cross-cutting return-type + laziness contract in docs/spec/09-core-library; SPEC.md notes that = masks type/laziness so they need predicate / over-infinite rows. EBNF is reader syntax only — unaffected. Seed change (partition-all/replace/eduction are clojure.core overlay) -> re-mint; selfhost holds. make test + shakesmoke + buildsmoke green, 0 new divergences. Co-authored-by: Yogthos <yogthos@gmail.com>
This commit is contained in:
parent
8180c85393
commit
f3084f8043
11 changed files with 810 additions and 679 deletions
|
|
@ -10,6 +10,40 @@ them (e.g. vector `nth` is "effectively constant time" — SHOULD-level).
|
|||
|
||||
---
|
||||
|
||||
## Collection return types & laziness (cross-cutting)
|
||||
|
||||
Two contracts hold across the sequence library and are not restated per entry.
|
||||
|
||||
**Return-type fidelity.** A function returns the same *kind* of collection the
|
||||
reference does — value equality is not enough, since `(= [0 1] '(0 1))`.
|
||||
|
||||
- Sequence transformations return **seqs** (lazy unless noted): `map`, `filter`,
|
||||
`remove`, `keep`, `mapcat`, `take`/`drop` and their `-while` forms, `partition`,
|
||||
`partition-all`, `partition-by`, `interpose`, `dedupe`, `distinct`, `concat`,
|
||||
`reductions`, `cons`, `rest`, `sequence`. The *elements* of `partition` /
|
||||
`partition-all` / `partition-by` are themselves seqs, not vectors.
|
||||
- The vector variants return **vectors**: `mapv`, `filterv`, `vec`, `subvec`,
|
||||
`partitionv`, `partitionv-all`, `splitv-at`. `split-at` / `split-with` return a
|
||||
2-vector `[take drop]`. A transducer applied eagerly (`into []`, the
|
||||
`partition-all` transducer's chunks) yields vectors.
|
||||
- Type-preserving functions return the input's type: `replace` over a vector is a
|
||||
vector, over any other seqable a (lazy) seq; `empty`/`into (empty coll)` keep the
|
||||
collection kind; `set`/`into #{}` return sets; `into {}`/`select-keys`/`zipmap`/
|
||||
`frequencies`/`group-by`/`merge` return maps (`group-by` values are vectors).
|
||||
|
||||
**Laziness.** The lazy sequence functions — including `sequence`, `eduction`, and
|
||||
`mapcat` — MUST consume their source incrementally and so terminate on an infinite
|
||||
or unbounded source when only a prefix is demanded: `(first (sequence (map inc)
|
||||
(range)))` and `(take n (mapcat f (range)))` return without realizing the whole
|
||||
source. `(apply concat coll-of-colls)` is likewise lazy in its argument seq. The
|
||||
eager consumers (`reduce`, `into`, `count`, `vec`, `doall`) realize the demanded
|
||||
portion fully.
|
||||
|
||||
These are exercised by the `seq / lazy over infinite` and the per-fn type-predicate
|
||||
rows in the conformance corpus.
|
||||
|
||||
---
|
||||
|
||||
### first — since 1.0
|
||||
|
||||
```
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue