(02-18-2015 09:45 PM)Marcus von Cube Wrote: I do understand the (almost) unlimited stack of the 28C and its descendants with at least some of the stack levels visible. And I do understand the fixed level stack of what is called classic RPN here. The former has a unique feature: a variable (and countable) number of values on the stack, including the empty stack.

This would apply to the proposed dynamic stack as well, with the exception of that we could not generally guarantee a specific stack depth, as it depends on the register utilization. However, if a user would not attempt to store data in higher-numbered registers (which is fully under the control of the user), the resulting maximum possible depth of the stack is deterministic.

Quote:A fixed stack simply doesn't care how many values the user has ever pushed. Whether the fixed stack contains garbage or useful data is completely open to interpretation.

Correct. And in the case of the dynamic stack, the dynamic stack may be filled with garbage or useful data just as well, it only depends on how the user uses the stack. The idea of the stack silently dropping the oldest value when it can no longer grow ensures that a user can continue to type ahead without having to flush the stack in between (as it may become necessary sooner or later with the stack in RPL). Nevertheless, it may be convenient even to Classical RPN users to store interim results on the stack and just use it as kind of a short-term log-book, as RPL users frequently do. For as long as he does not store data in the higher registers (which is fully under his own control), the stack won't be truncated, so he can fully depend on it, when he wants to, but can completely forget about it, when he doesn't.

Of course, it would be possible to put aside a dedicated area for the growing stack, but given its dynamic nature and the limited resources on this calculator, I think the "dynamically shared" usage model has a potentially higher utility value to users. We are just putting resources to use which are not currently used, it may or may not benefit a particular user, but it certainly doesn't restrict him in any way. At least, that's the idea.

Quote:A possible mixture of these modes as is the topic of this thread will lose either of the clear concepts.

Actually, I see it as a possible refinement of both concepts. Of course, in an ideal world, the user should be able to choose from all three modes, but implementing a true "unlimited" stack would require a significantly different approach, whereas the dynamic stack would be just an optional enhancement "on top" of the existing semi-static memory allocation model, therefore, I think, it could be implemented within the limited space constraints we have on this calculator.

Quote:You cannot determine the number of values on the stack if its less then the fixed size of the "base" stack.

It would be easy to let DEPTH return a value lower than the base stack's size, counting down (to 0) the number of drops after the dynamic stack has been emptied. This could even be used to indicate a "stack underrun". Similar, a "stack overrun" could be signalled when values drop out at the other end of the stack. Both indicators might be useful for users accostumed to a variable sized stack, and could be just ignored by users of fixed-size stacks. Such soft indicators may even help new users learning RPN in general.

You could. [c]RCL R/S s, [c]STO R/S s and [c]x<> R/S s would allow for stack-relative addressing, so that RCL R/S 1 returns the value of X, RCL R/S 2 the value of Y, RCL R/S 5 or 9 the last value stored on the dynamic stack, etc.

Of course, more sophisticated stack manipulation functions could be added as well (as found on RPL calculators), but this is where I too think we should keep it simple at least for as long as this has to run on this calculator hardware.

Quote:You will (quickly, due to the limited resources of the platform) lose data off the top of the stack without notice, or, depending on implementation, will be confronted with an error message which is annoying if you just don't care about the "garbage" you pushed earlier.

That's right, but it is part of the "concept" to implement a larger stack within the existing space constraints. We could even bind this to another flag, ideally combined with other message display.

(For the applications I envision some 16 - 25 stack levels would already be enough, whereas 4 or 8 levels are not. But others may have different needs.)

Quote:And all this happens "in the blind" because of the famous display.

We're certainly limited by the hardware here, but with Bit's new Y register display code enabled at least two stack levels can be displayed. It is not as convenient as on larger calculators, but at least we'd be able to store more than just 8 levels without the hassle of having to refer to registers. In some applications this could make a difference already.

You wrote that stack-relative addressing would use the [R/S] key. But that's already assigned to the letter Y. [RCL] [R/S] currently means RCL Y. If you wanted to use [R/S] for this purpose, then Y could be entered only as [RCL] [ENTER] [R/S], similarly to X, Z and T. It may not be easy to get used to entering RCL Y differently depending on whether or not dynamic stack is enabled. Alternatively, you could use [XEQ] instead of [R/S] for this purpose.

