--- title: RPNCalc v4 slug: rpncalc4 description: Reverse Polish Notation calculator, version 4 - increasingly esoteric and incomprehensible. Contributed by Aidan. ---
use stdlib?

### documentation

use `(name; value)` to define something. the definition can be recursive. `value` is executed and `name` is set to the final state of the stack, i.e. `(name; 1 3)` is possible

use `'` to push instead of apply to the stack, e.g. `'(a -> a)`. This is useful for lazyness, i.e. `'(->lazy evaluated thing)`

- `+, -, *, /, ^, sqrt, cbrt, exp, log, (a)cos/sin/tan, abs, floor`: mathematical operations
- `==`: equality (automatically derived for all types); returns `a b -> a` if true, `a b -> b` if false
- `typeof`: returns the type of the object
- `pair, fst, snd`: pairs two objects, gets first or second item of pair
- `tuple`: used like `... 3 tuple`; creates an n tuple of n items on the stack
- `!!`: index into a tuple
- `len`: length of a tuple

### stdlib

- `stop; "stop`
- `inv; x -> 1 x /`
- `fold; x acc fn -> acc '(-> x acc fn 'fn fold) 'x \"stop ==`
- `range; x y -> x '(->x x 1 + y range) 'x y ==`
- `listthen; fn -> (internal; x acc -> '(->acc fn) '(->x acc pair internal) x stop ==) 0 tuple internal`
- `list; (a -> a) listthen`
- `lmap; list fn -> list '(->list fst fn list snd 'fn lmap pair) list 0 tuple ==`
- `unlist; l -> (internal; list -> '(->) '(->list fst list snd internal) list 0 tuple ==) stop l internal`
- `map; fn -> '(l->l 'fn lmap unlist) listthen`