Why can't I sort or group a stream from Stdin, UDP or a TCP connection?
← Streams and Pipelines · Ref: Q1301
Buffering operations (sort, group, tail, uniq) must see or accumulate over ALL of the input before producing output, so they require a BOUNDED (finite) source. Stdin, UDP and TCPConnection are UNBOUNDED — infinite IO streams with no defined end — so buffering one would consume memory without bound and never emit. EK9 rejects this at compile time (E10050).
ERROR
stdin <- Stdin() cat stdin | sort > stdout // ERROR: E10050
FIX WITH head N (head bounds the stream)
cat stdin | head 1000 | sort > stdout // OK
FIX WITH bounded windows
while active batch <- cat udpConnection | head 100 | collect as List of Packet cat batch | sort > processor
STREAMING OPERATIONS ARE FINE ON UNBOUNDED SOURCES
cat stdin | filter by validLine | map with toEntry > stdout // OK cat udpConnection | map by handler > stdout // OK
head N is the mechanism that converts an unbounded stream to a bounded one.
Example
defines module qa.streams.unboundedbuffer defines function nonEmpty() as pure -> line as String <- rtn as Boolean: length line > 0 defines program UnboundedStreamDemo() stdin <- Stdin() stdout <- Stdout() //Streaming operations (filter/map) compose freely with an unbounded Stdin source. cat stdin | filter by nonEmpty > stdout //To sort/group/tail/uniq, 'head N' must bound the unbounded stream first. first10Sorted <- List() of String cat stdin | head 10 | sort > first10Sorted stdout.println(`Captured: ${length first10Sorted}`)
Common mistakes
E10050 — Buffering operators like sort need a bounded source; stdin is unbounded, so add 'head N' before sort. See ek9 -h E10050 for details.
Incorrect:
cat stdin | sort > first10Sorted
Correct:
cat stdin | head 10 | sort > first10Sorted
Other ways to ask this
- What triggers E10050 BUFFERING_REQUIRES_BOUNDED?
- Why does sort fail on an unbounded stream source in EK9?
- How do I sort/group/tail/uniq a stream from a socket or Stdin?
Coming from another language?
Java: Stream.sorted() on an infinite stream hangs at runtime, no compile check. Python: sorted(infinite_generator) hangs. Rust: collecting an infinite iterator to sort hangs. EK9: the compiler proves at compile time that buffering an unbounded source is impossible and requires 'head N' to bound it first.
Keywords: Stdin, backpressure, tail, E10050, sort, UDP, uniq, stream, TCP, unbounded, group, head, bounded