Enter RPN

R47: Program Style
Login

R47: Program Style

Motivations

There never has been a single broadly accepted programming style guide for HP RPN programs.

In other languages, the primary reason for this sad state is that software developers are a fractious bunch and will go their own way when allowed, which in turn is why we have things like go fmt over in the Go world to enforce a single common style, for the benefit of all.

That same antisocial force exists here in RPN land, but I believe there are a few other forces adding to it, making the situation worse:

  1. HP never standardized their assorted flavors of RPN and RPL. Each calculator worked differently, and this reflected in the language each one supported. They aren’t binary-compatible even among closely related machines, and if our community ever does make an attempt at a common programming language for all RPN machines, it could never be a true lingua franca short of having a cross-compilation step.

  2. RPN calculators do not have textual source code formats, as occurs in other programming systems. One enters the program via the calculator’s keyboard, and it is immediately translated into a binary form.

    Some post-HP creations extend the historical implementation with features like this, but then we get back to the fractiousness of software developers. I am aware of but a single case where two HP calculator simulators implement the same export format: JRPN 15c implements the Manz simulator format. Every other 15C simulator/emulator uses a different textual representation, if they have one at all, and none of them are upward compatible with HP-32S simulators or newer.

The R47 adds to this mess by having two export formats, neither of which is suited to programmer-to-programmer communication.

One is a quasi-binary file format, being the low-level instruction numbers printed out in ASCII form. Though nominally a “text” file, the *.p47 file format confers none of the virtues we expect from following the Unix Way. You can load it up into a text editor, but your ability to do anything useful with it at that point is likely to be near zero. You can check it into a version control system and get reasonably small diffs, but those diffs will be nonsense to another human. You can’t feed piles of examples into an LLM as a way to train it up as an R47 coding assistant. I could go on, but the point is that these files are for communicating a program from one calculator to another, not from one human to another.

The R47’s other program export method is its XPORTP function, producing an RTF file loosely replicating what you see on the calculator screen in PRGM mode. Word processing file formats also do not participate in the Unix Way, if only because editing one in a programmer’s text editor ranges from Royal PITA to Functionally Impossible. One might choose to press the obsolete WordPad into service as a text editor for these files, then check them into version control, diff them, etc., but this is fighting the model. We want a true text file format.

It is for these reasons that I have invented my own R47 programming style guide: not because I think it makes the world a huge amount better, but for lack of an acceptable standard we can all line up behind.

We will use as our exemplar the program at the top of my article R47: Program Entry.

Yet Another Idiosyncratic RPN Programming Style

Comments

One of the things we may hope for from a future R47 text program file format is the ability to round-trip comments. One should be able to write a program with comments on a PC, save the file over USB to the calculator, load the program up, edit it there, save it out, and resume editing on the PC without any loss of information, neither in RPN instructions nor in human-oriented comments.

This is one of several reasons the R47’s present RTF output format is unsuited for use as a programmer-to-programmer communication medium.

One of the first things you are likely to notice on studying my triangle solver is all the explanatory comments, one on nearly every line. I’ve always been a big fan of documenting code, and I find comments especially helpful with terse languages like the one backing the R47.

Take the comments showing stack register movements: they aid the reader in understanding the program by documenting how the data moves on the stack at each step. As currently written, these comments assume the simpler SSIZE4 mode even though the program was tested with SSIZE8 mode; my choice was to pick one for clarity or document both options, muddying the presentation. Since the only material difference is that the interactions involving T affect the R47’s D register instead, I took this simpler tack.

Line Numbers, or Rather, the Lack Thereof

The automatic line numbering in the R47 is one of its nicer programming features, considered against historical backgrounds like the HP-12C, where editing a program was likely to require renumbering all the GTO calls from the edit point forward in the program. I happen to prefer the label prefixing you get in the HP-32S series, up through the 35s, but that’s something you can get away with only when every label is a single letter.

What we might hope to get in a future R47 is numbers that restart at each global label:

00001 LBL ‘Foo’
00002   x²
00001 LBL ‘Bar’
00002   +
00003   …

This would allow much shorter line number prefixes since it should be rare to see a run of even 100 statements without another global LBL, allowing 2-digit numbers to suffice most of the time.

Another feature I’d like to see is label-relative jumps, as was added in the HP 35c:

GTO ‘Bar’ + 3

This would jump to the third line of the Bar function, which can avoid the creation of extra global labels purely for the purpose of adding these interior jumps.

But let us set these wishful thoughts aside. When it comes to communicating a program’s ideas to another human mind, we don’t need line numbers at all. That is purely for the benefit of the calculator. Even in a world where I get my LBL-relative GTO feature, small offsets are easy to count off visually, not needing explicit line numbering.

Study my triangle solver again. Does your understanding suffer for lack of line numbers?

Didn’t think so.

Indenting

This is a perennial source of conflict in programming style wars, but I think we can take our cues from many other programming languages and come up with something sufficiently close to a single format we can all live with. The scheme I present here is a 2-space indent with each LBL increasing the indent level and each RTN or END reducing it. Easy.

(We also need an exception for GTO-before-LBL as you see in the triangle solver. There may be other exception cases.)

For some reason, the automatic indenting logic within the R47 follows different rules. As far as I have been able to tell, all it does is indent everything after a LBL by one, without the nested indents you see in my example, with an extra indent for GTO calls, for some reason.

Blank Lines

Doubtless because of the limited screen real estate on calculators, even biggish ones like the R47, it is traditional in RPN to write one line after the next, all the way through, without any blank lines.

Yet, when writing the program out as described above, I do believe we can accept adding one blank line above each LBL for readability. This is another reason to suppress line numbers by default in such exports.

Automatic Reformatting

Above I brought up the example of the Go programming language’s automatic formatting. In case it is not clear, it is my wish that a future round-tripping system for the R47 do the same. On import from USB storage, it should strip out blank lines, and it should store comments as hidden line metadata. On export, it should add the blanks back and write the stored comments out.

Because there is automatic formatting on each side of the transfer, there should be no loss in the round trip so long as the programmer follows the style guide.

The importer should be tolerant of variances in this style — e.g. extra indent levels, tabs vs spaces, CR+LF vs lone LF, etc. — but there should be just one legal export format for a given program. While this does lose programmer style info, it is intentional. We are trying with this mechanism to increase alignment among the community, for pro-social purposes.

(You may now wish to return to my R47 article index.)

License

This work is © 2025 by Warren Young and is licensed under CC BY-NC-SA 4.0