Add loop combinators to stdlib: times, each-integer, while #394
Labels
No labels
bug
dependencies
documentation
duplicate
enhancement
good first issue
help wanted
invalid
question
refactor
rust
technical-debt
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
navicore/patch-seq#394
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Add basic loop combinators as stdlib words. These are table-stakes for concatenative languages (Factor has
each,times,while,until) and are identified as tier 1 inLANGUAGE_GAPS.md.Motivation
Recursion-only iteration is correct (TCO guarantees it) but not ergonomic. Simple counted loops require defining two words (the entry point and the recursive helper), managing an explicit index/counter on the stack, and getting the termination condition right.
Example — printing 5 shares currently requires:
With
each-integer, this becomes:Proposed Words
These can be pure stdlib (no compiler changes), backed by recursion + TCO:
times— execute quotation N timeseach-integer— call quotation with 0, 1, ..., n-1while— loop while predicate returns trueRisk
None. Pure stdlib additions — no compiler or runtime changes. TCO guarantee means these perform identically to hand-written recursion. No new syntax; the concatenative composition model is preserved.
Note
These combinators inherit the current limitation that their quotation arguments cannot use
>aux/aux>(see #393) and cannot auto-capture values from the enclosing scope (see #394 if filed). They still eliminate boilerplate for simple iterations.Context: discovered while implementing Shamir's Secret Sharing in Seq. Multiple recursive loop helpers (
split-byte-loop,print-points-loop,str-to-bytes-loop, etc.) could each be replaced by a singleeach-integerortimescall.we'll hold off on implementing "while". Requires either a typechecker special case (the dip/keep/bi pattern is established and works) or accepting a fixed-shape while (e.g., Int -> Int only).
but we are implementing the other 2 combinations via
github.com/navicore/patch-seq@34a0acdae7https://github.com/navicore/patch-seq/blob/main/docs/design/LOOP_COMBINATORS_PHASE1.md
https://github.com/navicore/patch-seq/pull/399