rpn-cli 1.6.0

Command line reverse Polish notation calculator.
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
# Reverse Polish Notation Calculator

## Versions

| Version | Released    | Change |
| ------- | ----------- | ------ |
| 1.0.0   | 06-Mar-2024 | Initial version. |
| 1.1.0   | 20-May-2024 | Import values and operations from file with `import` directive or `--import` option. |
|         |             | Export results to file with `export` directive. |
|         |             | Define custom functions with `define` directive. |
|         |             | Sum values in batch mode with `--sum` option. |
|         |             | Correct floating point errors by rounding to nearest repeating decimal. |
| 1.2.0   | 05-Jun-2024 | Parse and format hexadecimal as `0x89ab`. |
|         |             | Export hexadecimal in batch mode with `--hex` option. |
|         |             | Export no separators in batch mode or with `export` directive. |
| 1.3.0   | 15-Mar-2025 | Format and parse time (already in UTC) with "Z". |
|         |             | Format hexadecimal with comma not underscore separators. |
|         |             | Export separators in batch mode with `--sep` option. |
|         |             | Export precision in batch mode with `--dp` option. |
| 1.4.0   | 25-May-2025 | Set named variable to most recent entry with `set` directive, for later use. |
|         |             | Remove defined functions with `define` directive, and keyword but no body. |
|         |             | Show defined functions with `define` directive, and no keyword or body. |
|         |             | Show defined functions with derived parameter hints. |
|         |             | Improve inline help and stack history output. |
| 1.5.0   | 12-Jun-2025 | Group values on the stack for sequence operations. |
|         |             | Create and modify sequences with `seq`, `step`, `sort`, `rev` and `flat` operations. |
|         |             | Apply unary operation to all values with `apply` directive. |
|         |             | Copy and duplicate values without variable name. |
|         |             | Undo import file in a single step after `import` directive or `--import` option. |
|         |             | Undo cast after `plain`, `delta` and `time` operations. |
|         |             | Show entire stack with `show` command, or 10 most recent values after an operation. |
|         |             | Show defined variables with `set` directive and no variable name. |
| 1.6.0   | -           | Apply measurement units to values, with context specific scaling. |
|         |             | Apply formatting to interactive session, with `--hex`, `--sep` and `--dp` options. |
|         |             | Prevent number formatting infinite loops. |
|         |             | Show detailed unit and apply errors. |

## Contents

* [Versions]#versions
* [Contents]#contents
* [Introduction]#introduction
* [Program Options]#program-options
* [Program Features]#program-features
  * [Arithmetic Operations]#arithmetic-operations
    * [Floating Point Error Handling]#floating-point-error-handling
  * [Sequence Operations]#sequence-operations
    * [Stack Operations for Sequences]#stack-operations-for-sequences
  * [Bitwise Operations]#bitwise-operations
  * [Time Operations]#time-operations
  * [Unit Operations]#unit-operations
  * [Formatting Commands]#formatting-commands
  * [Stack Commands]#stack-commands
  * [History Commands]#history-commands
  * [General Directives]#general-directives
  * [Comments]#comments

## Introduction

RPN is a command line reverse Polish notation calculator.  As such, it pushes integer and fractional numbers onto a stack, and pops them off for operations, running in interactive mode:

```
$ rpn
rpn> 6 7
rpn> show
  6
  7
rpn> mul
  42
```

It accepts input from files supplied on the command line, running in batch mode:

```
$ cat input.txt
6 7
mul
$ rpn input.txt
42
```

It accepts input from a POSIX shell command pipeline, running in batch mode:

```
$ seq 1 5 | rpn --sum
15
```

It writes output to a POSIX shell command pipeline, running in batch mode:

```
$ rpn >output.txt
6 7
mul
$ cat output.txt
42
```

Feature requests are welcome, but it's a hobby project in a language I don't get to use in my day job, so I prefer to do all the development myself.

## Program Options

The `-c` or `--command` option accepts input directly from the command line:

```
$ rpn --command 6 7 mul
42
```

The `--import` option imports values and operations from a text file.  This can be used for commonly used custom functions:

```
$ cat defines.txt
define cube 3 pow
define percent 100 div
$ rpn --import defines.txt
rpn> 2 cube
  8
```

The `--sum` option causes all results to be summed, if running in batch mode:

```
$ cat numbers.txt
1 2 3 4 5
$ rpn --sum numbers.txt
15
$ rpn --sum --command 1 2 3 4 5
15
$ seq 1 5 | rpn --sum
15
```

