Post Reply 
RPL equivalents to BREAK, CYCLE, EXIT, etc.?
05-22-2014, 09:27 AM
Post: #1
RPL equivalents to BREAK, CYCLE, EXIT, etc.?
Are there User RPL equivalents to break out of loops or start the next iteration such as can sometimes be found in programming languages?

It ain't OVER 'till it's 2 PICK
Find all posts by this user
Quote this message in a reply
05-22-2014, 10:17 AM
Post: #2
RE: RPL equivalents to BREAK, CYCLE, EXIT, etc.?
(05-22-2014 09:27 AM)HP67 Wrote:  Are there User RPL equivalents to break out of loops or start the next iteration such as can sometimes be found in programming languages?
No. But as a workaround you can throw an error and catch it outside the loop.

HTH
Thomas
Find all posts by this user
Quote this message in a reply
05-22-2014, 10:31 AM
Post: #3
RE: RPL equivalents to BREAK, CYCLE, EXIT, etc.?
Thanks for the info.

It ain't OVER 'till it's 2 PICK
Find all posts by this user
Quote this message in a reply
06-06-2014, 01:37 AM
Post: #4
RE: RPL equivalents to BREAK, CYCLE, EXIT, etc.?
There's always the following construct which (using only "structured" commands) implements and arbitrary program.

WHILE (z) REPEAT
CASE
Z=1 THEN code stuff, Z=whatever END
Z=2 THEN code stuff, Z=whatever END
etc.
END (of the cases)
END (of the while)
Find all posts by this user
Quote this message in a reply
06-06-2014, 06:19 AM
Post: #5
RE: RPL equivalents to BREAK, CYCLE, EXIT, etc.?
Thanks. That's generally useful, of course. But Thomas's suggestion to use IFERR works for what I had in mind.

It ain't OVER 'till it's 2 PICK
Find all posts by this user
Quote this message in a reply
06-07-2014, 06:47 AM
Post: #6
RE: RPL equivalents to BREAK, CYCLE, EXIT, etc.?
(05-22-2014 09:27 AM)HP67 Wrote:  Are there User RPL equivalents to break out of loops or start the next iteration such as can sometimes be found in programming languages?
Error traps are a way for loops where you can't access the index easily, but you can exit FOR loops without generating an error condition.
Just set the index to the end value, and you're done;-)

Consider the following loop, which will run 100 times:
Code:
<< 1 100
   FOR x
     x DISP
   NEXT
>>

To break out of such a loop, you simply have to set the exit condition to TRUE.
The following code will exit the loop after 50 times:
Code:
<< 1 100
   FOR x
     x DISP
     IF x 50 ==
     THEN 100 'x' STO
     END
   NEXT
>>

The principle is the same for DO..UNTIL and WHILE..REPEAT loops, of course.

-- Ray
Find all posts by this user
Quote this message in a reply
06-07-2014, 06:40 PM
Post: #7
RE: RPL equivalents to BREAK, CYCLE, EXIT, etc.?
That doesn't work like BREAK/EXIT/CYCLE etc. because if you are in the middle of a bunch of calculations or deeply nested you still have to finish all that stuff before the loop starts again and exits.

I did actually push the loop counter past the index and used that in another piece of code a few weeks ago. I agree it is also a good technique in certain situations, probably one that people might miss since it's not documented. I was wondering if the index value was protected, and I found I could do whatever I wanted with it. Not exactly a safe coding practice, but pretty useful Wink

What I was looking for when I opened the thread was an immediate exit from a loop. IFERR seems to be the best (only?) way to do that.

It ain't OVER 'till it's 2 PICK
Find all posts by this user
Quote this message in a reply
06-07-2014, 11:48 PM
Post: #8
RE: RPL equivalents to BREAK, CYCLE, EXIT, etc.?
(06-07-2014 06:40 PM)HP67 Wrote:  What I was looking for when I opened the thread was an immediate exit from a loop. IFERR seems to be the best (only?) way to do that.

RPL seems to have been conceived by those who were probably trained with traditional "structured programming" in mind. There really isn't room for GOTO or BREAK/EXIT/etc. in structured programming. Error trapping is probably the closest you'll get in RPL to what you're seeking. Sometimes you can achieve what you need with a CASE statement as well, but it depends entirely on the situation as to whether that applies.

It's almost inevitable that you will need to go back and edit some of your code at some point (or perhaps that of someone else). The more of that you do, the more you'll appreciate how much easier it is to follow code that doesn't have lots of GOTOs (especially) and BREAKs/EXITs.