How would this new addressing mode be encoded in programs? It'd mean very many new instructions if you'd like to make it available with every command. Maybe it would be sufficient to only allow stack-relative addressing with some commands: e.g. RCL, STO, x<->, RCL/STO combined with basic operations, and their complex variants, but even then, it's very many new code points.

As someone who has little experience with an 'infinite' stack, I also wonder if there's any real need for such an addressing mode. I can imagine that one might like to work with the 9th or 10th number in the stack, but it seems unlikely that anyone would be able to keep track of a long stack with such precision that they'd want to take the 38th number. (The stack potentially changes all the time, it isn't as easy as keeping track of what's in the 38th register.) Perhaps making the contents of the dynamic stack available in the register browser would be good enough?

You're making extensive use of the [CPX] key in your proposals. Why is that? Is it simply that more key combinations are needed and [CPX] is available, or is there some logical reason behind it?

There's no unallocated persistent RAM available, so what should be sacrificed to store the stack depth?

Marcus hinted that restoring the stack after an error could be a challenge. Have you had a look at the code (xeq() in trunk/xeq.c) already? That part may need to be completely rewritten if the stack is allowed to become very large.

I understand that these ideas are a work in progress but once the dust has settled down a bit, could you provide a single list of all proposed stack rotate and similar operations, each with a short explanation of what they do, how they'd be entered from the keyboard, and why they're useful? I have to admit I've lost track of them, and it isn't clear to me how each fits into the big picture and why they make sense as a coherent set.

(02-19-2015 02:50 AM)Bit Wrote: You wrote that stack-relative addressing would use the [R/S] key. But that's already assigned to the letter Y. [...] Alternatively, you could use [XEQ] instead of [R/S] for this purpose.

Thanks for pointing this out, Bit! I overlooked that letter Y is assigned to R/S in the current keyboard layout.

However, some calculators support power operations on registers like RCL-arrow-^ and STO-arrow-^. It might be a good idea to reserve the key currently assigned to XEQ for this purpose (as it is in the same row as all those power functions and also above the ^ key, so it seems mnemo-technically the best choice).

(I am using arrow-v and arrow-^ here in order to distinguish them from ^ and v, which are already in use for maximum and minimum.)

I guess, the ideal candidate for stack-relative addressing would be the R-arrow-v key (like in RCL R-arrow-v n). However, in the current layout, this key is also assigned to "I". If we couldn't live with that, we might use the RCL key instead (as in RCL RCL n), but name the function RCL-arrow-v. (In my work-in-progress proposal for an improved keyboard layout, R-arrow-v has been moved to where the RCL key is now, so the conflict no longer exists.)

Quote:Maybe it would be sufficient to only allow stack-relative addressing with some commands: e.g. RCL, STO, x<->, RCL/STO combined with basic operations, and their complex variants, but even then, it's very many new code points.

I'm open on this. [c]RCL, [c]STO and [c]x<> were the commands I had in mind to allow some basic stack addressing. If the scheme can be generalized without code overhead, even better. I haven't looked at how commands are encoded and how it would best fit in there, yet.

Quote:You're making extensive use of the [CPX] key in your proposals. Why is that? Is it simply that more key combinations are needed and [CPX] is available, or is there some logical reason behind it?

cRCL, cSTO and cx<> were meant as double-register operations, as used for complex numbers (but not restricted to them). Otherwise, I just used CPX because it was available (in the tradition that the CPX key is also used for a limited number of other "more complex" functions already). (However, in my work-in-progress proposal for an improved future keyboard layout, there is even some more logic behind this, but this should better be subject to another thread -- later.)

Alternatively, we might think about implementing some kind of "smart" switch between the current functions of the up/down keys and a stack roll function.

Quote:There's no unallocated persistent RAM available, so what should be sacrificed to store the stack depth?

Good point.

One possible solution, although not ideal, would be to store this and other necessary values in the first re-purposed register, so that the initial allocation for the dynamic stack would have to allocate two registers instead of one. We would
still need a single bit flag to indicate the existance of the dynamic stack then.

I will have to think about a better solution.

In either case, any such implementation details should be transparent for the stack-relative addressing, of course.

Quote:Marcus hinted that restoring the stack after an error could be a challenge. Have you had a look at the code (xeq() in trunk/xeq.c) already? That part may need to be completely rewritten if the stack is allowed to become very large.

I definitely will, but haven't found any time for it so far. Right now I am trying to utilize my limited time to write down a number of ideas before hopefully finding the time to help implement them somewhen in the future.