The `--hex` option causes results to be printed in hexadecimal, if running in batch mode:

```
$ rpn --hex --command 10 10 mul
0x00000064
```

The `--sep` option causes results to be printed with separators, if running in batch mode:

```
$ rpn --sep --command 10 10 pow
10,000,000,000
```

## Program Features

Some operations are binary like `add` and `mul`, some are unary like `neg` and `inv`, some are nullary like `now`, while others operate on the entire stack like `sum` and `prod`.  Inline help provides hints on expected inputs and outputs:

```
rpn> help
  Arithmetic operations:
    N N  add,+   N    Add two values
    N N  sub,-   N    Subtract two values
    N N  mul,*   N    Multiply two values
    N N  div,/   N    Divide two values
    N N  mod,%   N    Modulo two values
      N  neg     N    Find the negative
      N  inv     N    Find the inverse
    N N  pow     N    Raise to the power
      N  sqrt    N    Find the square root
      *  sum     N    Sum all values
      *  prod    N    Multiply all values
  Sequence operations:
    N N  seq     *    Generate integer sequence (start to stop)
      3  step    *    Generate integer sequence (start with step to stop)
      *  sort    *    Sort stack or sequence
      *  rev     *    Reverse stack or sequence
      *  flat    *    Flatten entire stack
  Bitwise operations:
    N N  and     N    Bitwise AND two values
    N N  or      N    Bitwise OR two values
    N N  xor     N    Bitwise XOR two values
    N N  shl     N    Shift left (multiply by power of 2)
    N N  shr     N    Shift right (divide by power of 2)
  Time operations:
         now     N    Get the current time (in UTC)
      N  plain   N    Format as a plain value
      N  delta   N    Format as a delta value (duration)
      N  time    N    Format as a time value (in UTC)
  Formatting commands:
         dec          Format as decimal values
         hex          Format as hexadecimal values
         sep          Include comma separators
         nosep        Include no separators
      N  dp           Use fixed decimal places
         nodp         Use free decimal places
  Stack commands:
         show         Show all values on the stack
      *  clear        Remove all values from the stack
      N  pop          Remove a value from the stack
      N  dup     N N  Duplicate a value on the stack
    N N  swap    N N  Swap two values on the stack
      N  cut          Cut a value to the internal clipboard
      N  copy    N    Copy a value to the internal clipboard
         paste   N    Paste a value from the internal clipboard
  History commands:
         u(ndo)       Undo the last operation
         r(edo)       Redo the next operation
         hist         Show all undo/redo history
  General directives:
         import...    Import file e.g. "import file.txt"
         export...    Export file e.g. "export file.txt"
         set,=...     Set variable, e.g. "set x"
         define...    Define function e.g. "define cube 3 pow"
         apply...     Apply to stack or sequence, e.g. "apply 3 pow"
  General commands:
         units        Show unit names and symbols
         help         Show this help text
```

### Arithmetic Operations

The `add` operation adds two values:

```
rpn> 5.5 2.5 show
  5.5
  2.5
rpn> add
  8
```

The `sub` operation subtracts two values:

```
rpn> 5.5 2.5 show
  5.5
  2.5
rpn> sub
  3
```

The `mul` operation multiplies two values:

```
rpn> 5.5 2.5 show
  5.5
  2.5
rpn> mul
  13.75
```

The `div` operation divides two values:

```
rpn> 5.5 2.5 show
  5.5
  2.5
rpn> div
  2.2
```

The `mod` operation divides two values and finds the remainder:

```
rpn> 5.5 2.5 show
  5.5
  2.5
rpn> mod
  0.5
```

The `neg` operation finds the negative:

```
rpn> 8 show
  8
rpn> neg
  -8
```

The `inv` operation finds the inverse:

```
rpn> 8 show
  8
rpn> inv
  0.125
```

The `pow` operation raises to the power:

```
rpn> 3 4 show
  3
  4
rpn> pow
  81
```

The `sqrt` operation finds the square root:

```
rpn> 100 show
  100
rpn> sqrt
  10
```

The `sum` operation sums all values on the stack:

```
rpn> 1 2 3 4 5 show
  1
  2
  3
  4
  5
rpn> sum
  15
```

The `prod` operation multiplies all values on the stack:

```
rpn> 1 2 3 4 5 show
  1
  2
  3
  4
  5
rpn> prod
  120
```

#### Floating Point Error Handling