If you start branching into SysRPL, there's a handful of commands that can be used to perform similar functions to BREAK/EXIT. Used creatively, you can do some amazing things with those commands. See all of Chapter 19 (Runstream Control) in "Programming in System RPL" by Eduardo M Kalinowski and Carsten Dominik.

While those commands are useful, they can also make your code very difficult to read and understand later. You have been warned. Smile
Find all posts by this user
Quote this message in a reply
06-08-2014, 09:46 AM
Post: #9
RE: RPL equivalents to BREAK, CYCLE, EXIT, etc.?
I usually find your posts insightful and helpful. However, for this one I will go on record and say I don't agree with what seem to be your conclusions about the implied benefits of structured programming, what constitutes structured programming, how hard it is to maintain code that isn't written in that style, etc.

I don't have any intention to argue with anyone, but since "silence is consent" I felt compelled to clarify my views. I believe I have what to base my conclusions on and I'm sure you do also. So I will just "agree to disagree" with you on this one!

It ain't OVER 'till it's 2 PICK
Find all posts by this user
Quote this message in a reply
06-08-2014, 10:05 AM
Post: #10
RE: RPL equivalents to BREAK, CYCLE, EXIT, etc.?
(06-08-2014 09:46 AM)HP67 Wrote:  I usually find your posts insightful and helpful. However, for this one I will go on record and say I don't agree with what seem to be your conclusions about the implied benefits of structured programming, what constitutes structured programming, how hard it is to maintain code that isn't written in that style, etc.

I don't have any intention to argue with anyone, but since "silence is consent" I felt compelled to clarify my views. I believe I have what to base my conclusions on and I'm sure you do also. So I will just "agree to disagree" with you on this one!

And I have to "agree to agree" with you. Wink

Greetings,
    Massimo

-+×÷ ↔ left is right and right is wrong
Visit this user's website Find all posts by this user
Quote this message in a reply
06-08-2014, 01:44 PM
Post: #11
RE: RPL equivalents to BREAK, CYCLE, EXIT, etc.?
(06-08-2014 09:46 AM)HP67 Wrote:  I don't have any intention to argue with anyone, but since "silence is consent" I felt compelled to clarify my views. I believe I have what to base my conclusions on and I'm sure you do also. So I will just "agree to disagree" with you on this one!

No need to worry, I would never have interpreted silence as consent. In fact, I suspect that the majority here would tend to side with you, as the RPN crowd is much more prominent here. This topic is not new to the programming world, and it frequently seems to cause contention.

In the spectrum of programming languages/models, I think it's fair to say that the need for GOTOs and the like is inversely proportional to the complexity of the language. In other words, the closer to machine language you get, the greater the need. I can't imagine Saturn without its GOTOs, or RPN for that matter. But RPL is still quite functional without them, and higher level languages on other platforms as well.

Personally, I think a lot depends on the style a given programmer tends to use. I'm not a zealot on this topic, but I do contend that structured programming leads to more readable code. And no, I don't expect many here to agree with me. Smile
Find all posts by this user
Quote this message in a reply
06-08-2014, 01:57 PM (This post was last modified: 06-08-2014 07:56 PM by Thomas Radtke.)
Post: #12
RE: RPL equivalents to BREAK, CYCLE, EXIT, etc.?
(06-08-2014 01:44 PM)DavidM Wrote:  In fact, I suspect that the majority here would tend to side with you, as the RPN crowd is much more prominent here.
Hard to imagine that especially RPL fans don't miss BREAK etc. as any workaround consumes more code when more compact code should be desireable on a device with very limited display.

