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

Eval/Recall Semantics in RPL

7 views
Skip to first unread message

MSCHAEF.COM

unread,
Sep 29, 2005, 9:48:16 AM9/29/05
to
I have a question I've been puzzling over for a couple days, and thought
I'd solicit some outside imput. Specifically, I'm wondering when a RPL
calculator applies a program object to the stack and when it recalls the
object and pushes it on the stack. (Please forgive any mis-rememberings,
I'm away from my 48G, so I can't experiment, and it's been a while since
I've thought about this issue specifically.)

Here are four scenarios that illustrate what I think is a difference:

A. << 432 >> [EVAL] => 432

B. << << 432 >> >> [EVAL] => << 432 >>

C. 432 'a' [STO] [a] => 432

D. << 432 >> 'a' [STO] [a] => 432

When I pressed [a] in scenario D, the program stored in 'a' got evaluated
and 432 ended up on the stack. In contrast, in scenario B, the embedded
program got pushed on the stack, rather than evaluated, and you end up
with << 432 >> on the stack.

My question is this: what does the calculator do differently when you
press a softkey, compared to when it sees an object in a program?

My best guess is that 'evaluating' a program object pushes it on the
stack, and 'evaluating' an unquoted symbol recalls the variable's contents
and 'applies' it to the stack. That would make pressing a softkey
equivalent to evaluating the unquoted symbol.

Thanks,
Mike
--
http://www.mschaef.com

rsch...@comcast.net

unread,
Sep 29, 2005, 10:19:20 AM9/29/05
to


Hi Mike,

Any object is evaluated when called upon...isn't it?

Try:

E. << 432 >> 'a' [STO] 'a' [RCL] => <<432>>

Scott Chapin

MSCHAEF.COM

unread,
Sep 29, 2005, 10:36:04 AM9/29/05
to
In article <1128003560....@g14g2000cwa.googlegroups.com>,
<rsch...@comcast.net> wrote:
...

>> A. << 432 >> [EVAL] => 432
>>
>> B. << << 432 >> >> [EVAL] => << 432 >>
>>
>> C. 432 'a' [STO] [a] => 432
>>
>> D. << 432 >> 'a' [STO] [a] => 432
...

>Any object is evaluated when called upon...isn't it?
>
>Try:
>
>E. << 432 >> 'a' [STO] 'a' [RCL] => <<432>>

Thanks for the input.

So, scenario E would mean that the calc does this: (?)

- Recalls << 432 >> from 'a' into some temporary location
- Evaluate the temporary << 432 >> which pushes it on the stack

In contrast to scenario B, which would do this:

- Encounter << 432 >> in the program
- Evaluate << 432 >> which pushes it on the stack

In that model, my hypothetical on how Scenario D would work
goes like this:

- Recalls << 432 >> from 'a' into some temporary location
- Does some mysterious thing (apply?) that transfers control
to << 432 >>
- The program evaluator encounters << 432 >>, evaluates
432 which gets pushed on the stack.

That would imply the following, I think:

- Evaluating a symbol applies what it points to to the stack
- applying a non-program is the same as evaluating the non-program. That
is, it gets pushed to the stack.
- Programs are applies by evaluating each object in sequence, with some
exceptions that largely exist to create syntax (->, if...then...else...end,
etc.)
- Pressing a soft-key effectively means recall to a temp and apply
- Pressinng right-shift soft-key effectively means recall to a temp
and evaluate

Does this sound reasonable?

FWIW, I'm working on an implementation of an RPL like language in Lisp,
and want to get the details correct.

Thanks again,
Mike
--
http://www.mschaef.com

BobLogan

unread,
Sep 29, 2005, 12:23:02 PM9/29/05
to
>B. << << 432 >> >> [EVAL] => << 432 >>

When you enter in program delimiters inside a program, the editor
automatically inserts certain System RPL commands. When you type in << <<
432 >> >> and press ENTER, the resulting program will look like this in
SysRPL:

::
x<<
xSILENT'
::
x<<
ZINT 432
x>>
;
x>>
;

The double colon and semicolon indicate a secondary, which is a single
object. xSILENT' will push the object right after it to the stack rather
than evaluating it. Since the << 432 >> is a secondary (has :: and ;
around it), it is one object and will be pushed to the stack. If you have
no experience with SysRPL, you may find it interesting that the << and >>
have nothing to do with program flow or the object being a program -- all
they do is indicate to the editor that it should create a secondary. In
fact, when evaluated, the only thing << and >> do is check if the ON key
has been pressed! It is also of interest to note that it is the :: and ;
that tell the calculator it is dealing with a program. In SysRPL you can
edit out the << >> and the object will still be recognized as a program.
So basically, a "program" in User RPL is actually a SysRPL secondary.

>C. 432 'a' [STO] [a] => 432

>D. << 432 >> 'a' [STO] [a] => 432

The reason for this is that the designers of the calc are very clever.
They figured that if you press the softkey of a program, you are trying to
evaluate the program, rather than recall it. Compare that with a list:
when you press the softkey, it is recalled rather than evaluated. My guess
is that when you press a softkey, the type of the object associated with
that softkey is tested. If it is a program, EVAL is applied to it,
otherwise it is recalled. Another possibility is that the SysRPL EVAL is
applied to all objects, since it evaluates programs but does not affect
lists or algebraic objects. (On a side note, the command TEVAL uses the
SysRPL EVAL. Because of this, if you use it on an algebraic object, it
will always return s:.01 and leave the object unsimplified.)

Bob

MSCHAEF.COM

unread,
Sep 29, 2005, 3:12:34 PM9/29/05
to
In article <44aa4ee1b878eacd...@localhost.talkaboutcomputing.com>,
BobLogan <bobl...@NOSPAMdirecway.com> wrote:

First off, thank you for your post. It's exactly the kind of information
I was looking for when I asked my questions.

>>B. << << 432 >> >> [EVAL] => << 432 >>
>
>When you enter in program delimiters inside a program, the editor
>automatically inserts certain System RPL commands. When you type in << <<
>432 >> >> and press ENTER, the resulting program will look like this in
>SysRPL:
>
>::
> x<<
> xSILENT'
> ::
> x<<
> ZINT 432
> x>>
> ;
> x>>
>;
>
>The double colon and semicolon indicate a secondary, which is a single
>object. xSILENT' will push the object right after it to the stack rather
>than evaluating it.

Aha... this is one of the things I was wondering about. Does that mean
that evaluating this next function leaves 432 on the stack? The only
difference is the missing xSILENT'.

::
x<<


::
x<<
ZINT 432
x>>
;
x>>
;

>In
>fact, when evaluated, the only thing << and >> do is check if the ON key
>has been pressed!

Is that how the 'press ON to abort' logic is implemented? It seems like it
needs to check the ON key more frequently to allow interruption of
something like this:

1 10000000 FOR x NEXT

>It is also of interest to note that it is the :: and ;
>that tell the calculator it is dealing with a program. In SysRPL you can
>edit out the << >> and the object will still be recognized as a program.

But... that keeps the editor from inserting \<< and \>>, I take it?

I seem to remember an old trick that used this technique to
slightly compress UserRPL code.

>>C. 432 'a' [STO] [a] => 432
>
>>D. << 432 >> 'a' [STO] [a] => 432
>
>The reason for this is that the designers of the calc are very clever.
>They figured that if you press the softkey of a program, you are trying to
>evaluate the program, rather than recall it. Compare that with a list:
>when you press the softkey, it is recalled rather than evaluated. My guess
>is that when you press a softkey, the type of the object associated with
>that softkey is tested.

With xSILENT', I'm not so sure this explicit typecheck is neceessary.
Couldn't the rule be:

- Unshifted softkeys recall and evaluate.
- When executing a secondary, each object is evaluated unless quoted
with xSILENT'.

>If it is a program, EVAL is applied to it,
>otherwise it is recalled. Another possibility is that the SysRPL EVAL is
>applied to all objects, since it evaluates programs but does not affect
>lists or algebraic objects.

Yeah, this makes a lot of sense. I missed the distinction between
SysRPL EVAL and UserRPL Eval in my suggestion above.

Out of curiosity, how does this look in SysRPL?

<< -> x << x 432 + >> >>

-Mike
--
http://www.mschaef.com

John H Meyers

unread,
Sep 29, 2005, 8:53:48 PM9/29/05
to
On Thu, 29 Sep 2005 08:48:16 -0500, MSCHAEF wrote:

> \<< 432 \>> [EVAL] => 432
> \<< 432 \>> 'a' [STO] [a] => 432
> \<< \<< 432 \>> \>> [EVAL] => \<< 432 \>>

This is as defined in the manual (the original manuals
for the HP48 S/G series, that is, which were complete).

There is a table in each of the HP48 S/G "User's Guide"s
(possibly as well in the 48G "Advanced Users Reference")
which explains the "evaluation" of various kinds of *user*
objects when encountered when running a *UserRPL*program*
as compiled in the Command Line of the calculator,
and in that table it says that
*programs* encountered within other UserRPL programs
are simply put on the stack.

If the design of UserRPL hadn't done this,
you would have to perform some contortions
to create a program and leave it on the stack!

In fact, if it were not this way, then even
if you typed \<< my program \>> into the
Command Line (which simply compiles the entire
Command Line into a program and then runs it),
your program would then execute itself,
rather than just be put on the stack!

As Bob Logan has explained at great length,
the calculator arranges for this magic
by inserting various SysRPL tokens which don't display at all
(or display as something else, belying what they really are)
into the runstream, which simply make UserRPL programs
(and algebraic objects, for that matter)
look and act exactly as the manual says, without requiring you
to figure out how it's accomplished in lower-level SysRPL.

And in this case, for UserRPL program behavior,
the calc does exactly what the manual says,
thank goodness!

Complete scan of HP's 48G Series User's Guide [18_MB PDF]:
http://www.hpcalc.org/details.php?id=3937
http://www.hpcalc.org/hp48/docs/misc/hp48gug.zip

[r->] [OFF]

John H Meyers

unread,
Sep 30, 2005, 2:05:06 AM9/30/05
to
> When you enter in [the Command Line editor]
> program delimiters inside a program, the [compiler]

> automatically inserts certain System RPL commands.

The command line is always compiled into a program [object]
which is then evaluated, as if \<< ... \>> surrounded it anyway,
and then the resulting program were evaluated afterwards.

So even if you type \<< my program \>> the built-in compiler
automatically quotes the first \<< by inserting xSILENT'
but when the resulting complete program is evaluated,
xSILENT' disappears and leaves the following object
\<< my program \>> alone on the stack.

> [if you removed] xSILENT' [from the runstream]

Without a "quoting" command preceding it,
any program object encountered in the runstream
is immediately entered (executed), as you expected all along.

This is very similar to another "quoting" command named x'

When your program says \<< 'X' ... then the first
single-quote displayed there is actually SysRPL x'
in the compiled program object.

Without x' then the name (a/k/a ID object) would also
be immediately evaluated, rather than quoted (put on stack),
all again as described in the Users Guides.

The trailing single-quote, however, is xENDTIC after compilation,
which is there both to be displayed as another single-quote
character whenever your program is decompiled,
and also, like x>>, to perform CK0ATTNABORT,
which tests whether ON/CANCEL (a/k/a ATTN) has been pressed;
and otherwise could likewise be excised from the
compiled object without affecting run-time results.

However, if you re-displayed your programs as text
without these various embedded "cosmetic" tokens, they
would have different meanings (or syntax errors) if you were
to attempt to re-compile the text again, so it's a generally
worthy idea for these "useless" tokens to remain as compiled :)

As you also surmised, programs are never really "interrupted"
(fortunately) until they test for ON/CANCEL, but UserRPL programs
are automatically testing it frequently enough, because
a number of common user commands and programming structures
contain a built-in test via a call to CK0ATTNABORT.

> when you press a [VAR menu] softkey, the type of object


> associated with that softkey is tested.

SysRPL EVAL simply calls what is found at the address
in the first 20 bits of the object; that code knows
exactly what to do with that object to EVAL it,
which is for a data object (including a list or algebraic)
to put it on the stack, and for any other object
to do something appropriate to further evaluate it.

The UserRPL EVAL differs only for a list or algebraic,
which is then treated almost exactly like a program
(it is internally evaluated via COMPEVAL or CASCOMPEVAL),
and for a tagged object (whose tag must be perused
very carefully, in case it is a port number; otherwise
the tag is removed and EVAL starts over again).

> Couldn't the rule be...

It's even simpler; the ingenious design of each layer,
from machine language thru SysRPL thru UserRPL,
makes almost everything work out magically
to do just what one would expect,
although in UserRPL much of what's going on
is kindly hidden from sight,
much as is all the exploding stuff, gears, etc.
in my car's engine, transmission, etc.,
as well as what's happening to my digesting dinner :)

> Out of curiosity, how does this look in SysRPL?