RPN uses big fractions for all operations, except when calculating square roots or other fractional powers, when it converts the arguments to floating point.  In order to avoid floating point errors, it rounds all results to the nearest repeating decimal.  Without this feature, the final result would be something like 2.000000000000000273:

```
rpn> 2 sqrt
  1.4142135623730951454746218587388284504413604736328125
rpn> dup mul
  2
```

### Sequence Operations

The `seq` operation creates increasing or decreasing sequences of values, popping the start and end values from the stack and generating a step of 1.0 or -1.0:

```
rpn> 1 5 seq
┌ 1 ┐
│ 2 │
│ 3 │
│ 4 │
└ 5 ┘
```

```
rpn> 5 1 seq
┌ 5 ┐
│ 4 │
│ 3 │
│ 2 │
└ 1 ┘
```

The `step` operation does the same thing, but pops the start, step and end values; new values are created with the same meaning (plain, delta or time) as the start value:

```
rpn> 0 0.2 1 step
┌ 0   ┐
│ 0.2 │
│ 0.4 │
│ 0.6 │
│ 0.8 │
└ 1   ┘
```

```
rpn> 0 delta 3600 18000 step
┌       00.000 ┐
│ 01:00:00.000 │
│ 02:00:00.000 │
│ 03:00:00.000 │
│ 04:00:00.000 │
└ 05:00:00.000 ┘
```

The `sort` operation sorts values on the stack, treating "not a number" values as lower than everything else:

```
rpn> 4 2 1 0 div 3 5 1
    4
    2
  NaN
    3
    5
    1
rpn> sort
  NaN
    1
    2
    3
    4
    5
```

The `rev` operation reverses values on the stack:

```
rpn> 1 2 3 4 5 show
  1
  2
  3
  4
  5
rpn> rev
  5
  4
  3
  2
  1
```

The `flat` operation flattens all sequences on the stack:

```
rpn> 1 5 seq 6 8 seq
┌ 1 ┐
│ 2 │
│ 3 │
│ 4 │
└ 5 ┘
┌ 6 ┐
│ 7 │
└ 8 ┘
rpn> flat
  1
  2
  3
  4
  5
  6
  7
  8
```

#### Stack Operations for Sequences

If the values at the head of the stack are part of a sequence, operations which would otherwise apply to the entire stack (such as `prod` and `sort`) instead apply to that sequence only:

```
rpn> 11 10 5 4 3 2 1 show
  11
  10
   5
   4
   3
   2
   1
rpn> sort
   1
   2
   3
   4
   5
  10
  11
rpn> prod
  13200
```

```
rpn> 11 10 5 1 seq show
  11
  10
┌  5 ┐
│  4 │
│  3 │
│  2 │
└  1 ┘
rpn> sort
  11
  10
┌  1 ┐
│  2 │
│  3 │
│  4 │
└  5 ┘
rpn> prod
   11
   10
  120
```

### Bitwise Operations

The `and` operation performs a bitwise AND on all bits:

```
rpn> 0xffff 0xff00ff hex
  0x0000ffff
  0x00ff00ff
rpn> and
  0x000000ff
```

The `or` operation performs a bitwise OR on all bits:

```
rpn> 0xffff 0xff00ff hex
  0x0000ffff
  0x00ff00ff
rpn> or
  0x00ffffff
```

The `xor` operation performs a bitwise XOR on all bits:

```
rpn> 0xffff 0xff00ff hex
  0x0000ffff
  0x00ff00ff
rpn> xor
  0x00ffff00
```

The `shl` operation shifts left, i.e. multiplies by a power of 2:

```
rpn> 0xff00 hex
  0x0000ff00
rpn> 8 shl
  0x00ff0000
```

The `shr` operation shifts right, i.e. divides by a power of 2:

```
rpn> 0xff00 hex
  0x0000ff00
rpn> 8 shr
  0x000000ff
```

### Time Operations

The `now` command gets the current time, showing times in UTC:

```
rpn> now
  2025-03-31T12:34:56.789Z
```

The `plain` command converts to an integer or fractional value:

```
rpn> now
  2025-03-31T12:34:56.789Z
rpn> plain
  1743424496.789
```

The `delta` command converts to a delta value, optionally showing days, hours, minutes, seconds and milliseconds:

```
rpn> 86399 show
  86399
rpn> delta
  23:59:59.000
```

The `time` command converts to a time value, showing times in UTC:

```
rpn> 1709294400 show
  1709294400
rpn> time
  2024-03-01T12:00:00.000Z
```

Delta values can be added to or subtracted from times:

