8.01.2006
8:20 AM
Some important functional ... functions!
List foldl := method(
accu := first
args := list(nil)
if(call message arguments size == 1,
meth := call message argAt(0) name
slice(1) foreach(i, accu = accu performWithArgList(meth, args atPut(0, i)))
,
fn := Protos getSlot("Block") clone setArgumentNames(call message arguments slice(0, 2) map(name)) setMessage(call argAt(2)) setScope(call sender)
slice(1) foreach(i, accu = fn(accu, i))
)
accu
)
List foldr := method(
accu := last
args := list(nil)
if(call message arguments size == 1,
meth := call message argAt(0) name
slice(0, -1) reverseForeach(i, accu = i performWithArgList(meth, args atPut(0, accu)))
,
fn := Protos getSlot("Block") clone setArgumentNames(call message arguments slice(0, 2) map(name)) setMessage(call argAt(2)) setScope(call sender)
slice(0, -1) reverseForeach(i, accu = fn(i, accu))
)
accu
)
list(1, 2, 3) foldl(l, r, l + r) println // ((1 + 2) + 3) = 6
list(1, 2, 3) foldl(+) println
list(2, 3, 5) foldr(l, r, l * r) println // (2 * (3 * 5)) = 30
list(2, 3, 5) foldr(*) println
list(6, 2, 1) foldl(l, r, l - r) println // ((6 - 2) - 1) = 3
list(6, 2, 1) foldl(-) println
list(6, 2, 1) foldr(l, r, l - r) println // (6 - (2 - 1)) = 5
list(6, 2, 1) foldr(-) println
list(list, 1, 2, 3) foldl(l, r, l push(r)) println // list push(1) push(2) push(3) = list(1, 2, 3)
list(list, 1, 2, 3) foldl(push) println
list(42) foldr(+) println // (42) = 42
This is mostly to demonstrate the flexibility of Io's message manipulation, and method construction. The functions have two forms: an explicit and an implicit. The explicit form takes two symbols and a message, constructing a function to do the folding. The implicit form simply takes a symbol which it uses as the name of the function on the appropriate value to be called.
Next time I'll hit you up with some macro goodness using activatable messages.