However, it remains to show that the use of BREAK (we're not talking about GOTOs) makes code less readable or maintainable.

Edit: One of probably many typos removed.
Find all posts by this user
Quote this message in a reply
06-08-2014, 04:05 PM
Post: #13
RE: RPL equivalents to BREAK, CYCLE, EXIT, etc.?
(06-08-2014 01:57 PM)Thomas Radtke Wrote:  Hard to imagine that especially RPL fans don't miss BREAK etc. as any workaround consumes more code when more compact code should be disireable on a device with very limited display.

Whether or not you need to "workaround" not having BREAK is a stylistic issue. If you don't design code that depends on its existence to begin with, then you don't see it as a workaround at all.

Regarding the display, I might feel differently if I actually wrote a lot of code directly on my 50g. I don't. All of my RPL/SysRPL/Saturn coding is done on a laptop using an emulator and transferred over, so display limitations aren't usually an issue for me. I realize that lots of people still do all their coding directly on their calculators, though.

(06-08-2014 01:57 PM)Thomas Radtke Wrote:  However, it remains to show that the omission of BREAK (we're not talking about GOTOs) makes code less readable or maintainable.

This is a very subjective issue. Yes, I agree that BREAK is not in the same class as GOTO. In some situations, BREAK isn't very far removed from something like CASE when it comes to reading and maintenance.

Where it can be problematic (IMHO), is when people start using it in the context of exception handling. For example, using a definite loop that really should have been set up as an indefinite loop from the beginning. If you catch yourself adding a BREAK while debugging a loop because of an unforeseen situation arising, that's a good time to ask whether you designed the loop properly from the start. Similarly, adding a BREAK to handle an occasional outlying condition is probably a good sign that error trapping or pre-checking the parameters is a more appropriate model.

Whether using these alternatives makes code more readable/maintainable is a purely subjective issue. In my opinion, it does. I don't expect everyone to agree with me, but this one of those times when I actually do agree with the doctrine of my formal training.
Find all posts by this user
Quote this message in a reply
06-08-2014, 06:05 PM
Post: #14
RE: RPL equivalents to BREAK, CYCLE, EXIT, etc.?
(06-08-2014 04:05 PM)DavidM Wrote:  Whether using these alternatives makes code more readable/maintainable is a purely subjective issue. In my opinion, it does.

This program checks whether a number is prime:
Code:
\<< 2 OVER \v/
  IFERR
    FOR n
      IF DUP n MOD NOT
      THEN DOERR
      END
    NEXT DROP
  THEN 0
  ELSE 1
  END
\>>

How would you make it more readable?

Cheers
Thomas

PS: I'm aware of the shortcomings of the program. I just wanted to provide an example that is simple but still useful.
Find all posts by this user
Quote this message in a reply
06-08-2014, 08:22 PM
Post: #15
RE: RPL equivalents to BREAK, CYCLE, EXIT, etc.?
(06-08-2014 06:05 PM)Thomas Klemm Wrote:  How would you make it more readable?

I actually think this is a good example. In your code, you've used a definite loop for something that isn't actually definite, in that you don't know heading into it how many iterations it may actually need.

If I understood the logic of your code, I believe the following captures the gist of what you did, but in a different way:
Code:

\<<
   2 OVER \v/ 0 \-> n test last hasDivisor
   \<<
      DO
         n test MOD NOT 'hasDivisor' STO
         test 1 + 'test' STO
      UNTIL
         test last >
         hasDivisor
         OR
      END
      hasDivisor NOT
   \>>
\>>

I've intentionally not tried to optimize this for stack use, short variable names, etc. because I believe the goal was readability (and restructuring) as opposed to code size or speed.

While this is more readable to me, it may not be for everyone. The original program you posted was slightly less clear to me for these reasons:

- It used a definite loop structure for something that wasn't really intended to be definite (you don't have an expectation that all iterations are actually needed)
- It used IFERR for something that's not really an exception, but rather the more typical situation where you actually find a factor

As such, I had to spend a little time making sure I understood what the real intent was behind the steps. The code snippet I used above is (IMHO) more in keeping with the basic intent of the logic flow -- "keep trying until either of two conditions is met". It seems to me your logic flow was more like "do this a set number of times, unless you happen upon a factor".

Does this make sense?
Find all posts by this user
Quote this message in a reply
06-09-2014, 09:12 AM (This post was last modified: 06-09-2014 09:56 AM by HP67.)
Post: #16
RE: RPL equivalents to BREAK, CYCLE, EXIT, etc.?
Not to me, despite the technical correctness of your two points.

The first example used one fixed loop and one test. The counter-example used an indeterminate loop, an explicit counter variable, and two tests. That isn't simplicity nor clarity. Rather, I think Thomas motivated BREAK very well with his example. That is how it would be coded in any number of languages that don't impose a particular paradigm on the coder. The first version is simpler, clearer, more efficient, and less error-prone. The second version trades away clarity for a theoretical view of correctness that is not connected to an actual implementation. And the loop in the second example is actually a fixed-count loop in the degenerate case anyway, which weakens the argument that a definite loop structure is not appropriate.

It ain't OVER 'till it's 2 PICK
Find all posts by this user
Quote this message in a reply
06-09-2014, 04:24 PM
Post: #17
RE: RPL equivalents to BREAK, CYCLE, EXIT, etc.?
(06-09-2014 09:12 AM)HP67 Wrote:  ...

There's no question that Thomas' example is tightly coded and efficient. I doubt a UserRPL version could be created that is smaller or faster.

I've already stated that clarity and readability is subjective. From my perspective, Thomas' version is less clear for the reasons I gave. Coming back to both of these a couple years from now, I would have to spend a little more time understanding what his was doing. I don't understand your error-prone assessment, but that's also a more subjective area.

Before I even responded to Thomas, I realized that he intentionally chose an example that was biased toward using something like a BREAK. His example is small enough that having multiple exit points isn't particularly risky. But I still believe it makes a good example of a piece of code that works less by the design of language constructs and more by artifacts of the specific mechanisms employed. Generally speaking, code written in that way is more fragile, less portable, and more likely to encounter problems as updates to software occur later.

I'm not suggesting that the version I submitted is "more correct". It's simply a translation with a different focus (as requested). A more realistic approach to coding should always attempt to strike a balance between the competing goals of space, time, and clarity. The best mix will depend on the specific problem.

"Life is short and ROM is full", and handheld devices historically haven't afforded lots of breathing room for programmers. That has caused a heightened scrutiny of code size and speed, but I believe that we've left clarity behind far more often than we should. Programmers tend to value cleverness in themselves, but they complain quite loudly when others have employed it too often in code they're trying to maintain (and with good reason).

Sometimes, that "other programmer" is yourself, 2 months/years/decades later. Smile I suppose that's my motivator for promoting a healthier balance in coding styles.
Find all posts by this user
Quote this message in a reply
06-09-2014, 04:56 PM
Post: #18
RE: RPL equivalents to BREAK, CYCLE, EXIT, etc.?
At the same time there are people who have have been responsible for developing and maintaining medium-large enterprise software systems for many decades who don't share your views. Knowing your audience and addressing them accordingly rather than lecturing to them seems like common courtesy. In the absence of the former, more circumspection and less "you've been warned" goes a long way. I'm trying to filter the attitude from the content but it's increasingly hard to do.

It ain't OVER 'till it's 2 PICK
Find all posts by this user
Quote this message in a reply
06-09-2014, 05:30 PM
Post: #19
RE: RPL equivalents to BREAK, CYCLE, EXIT, etc.?
(06-09-2014 04:56 PM)HP67 Wrote:  At the same time there are people who have have been responsible for developing and maintaining medium-large enterprise software systems for many decades who don't share your views. Knowing your audience and addressing them accordingly rather than lecturing to them seems like common courtesy. In the absence of the former, more circumspection and less "you've been warned" goes a long way. I'm trying to filter the attitude from the content but it's increasingly hard to do.

I'm truly sorry that my comments have offended you. My "warning" was obviously ill-conceived and I can assure you that no offense was intended. Like you, my experience over the years with both coding and managing coders has shaped my views, and I'm sorry that my explanations have seemed more like lecture than the promotion of a concept which gets decreasing attention (which was actually my intent).

I fear that I'm doing more harm than help to the very idea I was trying to promote, so I'll bow out gracefully now lest I do even more damage.
Find all posts by this user
Quote this message in a reply
06-09-2014, 07:43 PM
Post: #20
RE: RPL equivalents to BREAK, CYCLE, EXIT, etc.?
(06-09-2014 04:24 PM)DavidM Wrote:  Before I even responded to Thomas, I realized that he intentionally chose an example that was biased toward using something like a BREAK.

My intention was to provide an example where eliminating the BREAK isn't trivial. I knew you couldn't use the FOR-loop and then you had to find a way to access the outcome of hasDivisor outside the loop. Throwing an error allows to pass that information without using a local variable.

I guess the most difficult part in my program is to figure out the next step after DROP:
Code:
    NEXT DROP
  THEN 0
  ELSE 1
In a longer program this can be multiple lines away from the condition.

And I agree with you: reasoning about a program is more difficult if there are multiple exit points.
I like your solution: By using meaningful names for the variables the intent is made clear.

Let me add a 3rd more functional variant:
Code:
\<< \-> n
  \<<
    'n MOD ?' ? 2 n \v/ 1 SEQ
    \<< AND \>> STREAM
  \>>
\>>
It doesn't work for small numbers and it doesn't short-cut when the first factor is found. But if the sequence was evaluated lazy the calculator could do that for us.

Kind regards
Thomas
Find all posts by this user
Quote this message in a reply
Post Reply 




User(s) browsing this thread: 1 Guest(s)