Code becomes more reusable because it can be written to not worry about which stream is being used, and instead the caller can use with-input-stream or with-output-stream to specify the source or destination for I/O operations.
For example, here is a program which reads the first line of a file, converts it to an integer, then reads that many characters, and splits them into groups of 16:
USING: continuations kernel io io.files math.parser splitting ;
"data.txt" utf8 <file-reader>
dup stream-readln string>number over stream-read 16 group
This code has two problems: it has some unnecessary stack shuffling, and if either stream-readln or stream-read throws an I/O error, the stream is not closed because dispose is never reached. So we can add a call to with-disposal to ensure the stream is always closed: