Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

How SEQ works (or doesn't!), plus S/SX version

17 views
Skip to first unread message

John H Meyers

unread,
Mar 24, 1998, 3:00:00 AM3/24/98
to

In some previous posts, I have attempted to show how some of
the handy G/GX list-processing and related functions work,
and also to provide nearly equivalent S/SX versions:

1998/01/21 DOLIST & DOSUBS for S/SX

1998/01/22 STREAM, REVLIST, etc. for S/SX
[also DeltaLIST, SumLIST, PILIST, HEAD, TAIL]

1998/03/19 How SORT works (plus S/SX version)


Well, now we come to SEQ, which takes five stack arguments:

object 'index' start end increment

The general idea is that the "object" will be either an expression
or a program, e.g. 'SQ(N)' or \<< N SQ \>>; the object in turn
will compute a function of the variable 'index' (e.g. 'N');
finally, SEQ will return a list of all the results which are generated
by the repeated evaluation of the object, letting 'index' take on
a sequence of values beginning with "start" and incrementing by
"increment" until the current value exceeds the "end" value.

Thus, \<< N SQ \>> 'N' 2 4 1 SEQ returns { 4 9 16 }.

Quoting the AUR:

The action of SEQ for arbitrary inputs can be predicted exactly
from this equivalent program:

start end FOR index object EVAL increment STEP n \->LIST

where n is the number of new objects left on the stack by the
FOR...STEP loop. Notice that 'index' becomes a local variable
regardless of its original type.

Well, for old-time Maxwell Smart fans, I now pose this rhetorical
question: Would you believe that the manner in which HP implemented
the SEQ command was simply to make a string out of every one of its
arguments, including the executable object (which *must* therefore
be in User-RPL), then to arrange all these strings so as to form
the larger string "start end FOR index object EVAL increment STEP"
and then to perform STR-> on that final string in order to run the
"equivalent program" of which the AUR speaks?

Well, that's in fact what the G/GX does! Now, suppose that we take our
example program \<< N SQ \>> and store it in a variable named 'NSQ';
the G/GX User's Guide (near page 17-7) quite clearly tells us in
step #1 under the heading "To generate a sequence" that you can put
on the stack either the function or program to be evaluated,
*or*its*name*, followed by the remaining arguments, as above.

Suppose, then, that we put on the stack 'NSQ' 'N' 2 4 1, where
'NSQ' contains \<< N SQ \>> [or 'SQ(N)'], and then perform SEQ again.

Do we get the correct results this time? NO!! Depending upon the
current setting of flag -3, and upon whether a variable named 'N'
currently exists, we get either an error message or an invalid
list of symbolic or numeric expressions, but *not* { 4 9 16 }.

Why not? Because the variable name 'N' within the object already stored
in 'NSQ' is a *global* variable name; the SEQ function does not even try
to recall the stored object before turning the "object" argument into
a string, so it actually performs its final STR-> upon the string
"2 4 FOR N 'NSQ' EVAL NEXT", leaving the object 'NSQ' to evaluate
the *global* variable 'N' (if it exists), rather than the *local*
variable created by the FOR...NEXT loop!

We might attempt to salvage some truth from the User's Guide by trying
'NSQ(N)=SQ(N)' DEFINE to define the function, but this would not work
either; although the function NSQ(N) would then be defined in terms
of a local variable N, the function would each time try to obtain
its argument from the *stack*, storing that into a *new* local variable,
rather than using any existing local variable named N.

So, the only way in which SEQ can actually work on the G/GX is:

o The "object" argument must generally be an actual *User*RPL*
program object (or algebraic expression), which in turn must be
an *explicit* function of the named 'index' variable.

You can *not* in general use the *name* of any stored object,
nor can you use any program object containing SysRPL/ML coding.

o It may take a rather significant amount of time to decompile and
re-compile the object if it is a large User-RPL program
or a complex algebraic expression.

o SEQ also ends with the "standard" piece of SysRPL coding which compares
stack sizes before and after execution, and then returns a result list
*only* if the stack grew larger; this same bit of coding is also common
to DOLIST and DOSUBS, and is what fails to return an empty list
whenever nothing is appended to the stack during the repeated
object evaluations performed by these commands.

I.e. it ends with DEPTH 1GETLAM 2DUP #>ITE :: #- {}N ; 2DROP ABND
rather than simply DEPTH 1GETLAM 2DUP#< IT 2DROP00 #- {}N ABND,
as folks like me might have preferred, which would never have
failed to return exactly one result in all cases, like every other
command which returns neither a count nor a true/false indication
to tell you about a possible variable number of results.

At any rate, that's how it's implemented in the G/GX, which allows us
to provide this S/SX equivalent program, which you may store as 'SEQ'
in your HOME directory, if you wish:

%%HP: T(3); @ SEQ for HP48S/SX
\<< DEPTH 5 - \-> ?p ?v ?s ?e ?i ?d
\<< " " ?s \->STR OVER + ?e \->STR + " FOR " + ?v + SWAP +
?p \->STR + " EVAL " + ?i \->STR + " STEP" +
STR\-> DEPTH ?d - \->LIST \>>
DUP SIZE NOT { DROP } IFT \>>

Please be sure to provide the blank spaces in the various string
constants, exactly as shown above; an extra space would not be harmful,
but a missing space might possibly be so.

The several ->STR commands are also important, in case any of the
arguments happen to be quoted variable names (which are allowed).

The odd-looking local variable names were chosen so as to be unlikely
to conflict with any variable names in the stack arguments.

Together with the previously-posted functions, I believe that we now have
a complete set of list-processing functions for the S/SX, so that almost
all G/GX User-RPL programs which use list-processing functions can now be
compiled and run by S/SX owners -- however few of those are left :)

Why weren't these programs posted by someone else, about four years ago?
Would two or three fewer G/GX's have been sold if they had been?


"I've got a little list... and they'd none of them be missed"
- W. S. Gilbert

-----------------------------------------------------------
With best wishes from: John H Meyers <jhme...@mum.edu>

John H Meyers

unread,
Mar 24, 1998, 3:00:00 AM3/24/98
to

[corrected version]

Quoting the AUR:

%%HP: T(3); @ SEQ for HP48S/SX [corrected version]
\<< DEPTH 5 - RCLF \-> ?d ?f
\<< STD 64 STWS ROT \->STR " " + ROT \->STR + " FOR " +
ROT + " " + ROT \->STR + " EVAL " + SWAP \->STR + " STEP" +
?f STOF STR\-> DEPTH ?d - \->LIST \>>

0 new messages