> \<< \-> x \<< x 432 + \>> \>>

Put that on the stack, and then:

On HP49 do \->S2 [or #100020h LIBEVAL], or
on HP48 do DIS [in Jazz library], to get

:: x<< RPN-> LAM x x<< LAM x % 432 x+ x>>ABND x>> ;

While \<< \-> x 'x+432' \>> is

:: x<< xALG-> LAM x SYMBOL LAM x % 432 x+ ; x>> ;

Notice that RPN-> and xALG-> both display as \-> but are
different SysRPL functions, that x>>ABND and x>>
both display as \>> but are likewise different internal functions,
just as x' and xENDTIC (surrounding 'X') are different.

Note also that an algebraic object SYMBOL ... ;
is actually an efficient compiled RPL program,
exactly like any other program, except that
it begins with the SYMBOL token instead of ::
and that the decompiler has the tough job
of turning it back into algebraic style
(surrounded by quotes instead of program delimiters)
whenever having to display it again as text!

This is all to illustrate that UserRPL
"is all done with smoke and mirrors";
it does exactly what the User Guide says,
but by means of lots of sleight of hand and misdirection
within both the built-in compiler and decompiler.

[r->][OFF]

BobLogan

unread,
Sep 30, 2005, 12:53:45 PM9/30/05
to
>Aha... this is one of the things I was wondering about. Does that mean
>that evaluating this next function leaves 432 on the stack? The only
>difference is the missing xSILENT'.

Yes, it will return 432.

>>In
>>fact, when evaluated, the only thing << and >> do is check if the ON
key
>>has been pressed!

>Is that how the 'press ON to abort' logic is implemented? It seems like
it

>needs to check the ON key more frequently to allow interruption of
>something like this:

>1 10000000 FOR x NEXT

*All* User RPL commands check the ON key. That's why you can interrupt a
UserRPL program at any point, and also a part of the reason why User RPL
runs so slow compared to SysRPL. Every command must check for ON
(sometimes repeatedly - the factorial function, for example). Some
commands, like << and >>, do nothing but check for ON when executed.
Surprisingly, both the IF and the END in an IF THEN END construct do
nothing but check for ON.

>>It is also of interest to note that it is the :: and ;
>>that tell the calculator it is dealing with a program. In SysRPL you
can
>>edit out the << >> and the object will still be recognized as a
program.

>But... that keeps the editor from inserting \<< and \>>, I take it?

Well, if you take a program that has no << >>, edit it, and press ENTER,
it will be evaluated as if you had simply typed it into the command line.
As John H Meyers explained, when you insert a << at the beginning of your
program, an xSILENT' is automatically placed before it when you press
ENTER. The xSILENT' causes the program to appear on the stack rather than
being evaluated.

>With xSILENT', I'm not so sure this explicit typecheck is neceessary.
>Couldn't the rule be:

>- Unshifted softkeys recall and evaluate.
>- When executing a secondary, each object is evaluated unless quoted
> with xSILENT'.

I'd say it's more likely that it just uses the SysRPL EVAL on the object
associated with the softkey you press, regardless of its type. This is a
simple and fast solution.

>Out of curiosity, how does this look in SysRPL?

><< -> x << x 432 + >> >>

::
x<<
xRPN->


LAM x
x<<
LAM x

ZINT 432
x+
x>>ABND
x>>
;

No xSILENT' here, so no quoting occurs. xRPN-> creates a temporary
environment, and x>>ABND abandons it. There is a lot more to UserRPL than
can be seen by the casual observer. For instance, if you added an x
between the last two >>'s, your program would look like this:

::
x<<
xRPN->


LAM x
x<<
LAM x

ZINT 432
x+
x>>ABND
ID x
x>>
;

Although the x inside the inner delimiters may look the same as the x at
the end in User RPL, they are actually two different objects. The x inside
the temporary environment is compiled as a local var (LAM), but the other
one is a global var (ID). All of this is completely invisible to the
user.

Bob

MSCHAEF.COM

unread,
Sep 30, 2005, 1:20:44 PM9/30/05
to
In article <32a472564985c77c...@localhost.talkaboutcomputing.com>,
BobLogan <bobl...@NOSPAMdirecway.com> wrote:
...

Heh, I discovered that the other way around, trying to see if RPL programs
were lexically closed over local variables.

<< 3 -> << << x >> >> >>

Evaluating that gives this

<< x >>

Where I take it from what you've said, x is a local reference (LAM x)
rather than a global (ID x), thanks to the compiler.

Evaluating the newly returned << x >> gave an error, of course. (Unless
I evaluated it with a program like this, that creates another local x.)

<< 4 -> x << EVAL >> >>

Anyway, I appreciate all the time spent answering my SysRPL-naive
questions. I think I'm getting a better understanding of how the pieces
fit together. (These really are wonderful little machines, aren't they?)

-Mike

--
http://www.mschaef.com

0 new messages