Quote:I understand that these ideas are a work in progress

Yes, and I very much value any constructive input on this idea.

Quote:but once the dust has settled down a bit, could you provide a single list of all proposed stack rotate and similar operations, each with a short explanation of what they do, how they'd be entered from the keyboard, and why they're useful?

(02-19-2015 10:10 AM)matthiaspaul Wrote: However, some calculators support power operations on registers like RCL-arrow-^ and STO-arrow-^. It might be a good idea to reserve the key currently assigned to XEQ for this purpose (as it is in the same row as all those power functions and also above the ^ key, so it seems mnemo-technically the best choice).

RCL and the arrows are already used for the RCL combined with minimum/maximum operations, and you need the arrow keys to enter them. How would your proposal work in relation to that?

(02-19-2015 10:10 AM)matthiaspaul Wrote:

Quote:Maybe it would be sufficient to only allow stack-relative addressing with some commands: e.g. RCL, STO, x<->, RCL/STO combined with basic operations, and their complex variants, but even then, it's very many new code points.

I'm open on this.

What I'm curious about is whether all of these new commands would fit into the bytecode at all, or what tricks would need to be employed to make them fit.

(02-19-2015 10:10 AM)matthiaspaul Wrote: Alternatively, we might think about implementing some kind of "smart" switch between the current functions of the up/down keys and a stack roll function.

You'll have to be careful with the arrows as pointed out above.

(02-19-2015 10:10 AM)matthiaspaul Wrote: One possible solution, although not ideal, would be to store this and other necessary values in the first re-purposed register, so that the initial allocation for the dynamic stack would have to allocate two registers instead of one. We would
still need a single bit flag to indicate the existance of the dynamic stack then.

That'd work but it'd be somewhat wasteful, especially in double precision mode. You'd only need 7 bits so I'd be surprised if there was a better way than stealing some user flags.

(02-19-2015 10:10 AM)matthiaspaul Wrote:

Quote:but once the dust has settled down a bit, could you provide a single list of all proposed stack rotate and similar operations, each with a short explanation of what they do, how they'd be entered from the keyboard, and why they're useful?

I certainly can do that if necessary.

I can only speak for myself but in my opinion it is absolutely necessary if you'd like useful feedback.

(02-19-2015 01:05 AM)BarryMead Wrote: Stack operations are deceptively SIMPLE LOOKING. They APPEAR to be easy, but are always much more complex under the surface. Paul Dale mentioned that stack operations were "Pervasive" and that you would need to look at code affected by at least three stack related variables to correctly alter program behavior. I am just saying that, from my experience, more things will break than you can possibly imagine.

Implementing 'Entry RPN' (without the dynamic stack) may not to be as difficult as one might think, although very thorough testing would be needed as usual. I've just had a quick look at the code and there aren't very many places that deal with stack lifts, and XROM code could easily be exempted. Provided, of course, that the precise specification, once we have one, doesn't introduce some unexpected complexity. ENTER is simple but what should CLx do? Clear the command line if present and then DROP? Something else? What about Σ±?

