[
v0.1
]
f-streams
is a pull-based streams library for Lua:
- A stream produces a new value each time is called.
- A stream terminates when it returns
nil
. - A stream can use
:
combinators to create stream pipelines. - A stream can be iterated over using Lua's generic for loop.
- A stream can represent infinite lazy lists.
A simple example that produces the values 1
, 2
, and 3
:
local S = require "streams"
local s = S.from(1,3)
print(s()) -- 1
print(s()) -- 2
print(s()) -- 3
print(s()) -- nil
An example that prints the first three odd numbers multiplied by 2
:
local S = require "streams"
S.from(1) -- 1, 2, 3, ...
:filter(function (x) return x%2 == 1 end) -- 1, 3, 5, ...
:map(function (x) return x * 2 end) -- 2, 6, 10, ...
:take(3) -- 2, 6, 10
:to_each(function (v)
print(v) -- 2 / 6 / 10
end)
The API is divided into three groups: sources, combinators and sinks.
A source has the prefix fr_
and creates a stream from the given values.
A combinator combines streams and values to create new streams.
A sink has the prefix to_
and consumes a stream, producing results, until it
terminates.
-
Sources
fr_consts(v)
: stream of constantsv
fr_counter(a)
: stream of numbers froma
to infinityfr_function(f)
: stream off()
resultsfr_range(a,b)
: stream of numbers froma
tob
fr_table(t)
: stream of values fromt
from(v)
: calls the appropriatefr_*
forv
-
Combinators
distinct(s)
: removes duplicate values ofs
loop(fs)
: repeats the streams=fs()
indefinitelyfilter(s,f)
: filterss
based onf
map(s,f)
: appliesf
to each value ofs
skip(s,n)
: skips the firstn
values ofs
take(s,n)
: takes the firstn
values ofs
tap(s,f)
: appliesf
to each value ofs
xseq(ss)
: TODO: flattens a stream of streamsss
into a single stream
-
Sinks
to(s)
: consumes and discards all values ofs
:s() ; s() ; ...
to_first(s)
: first value ofs
:s()
to_table(s)
: appends all values ofs
to a table:{ s(), s(), ... }
to_each(s,f)
: applies all values ofs
withf
:f(s()) ; f(s()) ; ...
to_acc(s,acc,f)
: accumulates all values ofs
based onf
:f(...f(f(z,s()),s())...)
to_sum(s)
: sums all values ofs
:s() + s() + ...
to_mul(s)
: multiplies all values ofs
:s() * s() * ...
to_min(s)
: minimum value ofs
:min(...min(s(),s())...)
to_max(s)
: maximum value ofs
:max(...max(s(),s())...)
As a fundamental limitation, f-streams
does not support a merge
combinator to read from multiple streams concurrently.
However, this limitation is addressed by lua-atmos
, which
extends f-streams
with equivalent combinators.
sudo luarocks install f-streams
lua <example.lua>
You may also copy the file streams/init.lua
as streams.lua
into your Lua
path, e.g.:
cp streams/init.lua /usr/local/share/lua/5.4/streams.lua
Counts from 1
to infinity, takes the first 3 values, converts to table, and
print all indexes and values:
-- without `:` notation
cnt = S.fr_counter() -- 1, 2, 3, 4, 5, ...
vs3 = S.take(cnt, 3) -- 1, 2, 3
vec = S.to_table(vs3) -- {1, 2, 3}
for i,v in ipairs(vec) do
print(i,v) -- 1,1 / 2,2 / 3,3
end
From a table with names, prints all starting with J
:
js = S.from { "Joao", "Jose", "Maria" }:filter(function(n) return n:find("^J") end)
for n in js do
print(n) -- Joao / Jose
end
Prints each value from 1
to 10
:
vs = S.fr_range(1, 10)
S.to_each(vs, print)