Just a few thoughts after having gone through the HP28 manuals... No need to answer...unless you really want to ;-) Probably best to figure out some things myself.
1. The manuals could be worse, but IMHO, could be a lot better too. Does anyone have, say, a one-page cheat sheet of high-level best practices and such?
2. For my first program of note, I'm attempting to translate an HP15 program I wrote a LONG time ago that generates prime numbers (based I think on an SR56 program, which in turn was based, I think, on a BASIC program). It ain't easy converting spaghetti to pure "structured" code...phew!
3. Wonder if IF..THENs can be nested...
4. I find the multiple ways of writing things a tad confusing (RPN, algebraic, etc?).
Here's just one example from my Primes thingy:
pseudocode:
IF FRAC(a/b)==0 THEN ...
Translates, I think, to something like:
RPN:
IF a b / FP 0 == THEN ... END
tho I guess this would be even MORE RPNish:
a b / FP 0 == IF THEN ... END
or:
a b / FP 0 IF == THEN ... END
:-)
Algebraic:
IF 'FP(a/b)==0' EVAL THEN ... END
THAT one took a while to figure out!
Other (better?) ways?
It's fun reading your impressions. Some of them are similar to mine, although I started learning RPL on my HP 50g with 0 programming experience whatsoever, unlike you where you have some RPN programming experience. This also makes me wonder how RPL has changed from the HP 28 to the 50g.
(06-27-2018 01:19 AM)mdunn Wrote: [ -> ]3. Wonder if IF..THENs can be nested...
I had this same thought with my HP 50g. I tried it out and it worked for me.
(06-27-2018 01:19 AM)mdunn Wrote: [ -> ]4. I find the multiple ways of writing things a tad confusing (RPN, algebraic, etc?).
Here's just one example from my Primes thingy:
Same here. It was a feature I had to get use to. Now that it makes sense, I overall like it because it makes it better to read when I am looking through the program.
I had been using RPN for about 11 years (HP-25 and HP-11C) when I bought my HP-28C in 1988. I loved reading the manuals and became an instant RPL convert. I thought they were really well written.
(06-27-2018 01:19 AM)mdunn Wrote: [ -> ]Algebraic:
IF 'FP(a/b)==0' EVAL THEN ... END
THAT one took a while to figure out!
Other (better?) ways?
A few thoughts:
- Take a look at the documentation for the
IFT and
IFTE commands if you really want to stick with a "load the stack first before finalizing the test" approach. There are some slight footprint and speed advantages to using those commands in certain situations, but you sacrifice some readability (IMHO) if you go that route. It's a nice option to have, though.
- This applies to 48-50 RPL systems, but I'm not sure about the 28: the backquote character (
`) can be used to encapsulate a clause that is automatically evaluated instead of manually evaluating it with EVAL. So in this case, you could use
`FP(a/b)==0` instead of
'FP(a/b)==0' EVAL.
- RPL statements that expect a boolean truth value automatically treat 0 as FALSE and any other value (positive or negative) as TRUE. This can be an advantage for size and speed in some situations. NOT can be applied to any number, which will convert 0 to 1 (TRUE), and any non-zero number to 0 (FALSE). So in this case, you could actually use
a b / FP NOT in a non-algebraic clause to perform the truth test. It may or may not be as readable, but it saves space and time. Again, you get to decide which is more important.
Finally, as Carsen says, experiment. Trying out various language features is the best way to learn, IMHO.
EDIT: Oops... I see that while I was writing the following DavidM beat me to it!
Ah, the joys of learning RPL! Welcome to the club!
(06-27-2018 01:19 AM)mdunn Wrote: [ -> ]3. Wonder if IF..THENs can be nested...
Yes. See the
Advanced Users Reference Manual, page 2-25 (that's one page, not a range) for an example of nested conditionals.
RPL allows everything (*) to be nested as many levels deep as you want, limited only by its available memory and your available patience.
A fun example is the →RPN program on page 2-28, which has an IF/THEN nested inside a FOR/NEXT loop which is nested inside an IF/THEN!
* Gentle Reader: If there's anything that RPL doesn't allow to be nested, please correct me.
Fleeting thought: Some nested IF/THEN structures are more efficiently coded (and more human-readable) using the CASE structure instead.
(06-27-2018 01:19 AM)mdunn Wrote: [ -> ]4. I find the multiple ways of writing things a tad confusing (RPN, algebraic, etc?).
Here's just one example from my Primes thingy:
pseudocode:
IF FRAC(a/b)==0 THEN ...
Translates, I think, to something like:
RPN:
IF a b / FP 0 == THEN ... END
tho I guess this would be even MORE RPNish:
a b / FP 0 == IF THEN ... END
or:
a b / FP 0 IF == THEN ... END
:-)
Since THEN treats 0 as false and any nonzero value as true, you can replace
0 == with just
NOT in all of the above (e.g.
IF a b / FP NOT THEN ... END), which makes the code slightly shorter and faster but cryptic to any human reader who doesn't know how THEN works.
(06-27-2018 01:19 AM)mdunn Wrote: [ -> ]Algebraic:
IF 'FP(a/b)==0' EVAL THEN ... END
THAT one took a while to figure out!
As the AUR mentions on pages 1-13 and 3-112, "If the test-clause is an algebraic, it’s automatically evaluated to a number — you don’t need →NUM or EVAL." Therefore
IF 'FP(a/b)==0' THEN ... END and
IF 'NOT FP(a/b)' THEN ... END also work (with the EVAL omitted).
In many ways RPL is a natural extension to RPN. Once the stack size limit is lifted and extra types added, you end up with something akin to RPL.
Pauli
(06-27-2018 01:19 AM)mdunn Wrote: [ -> ]I'm attempting to translate an HP15 program I wrote a LONG time ago that generates prime numbers.
Feel free to post your program here. With combined forces, we can hopefully develop an RPL program.
Quote: a b / FP
You might use
MOD instead.
Good ideas re not explicitly needing "zero" comparisons. Readable enough to anyone used to the 0/NOT 0 = false/true convention :-)
` is not available on the 28. Ditto CASE.
Needing the EVAL must be a 28 thing then...
Wonder if one can leave the THEN clause blank and only have an ELSE clause... Meh...easier to just reverse my test.
OK...I'll work on my Primes program, time permitting :-}
thx
(06-27-2018 03:04 AM)Steve Simpkin Wrote: [ -> ]I had been using RPN for about 11 years (HP-25 and HP-11C) when I bought my HP-28C in 1988. I loved reading the manuals and became an instant RPL convert. I thought they were really well written.
My case is similar. My first HP calculator was the 15C, followed by the 16C and then the 71B with Forth/Assembler and Math ROMs. I was also an admirer of LISP but my only experience with it was "toy" versions on a PC clone. Needless to say I was very impressed with the HP28 and I used mine until it wore out! Nowadays however I'm so used to the HP50 that I find the RPL of the 28 to be frustratingly limiting.
To the OP, I would also suggest looking at the many programs posted on this site and on hpcalc.org. Having working programs as examples can be very helpful in learning a new language.
John
I strongly recommend buying the museum drive that have some good books for RPL, specifically the Bill Wickes HP 28, which goes beyond the respective calculator manual.
Cheers
OK, you've convinced me...I ordered the flash drive!
Argh...I made the mistake of entering the whole program before saving it, and, surprise, there's ≥1 syntax error(s).
Can I save the flawed code for later editing, or do I simply have to fix it "open loop" before moving on??
Enter an odd number ≥5 and it will return the number if prime, or the next prime if not. CONT will return succeeding primes.
I know…it’s a poor program, and should really be two programs, have local variables, etc. It was just an exercise. What were my syntax errors? Writing STO var instead of ‘var’ STO. And not using the correct WHILE syntax.
Argh…is there no way to stop the 28 from mangling my nice formatting?
Code:
;Prime number checker/generator
;Michael Dunn, 2018/6/27
«
‘Primes’ STO
1 ‘TestDiv’ STO
WHILE 1 REPEAT
2 ‘TestDiv’ STO+
IF ‘NOT FP(Primes/TestDiv)’ EVAL
THEN
2 ‘Primes’ STO+
1 ‘TestDiv’ STO
ELSE
IF ‘SQ(TestDiv) > Primes’ EVAL
THEN
1245 .3 BEEP Primes HALT
2 ‘Primes’ STO+
1 ‘TestDiv’ STO
END
END
END
»
Here's an
audibly better version ;-)
Code:
;Prime number checker/generator for HP28 v2
;Michael Dunn, 2018/6/27
«
‘Primes’ STO
1 ‘TestDiv’ STO
WHILE 1 REPEAT
2 ‘TestDiv’ STO+
IF ‘NOT FP(Primes/TestDiv)’ EVAL
THEN
2 ‘Primes’ STO+
1 ‘TestDiv’ STO
ELSE
IF ‘SQ(TestDiv) > Primes’ EVAL
THEN
Primes .1 BEEP
Primes 3 DISP
2 ‘Primes’ STO+
1 ‘TestDiv’ STO
END
END
END
»
(06-27-2018 05:11 PM)mdunn Wrote: [ -> ]should (...) have local variables, etc.
It's been a while since I wrote an RPL program. I tried to keep it similar to your solution:
Code:
\<< 1
WHILE 1
REPEAT
2 +
\<< \-> n t
\<<
IF n t MOD NOT
THEN
n 2 +
1
ELSE
IF t SQ n >
THEN
1245 .3 BEEP
n HALT
n 2 +
1
ELSE
n t
END
END
\>>
\>> EVAL
END
\>>
Here's how your global variables correspond to the local variables:
Still I have the impression we could improve on that.
Quote:(...) should really be two programs
Do you mean like
ISPRIME? and
NEXTPRIME of the HP 50g?
Nice use of the stack :-) and locals...
Yours is faster too. In 20s, your program got to 131, mine only to 89.
HP50g? No idea... Send me one
I was a bit shocked when I first saw your code, till I realized you were substituting for « & ➝ !
(06-28-2018 08:48 PM)mdunn Wrote: [ -> ]Yours is faster too.
Algebraic expressions tend to be slow. Avoid them like the plague.
Quote:HP50g? No idea... Send me one
Never had one. Somehow stopped at the HP-48GX.
But similar functions exist e.g. on the WP-34S:
You can't really know that the initial number is a prime if you only have
NEXTP.
Thus you need
PRIME? at least for the first check:
PRIME?
NEXTP
NEXTP
NEXTP
(...)
Quote:I was a bit shocked when I first saw your code, till I realized you were substituting for « & ➝ !
These
tri-graphs make it easier to transfer a program from the computer to the calculator.
However that might not be useful with the HP-28.
(06-28-2018 09:43 PM)Thomas Klemm Wrote: [ -> ]But similar functions exist e.g. on the WP-34S:
You can't really know that the initial number is a prime if you only have NEXTP.
Thus you need PRIME? at least for the first check:
PRIME?
NEXTP
NEXTP
NEXTP
(...)
Here is a simple PRIME? implementation for the HP-28S:
« DUP 2 / FP
IF NOT NOT
THEN DUP √ 1
DO 2 + 3 DUPN
SWAP OVER
UNTIL < ROT ROT
MOD NOT OR
END SWAP DROP
MOD NOT
END NOT
»
It will work for n > 1 ( 1 is NOT prime).
That's one of my first RPL programs (HP-28S, back in 1987), so it can surely be optimized a bit.
Gerson.
(06-29-2018 01:08 PM)Gerson W. Barbosa Wrote: [ -> ]« DUP 2 / FP
IF NOT NOT
THEN DUP √ 1
DO 2 + 3 DUPN
SWAP OVER
UNTIL < ROT ROT
MOD NOT OR
END SWAP DROP
MOD NOT
END NOT
»
This is a perfect example of what some people dislike about RPL: in order to write efficient programs, you have to avoid expressions and use stack manipulation instead. The resulting programs are hard to write and even harder to read.
Can be great fun for programming challenges, though.
(06-29-2018 02:49 PM)Thomas Okken Wrote: [ -> ]This is a perfect example of what some people dislike about RPL: in order to write efficient programs, you have to avoid expressions and use stack manipulation instead..
? that's what trditional RPN does too??
Besides, that's exactly what I like about RPL compared to e.g. Prime (and Casio/TI/Sharp)
And for RPL calculators, the stack is an "infinite" set of storage registers
(06-29-2018 01:08 PM)Gerson W. Barbosa Wrote: [ -> ]That's one of my first RPL programs (HP-28S, back in 1987), so it can surely be optimized a bit.
Using local variables avoids stack juggling. Otherwise the changes were only minor.
Code:
«
IF DUP 2 MOD
THEN
DUP √ → n r
« 1
DO
2 +
UNTIL
r OVER <
OVER n SWAP MOD NOT
OR
END
n SWAP MOD NOT
»
END
NOT
»
(06-29-2018 02:49 PM)Thomas Okken Wrote: [ -> ]The resulting programs are hard to write and even harder to read.
Is that easy enough to understand?
Cheers
Thomas