Functional ProgrammingI love functional programming (lambda calculus, Haskell, LISP) a lot. I also love RPN (RPL, Joy, Cat). They fit pretty well together. However, the 28S does not have compiler that is sufficiently smart enough to use list fusion (it doesn't compile AFAIK) so these can be slow. Use them for quick programs or proof-of-concepts, but not in large programs where speed is an issue.
MAPMAP takes a list and a program and
maps the program over the list.
Example: «{ 1 2 3 } « 1 + » MAP», when evaluated, returns {2 3 4}.
« OVER SIZE → l p s
« l s FOR i
l i GET p EVAL
NEXT s →LIST
»
»
MAPE (
MAP Effectual)
MAPE takes a list and a program and applies the program to each argument, but doesn't care about outputs. Useful with PIXEL or putting things onto the stack.
Example: { (0,1) (0,2) (1,3) } « PIXEL » MAPE », when evaluated, plots the points (0,1), (0,2), and (1,3).
« OVER SIZE ROT ROT → l p
« 1 SWAP FOR i
l i GET p EVAL
NEXT
»
»
RANGERANGE takes a start, end, and a step, and returns a list from start to the closest number less than or equal to end, going by step.
Example: « 4 7 0.2 RANGE », when evaluated, returns { 4 4.2 4.4 4.6 4.8 5 5.2 5.4 5.6 5.8 6 6.2 6.4 6.6 6.8 7 }.
« → a b s
« { } a b FOR i
i +
s STEP
»
»
ZIPP (
ZIP Program)
ZIPP takes two lists and a program and applies a program to each pair, stopping when one list runs out of items. (It's not called
ZIP because that takes two lists returns a list of tuples (2 item lists here), but that doesn't have much use on a slow system like this and I'm lazy and could make it with « « { } + + » ZIPP ».)
Example: « { 1 2 3 } { 4 5 6 } « * » ZIPP », when evaluated, returns { 1 10 18 }.
Example: « { 1 2 3 } { 4 5 6 } « R→C » ZIPP », when evaluated, returns { (1,4) (2,5) (3,6) }.
« → xs ys p
« { } 1 xs SIZE ys SIZE MIN FOR i
xs i GET ys i GET p EVAL +
NEXT
»
»
ZIPPD (
ZIP Program
Duplicate)
Acts like ZIPP, except it takes one item as the first argument and acts as if the first list was infinite and composed only of it.
EXAMPLE: « 6 { « 7 * » « 2 - » « 2 ^ » } « EVAL » ZIPPD », when evaluated, returns { 42 4 36 }. You may ask, "Why not use MAP?" You cannot make a program that injects a local variable into a nested program (eg. « 42 « { « 7 / » } SWAP « → x « « x SWAP EVAL» MAP » » » EVAL », when evaluated would not return { 6 }, but 'x' as → only scopes one level.
« → x ys p
« { } 1 ys SIZE FOR i
x ys i GET p EVAL +
NEXT
»
»
Edit: Clarification and usage