I'd expect trouble with library and user programs. If they change the RPN mode and get paused or interrupted, it'd be a major source of confusion for the user if the ENTER key suddenly works differently, especially as it may not be noticed right away. If the mode change only affects the program (e.g. it's stored as a local flag), then what should happen if you single step a program? I can't think of a good solution other than rewriting all library routines so they work correctly in both RPN modes and warn users that their programs will break unless they pay attention to this.

Ultimately I think creating a well thought-out specification that provides a consistently good user experience and covers every detail might be more work than the programming.

(02-19-2015 01:51 PM)Bit Wrote: Ultimately I think creating a well thought-out specification that provides a consistently good user experience and covers every detail might be more work than the programming.

Yes, as for any piece of software

I'm not familiar with Entry RPN on a limited display machine, I just have experience of the RPL calculators so there is one thing that is not clear for me with Entry RPN applied to the WP 34s: is the command line displayed on the screen different from the stack X register?

For example, if I have 4 in the Y register and 3 in the X register as a result of a previous calculation and I press [2], what happen on the display if I have set YDON? Is 2 just replacing 3 which stay hidden in the X register until I press ENTER or an operator key while 4 is still displayed on the top line?

(02-19-2015 01:05 AM)BarryMead Wrote: Paul Dale, or Marcus von Cube also have this kind of deep grasp of the code because they wrote most of it.

I've just noticed this sentence... Barry, you're very kind, but let's be realistic and honest here: Pauli and Marcus know vastly more about the code than I do. They had created it and have been working with it much longer, whereas I only really analyzed the parts I wanted to change or fix. This is not false modesty, only the truth. :-)

(02-19-2015 05:24 PM)Thomas Klemm Wrote: Meanwhile the WP-34s will just return to the initial state and display 4 and 3. In this case the whole stack is unaltered which means that register t isn't lost. This is in contrast to the HP-42s.

Hmmh, that must have crept in inadvertently. The HP-42S is meant to be our gold standard, so I suggest we change this behaviour.

d:-/

(The response of Thomas K. to Didier's post isn't filed correctly but I gave up trying to teach Thomas - no use.)

I have been reviewing the code affected by this proposal (for some time) and it is my opinion (humble even) that this proposed change is ill-advised. If you were to do a complete 'rewrite' to clean things up a bit and 'design' the alternate OP_ENTER behavior into the system from the get-go then maybe the benefits obtained 'might' warrant the work required.

As things are, the work required here off-set against the assumed benefits of 'entry' RPN (not to mention the assumed regression testing nightmare which must follow) certainly does not warrant the effort, nor the risk, involved in making the change.

This is clearly one of those situations (religious for me) of, "If it ain't broke ladies, don't fix it!".

(02-19-2015 07:25 PM)MarkHaysHarris777 Wrote: This is clearly one of those situations (religious for me) of, "If it ain't broke ladies, don't fix it!".

Indeed. There's a chance to do it right in the 43s .

This is another example where an implementation of RPN doesn't work as expected. Should be clear by now that this error prone implementation of a copious entry method with no benefits over a modern RPN implementation should be avoided.

(02-19-2015 08:24 PM)Paul Dale Wrote: I think the 42S is doing the wrong thing here. It is a backspace, which should erase the entry and go back to the previous state.

I completely agree. The 42S in this particular case is problematic in two ways: You have to roll the stack to get rid of the zero if you accidentally pressed a key, and worse, you lose register T. But there's no upside, this behavior serves no useful purpose.

(02-16-2015 08:51 PM)Paul Dale Wrote: From scratch, it would be much easier to implement and get right.

From the current base, the worst part would be exterminating all of the odd-ball cases throughout the code that support stack lifting. It is a rather ad-hoc mixture and quite pervasive.

- Pauli

I know what Paul is saying. It is the "odd-ball cases throughout the code" that make this a complex issue. Special individual case by case behaviors have been "Fine Tuned" to perform in the most logical way to make the user interface SEEM logical and easy to use. There are lots of special cases and adding a whole new stack lift and entry system would require the same "Fine Tuning" on a case by case basis for many "odd-ball" cases. As I said the behavior is NOT AS SIMPLE AS IT APPEARS TO BE. The Enter key is not the whole picture, the stack lifts (or not) according to a very complex set of case by case rules. The "Backspace" example just discussed is only one of the many individual case-by-case "Finely Tuned" behaviors that could be BROKEN by a new stack lift/entry system. I would like to suggest that this feature be postponed until the 43S project.

(02-20-2015 02:23 AM)BarryMead Wrote: The Enter key is not the whole picture, the stack lifts (or not) according to a very complex set of case by case rules.

The [ENTER] key is not *any* of the picture. It is all about 'stack lift' and the mish-mash of embedded 'policy' for the complex set of case-by-case rules!

Implementing this proposal (from the current code-base) would be a serial night-mare of grand proportions-- similar to a Greek tragedy.

Well, before you begin, lock the code down and make one last golden real-build so that you have a place to begin from again three months from now when regression testing is all over the floor (what a night-mare).

(02-20-2015 02:23 AM)BarryMead Wrote: I know what Paul is saying. It is the "odd-ball cases throughout the code" that make this a complex issue.

It probably isn't all that bad if you decide to replace the current stack behaviour with something else entirely. Trying to support both the old and something new together will be quite difficult, I certainly wouldn't attempt to modify the code base to handle both.

Much of the current behaviour was defined by decisions made by HP in severely memory limited times. E.g Σ+ puts the number of samples in X and disables stack lift and leaves Y unchanged. This was a reasonable idea when this function was first introduced in the 1970's but it really doesn't make a lot of sense now -- just show the number of samples in the display, pop both X and Y and save both with an undo or restore function of some kind.