```
rpn> 1709294400 time 86400 delta
  2024-03-01T12:00:00.000Z
           1T00:00:00.000
rpn> sub
  2024-02-29T12:00:00.000Z
```

One time value can be subtracted from another:

```
rpn> 1709294400 time 1709208000 time
  2024-03-01T12:00:00.000Z
  2024-02-29T12:00:00.000Z
rpn> sub
  1T00:00:00.000
```

### Unit Operations

Measurement units can be applied to values, in various categories:

* Time (second, minute, hour, day, week, month, year).  Note, month and year are defined as 30 and 365.25 days for this purpose.
* Length (metre, inch, foot, yard, mile).
* Area (square unit, hectare, acre).
* Volume (cubic unit, litre, teaspoon, tablespoon, fluid ounce, cup, pint, quart, gallon, barrel) (UK and US versions).
* Speed (distance over time, speed of sound in air at sea level, speed of light in vacuum).
* Mass (gram, ounce, pound, stone, ton).
* Temperature (Kelvin, Celsius, Fahrenheit, Rankine).
* Data (byte, bit).

[SI and related units](https://en.wikipedia.org/wiki/International_System_of_Units) can be specified by name or symbol (e.g. `second` or `s`, `metre` or `m`) with optional [SI prefixes](https://en.wikipedia.org/wiki/Metric_prefix) (e.g. `millisecond` or `ms`, `kilometre` or `km`).  The same applies to byte units, but only multiplying prefixes are allowed (e.g. `kilobyte` or `kB`).  International units can be specified by name only (e.g. `mile`, `acre`).

Plain values can be cast to specific units, and unit values are converted to equivalent units:

```
rpn> 37 celsius
  37 C
rpn> fahrenheit
  98.6 F
```

```
rpn> 1 light
  1 light
rpn> m/s sep
  299,792,458 m/s
```

All equivalent units can be added or subtracted, and RHS values are converted to LHS units.  All equivalent units can be divided, and results are stripped of their units, leaving plain values:

```
rpn> 1 foot 6 inch
  1 foot
  6 inch
rpn> add
  1.5 foot
```

```
rpn> 1 mile 1 foot
  1 mile
  1 foot
rpn> div
  5280
```

Some non-equivalent units can also be multiplied or divided, for area, volume and speed values:

```
rpn> 70 mile/hour 30 minute
  70 mile/hour
  30 minute
rpn> mul
  35 mile
```

```
rpn> 144 inch^2 1 foot
  144 inch^2
    1 foot
rpn> div
  12 inch
```

Available units and prefixes can be shown with the `units` command:

```
rpn> units
  Prefix units:
    Q    quetta       10^30
    R    ronna        10^27
    Y    yotta        10^24
    Z    zetta        10^21
    E    exa          10^18
    P    peta         10^15
    T    tera         10^12
    G    giga         10^9
    M    mega         10^6
    k    kilo         10^3
    h    hecto        10^2
    da   deca         10
    -    -            1
    d    deci         10^-1
    c    centi        10^-2
    m    milli        10^-3
    u    micro        10^-6
    n    nano         10^-9
    p    pico         10^-12
    f    femto        10^-15
    a    atto         10^-18
    z    zepto        10^-21
    y    yocto        10^-24
    r    ronto        10^-27
    q    quecto       10^-30
  Time units:
    s    second
         minute
         hour
         day
         week
         month
         year
  Length units:
    m    metre
         inch
         foot
         yard
         mile
  Area units:
    m^2  square-metre (and other square-length units)
         hectare
         acre
  Volume units:
    m^3  cubic-metre (and other cubic-length units)
    l    litre
         tsp
         tbsp
         floz
         pint
         quart
         gallon
         barrel
         ustsp
         ustbsp
         usfloz
         uscup
         uspint
         usquart
         usgallon
         usbarrel
  Speed units:
    m/s  metre/second (and other length/time units)
         mach
         light
  Mass units:
    g    gram
         ounce
         pound
         stone
         ton
  Temperature units:
    K    kelvin
    C    celsius
    F    fahrenheit
    R    rankine
  Data units:
    B    byte
         bit
```

### Formatting Commands

The `dec` and `hex` commands format values as decimal and hexadecimal:

```
rpn> 2 32 pow hex
  0x0000000100000000
rpn> dec
  4294967296
```

The `sep` and `nosep` commands show and hide separators for decimal and hexadecimal:

```
rpn> 2 32 pow hex sep
  0x,00000001,00000000
rpn> dec
  4,294,967,296
```

The `dp` and `nodp` commands set and cancel fixed precision for decimal:

```
rpn> 2 sqrt
  1.4142135623730951454746218587388284504413604736328125
rpn> 0 dp
  1
rpn> 3 dp
  1.414
rpn> 6 dp
  1.414214
rpn> nodp
  1.4142135623730951454746218587388284504413604736328125
```

### Stack Commands

The `clear` command removes all values from the stack:

```
rpn> 1 23 456 show
    1
   23
  456
rpn> clear
```

The `pop` command removes a value from the stack:

```
rpn> 1 23 456 show
    1
   23
  456
rpn> pop
   1
  23
```

The `dup` command duplicates a value on the stack:

```
rpn> 1 23 456 show
    1
   23
  456
rpn> dup
    1
   23
  456
  456
```

The `swap` command swaps two values on the stack:

```
rpn> 1 23 456 show
    1
   23
  456
rpn> swap
    1
  456
   23
```

The `cut` and `copy` commands store a value from the stack in the internal clipboard.  The `paste` command copies that value back to the stack:

```
rpn> 1 23 show
   1
  23
rpn> copy
rpn> 456 show
    1
   23
  456
rpn> paste
    1
   23
  456
   23
```

### History Commands

The `undo` and `redo` commands undo the last operation, and redo the next operation in the history:

```
rpn> 1 23 456 show
    1
   23
  456
rpn> prod
  10488
rpn> undo
    1
   23
  456
rpn> undo
rpn> undo
  Start of undo history
rpn> redo
    1
   23
  456
rpn> redo
  10488
rpn> redo
  End of undo history
```

The `hist` command shows all undo history:

```
rpn> 1 23 456 show
    1
   23
  456
rpn> prod
  10488
rpn> undo
    1
   23
  456
rpn> hist
  1 23 456 <==
  prod
```

### General Directives

The `import` directive imports values and operations from a text file; the `export` directive exports values to a text file.  The following creates a file containing the result of the multiplication:

```
rpn> import params.txt
  6
  7
rpn> mul
  42
rpn> export result.txt
```

The `set` or `=` directive sets a named variable to the most recent entry on the stack:

```
rpn> 36 sqrt = x
  6 = x
rpn> 49 sqrt = y
  6 = x
  7 = y
rpn> x y mul
   6 = x
   7 = y
  42
rpn> set xy
   6 = x
   7 = y
  42 = xy
```

Multiple variables can be set on the same line, and variables can be listed with the `set` or `=` directive by itself:

```
rpn> 1 = one 2 = two 3 = three 4 = four 5 = five 6 7 8
  1 = one
  2 = two
  3 = three
  4 = four
  5 = five
  6
  7
  8
rpn> set
  5 = five
  4 = four
  1 = one
  3 = three
  2 = two
```

The `define` directive defines a custom function for subsequent use:

```
rpn> define cube 3 pow
rpn> 2 cube
  8
```

The `define` directive with a function name but no body undefines the function.  The directive with no function name lists defined functions, with hints on expected inputs and outputs, and this information is also included in the inline help:

```
rpn> define cube 3 pow
rpn> define percent 100 div
rpn> define fubar 0 div
rpn> define fubar
rpn> define
  Defined functions:
      N  cube    N    Function "3 pow"
      N  percent N    Function "100 div"
```

The `apply` directive applies the same operation (or sequence of operations) to each value on the stack:

```
rpn> 1 2 3 4 5 show
  1
  2
  3
  4
  5
rpn> apply 3 pow
    1
    8
   27
   64
  125
```

Only operations which pop one input and push one output are allowed:

```
rpn> 1 2 3 4 5 show
  1
  2
  3
  4
  5
rpn> apply add
  Unsupported apply: N N to N
```

When operations are applied to multiple values, a temporary stack is created for each value, so each result is calculated independently.  The temporary stack may contain multiple intermediate values or sequences, as long as they reduce down to a single value at the end.  This allows us to (for example) find the factorial of each value on the stack:

```
rpn> define fact 1 seq prod
rpn> 1 5 seq flat
  1
  2
  3
  4
  5
rpn> apply fact
    1
    2
    6
   24
  120
```

### Comments

It is possible to add a comment to any entered value, or the result of a calculation.  Comments remain attached to their values until replaced, and are copied to duplicated values:

```
rpn> 6 7
rpn> mul # the answer
  42 # the answer
rpn> dup
  42 # the answer
  42 # the answer
```