map
transducer:.map: f unknown :: unknown :: transducer [ transduce\wrap:, transduce\step: ]
Create a transducer which maps tuples from (x) => (y) via f.
nums := [ 1,2,3,4 ]
# Calling your transducer 'xf', short for 'transformer' is a common convention.
# Create a transducer which transforms the values it sees by squaring them.
xf := Transducers.map(x :: x * x)
squared_nums := nums.collect(xf)
filter
transducer:.filter: f unknown :: boolean :: transducer [ transduce\wrap:, transduce\step: ]
Create a transducer which filters values via the predicate f.
nums := [ 1,2,3,4 ]
# Create a transducer which filters out the odd numbers
xf := Transducers.filter(x :: x.is\even)
even_nums := nums.collect(xf)
mapfilter
transducer:.mapfilter: f unknown :: predicate\boolean: unknown :: transducer [ transduce\wrap:, transduce\step: ]
Create a transducer which both maps and filters values by the block f.
nums := [ 1,2,3,4 ]
# Create a transducer which filters out the odd numbers, and squares the remaining ones.
xf := Transducers.mapfilter(x :: (x.is\even, x * x))
squared_even_nums := nums.collect(xf)
# This could also be accomplished by composing the map and filter transducers:
xf := Transducers.filter(x :: x.is\even)
|> Transducers.map(x :: x * x)
squared_even_nums := nums.collect(xf)
reduce
transducer:.reduce: (initial unknown, f unknown :: predicate\boolean: unknown) :: transducer [ transduce\wrap:, transduce\step: ]
Create a transducer which yields each accumulator value as it applies the reducing block f
nums := [ 1,2,3,4 ]
# Create a transducer which accumulates values into a list.
# Each intermediate value is passed through.
xf := Transducers.reduce([], (list, x) :: list.cons x)
lists := nums.collect(xf)
# [ [1], [1, 2], [1, 2, 3], [1, 2, 3, 4] ]
transduce
transducer:.transduce: (initial unknown, f unknown :: predicate\boolean: unknown, xf [ transduce\wrap:, transduce\step: ]) :: transducer [ transduce\wrap:, transduce\step: ]
Like reduce, except it accepts a transducer and a reducer, and first wraps the reducer with the transducer.
nums := [ 1,2,3,4 ]
# Create a transducer which accumulates values into a list.
# Each intermediate value is passed through.
xf := Transducers.transduce([], (list, x) :: list.cons x, Transducers.map(square))
lists := nums.collect(xf)
# [ [1], [1, 4], [1, 4, 9], [1, 4, 9, 16] ]
deduce
transducer:.deduce: (initial unknown, f unknown :: predicate\boolean: unknown) :: transducer [ transduce\wrap:, transduce\step: ]
A more interesting version of reduce. Explanation TBD.
tap
transducer:.tap: f unknown :: predicate\boolean: unknown :: transducer [ transduce\wrap:, transduce\step: ]
Create a transducer which applies a side-effect to each value.
nums := [ 1,2,3,4 ]
xf := Transducers.tap(num :: num.println)
same_nums := nums.collect([] xf)
# 1
# 2
# 3
# 4
skip
transducer:.skip: f unknown :: () :: transducer [ transduce\wrap:, transduce\step: ]
Create a transducer which skips values based on the predicate f. Consider skip the inverse of filter.
nums := [ 1,2,3,4 ]
xf := Transducers.skip(num :: num.is\even)
odd_nums := nums.collect([] xf)
take
transducer:.take: n int :: transducer [ transduce\wrap:, transduce\step: ]
Create a transducer which accepts up to n values.
nums := [ 1,2,3,4,5 ]
xf := Transducers.take 2
two_nums := nums.collect([] xf)
# [1, 2]
drop
transducer:.drop: n int :: transducer [ transduce\wrap:, transduce\step: ]
Create a transducer which ignores up to n values, then accepts the rest.
nums := [ 1,2,3,4,5 ]
xf := Transducers.drop 2
three_nums := nums.collect([] xf)
# [3, 4, 5]
take_while
transducer:.take_while: f unknown :: boolean :: transducer [ transduce\wrap:, transduce\step: ]
Create a transducer which accepts values while f returns true: - then ignores the rest.
nums := [ 1,2,3,4,5 ]
xf := Transducers.take_while(x :: x <= 2)
two_nums := nums.collect([] xf)
# [1, 2]
take_until
transducer:.take_until: f unknown :: boolean :: transducer [ transduce\wrap:, transduce\step: ]
Create a transducer which accepts values until f returns true: - then ignores the rest.
nums := [ 1,2,3,4,5 ]
xf := Transducers.take_until(x :: x == 3)
two_nums := nums.collect([] xf)
# [1, 2]
drop_while
transducer:.drop_while: f unknown :: boolean :: transducer [ transduce\wrap:, transduce\step: ]
Create a transducer which ignores values while f returns true: - then accepts the rest.
nums := [ 1,2,3,4,5 ]
xf := Transducers.drop_while(x :: x < 3)
three_nums := nums.collect([] xf)
# [3, 4, 5]
count
transducer:.count: () :: transducer [ transduce\wrap:, transduce\step: ]
Create a transducer which appends the number of seen values so far to the tuple.
nums := [ 1,2,3 ]
xf := Transducers.count |> Transducers.map((x idx) :: [x idx])
two_nums := nums.collect([] xf)
# [ [1, 0] [2, 1] [3, 2] ]
interpose
transducer:.interpose: () :: transducer [ transduce\wrap:, transduce\step: ]
Create a transducer which inserts a separator between each value it sees.
nums := [ 1,2,3 ]
xf := Transducers.interpose 'hello!'
three_nums := nums.collect([] xf)
# [ 1 'hello!' 2 'hello!' 3 ]