stdlib: complete the Seq module - #44
Merged
Merged
Conversation
Seq had 7 members against List's 51, which made the lazy half of the library the one you left for a list plus a conversion. This adds 22, and the single-pass caveat decides how they are grouped. Lazy, answering a new sequence with nothing pulled yet: drop, takeWhile, dropWhile, concat, flatten, collect, zip, indexed, distinct, pairwise, init, initInfinite, unfold. Most route to Python's own lazy machinery (itertools.islice/takewhile/dropwhile/chain/pairwise/count), so a chain of them stays lazy; distinct and unfold are emitted generators, since they carry state while staying lazy. Consuming, where a Python iterator being single-pass means what they pull is gone: head, isEmpty, len, exists, forall, contains, sum, iter, find. Several short-circuit, so they consume only as far as the answer. initInfinite and unfold are the members with no list behind them, which is the reason the lazy module exists at all. Two end-to-end tests pin that down by building endless sequences and taking from them: neither terminates if a member that claims to be lazy quietly forces its input. Naming follows List rather than F#: drop not skip, and concat appends where flatten flattens. Every member's hover line says which half it is in, and what it costs to ask — that Seq.len walks the whole thing and never returns on an endless sequence is exactly what a reader needs before calling it.
This was referenced Jul 31, 2026
Merged
simontreanor
added a commit
that referenced
this pull request
Jul 31, 2026
Two dogfooding reports from real programs, and the standard-library sweep they triggered. Language: * a `type` declaration can name an imported type, bare or module-qualified (#36) — the one gap that changed a program's architecture rather than its phrasing, forcing two modules into one file * field access resolves from the base's type when it is known, so two records may share a field name without prefixes (#37) * parameters destructure: tuples (#38), records (#40), and `_` * a direct self tail call lowers to a loop, so an interactive turn loop no longer walks the stack (#39, #41) Standard library — about 115 new members, taking every module to the F# core set: List (#42), Seq (#44), Set and Map (#46), String (#47), Option and Result (#48), then a member-by-member FSharp.Core audit (#51). Every built-in member now carries a one-line description and its complexity in hover and completion (#43, #49), enforced by tests. Fixes: * `pyfun run` on a single file gives the program its own stdin, so an interactive program is runnable by the command whose job is running programs (#35) * a partially applied lambda closes over its argument instead of being wrapped, so `List.map ((+) 2)` emits `lambda b: 2 + b` (#52) * every multi-argument callback's scheme put the effect variable on the wrong arrows, so `List.fold` could never accept an effectful folder (#51) * `Seq.empty` lowered to a bare `iter()`, a TypeError (#51) One source-incompatible change, which is why this is 0.4.0 and not 0.3.1: a dotted `extern` target whose module prefix cannot be decided from the text is now a compile error naming the `extern import` to add (#50). `sys.stdout.flush` used to emit `import sys.stdout` and fail at runtime; declaring `extern import sys` fixes it.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Dogfooding finding #5, PR 2 of 5 (see #34). Follows #42 (
List) and #43 (member docs).Seqcarried 7 members againstList's 51, which made the lazy half of the library the one you left for a list plus a conversion. This adds 22, and the single-pass caveat turned out to be the organising idea rather than a footnote — every member's hover line now says which half it is in.Lazy — a new sequence, nothing pulled yet:
droptakeWhiledropWhileconcatflattencollectzipindexeddistinctpairwiseinitinitInfiniteunfold. Most route to Python's own lazy machinery (itertools.islice/takewhile/dropwhile/chain/pairwise/count), so a chain of them stays lazy.distinctandunfoldare emitted generators, since they carry state while staying lazy.Consuming — a Python iterator is single-pass, so what these pull is gone:
headisEmptylenexistsforallcontainssumiterfind. Several short-circuit, consuming only as far as the answer.initInfiniteandunfoldhave no list behind them, which is the reason the lazy module exists:Two end-to-end tests build endless sequences deliberately. Neither terminates if a member that claims to be lazy quietly forces its input, so they check the laziness itself rather than asserting on emitted text.
Naming follows
List, not F#:droprather thanskip, andconcatappends whileflattenflattens — the same divergence already taken forList, kept consistent so the two modules read the same way.Documentation carries the cost, which matters more here than for
List: thatSeq.lenwalks the whole sequence and never returns on an endless one is exactly what a reader needs before calling it, and that is now in hover rather than in DESIGN prose.Tests: 7 typecheck cases (lazy members stay in
Seq,SeqandListmembers do not mix,unfoldmust answerOption,itercarries its effect), 3 lowering assertions (routes to the lazy machinery,distinctyields rather than building a list,unfold's loop), and 3 end-to-end programs including the two endless ones. Full suite, clippy and fmt clean.