From: John H Meyers on
In this post we will illustrate a \PI (product) function,
written in UserRPL with a little help from library 256.

When implementing any user-defined function of symbolic arguments,
a serious problem is that the arguments of user-defined functions
are not normally quoted, hence they will be evaluated if possible,
even before the user function is invoked.

This is equally true of HP48 and HP49, E.g.

'\GS(a=b,c,d)'
@ built-in function,
@ key arguments remain symbolic when compiled:

SYMBOL
SYMBOL
ID a
;
ID b
ID c
SYMBOL
ID d
;
xSUM
;


'\PI(a,b,c,d)'
@ user-defined,
@ all args are unfortunately pre-evaluated:

SYMBOL
ID a
ID b
ID c
ID d
SYMBOL
ID \PI
;
BINT4
xFCNAPPLY
;


A second problem for some user functions,
such as a complete \PI [product] function
to complement the built-in \GS [summation] function,
is that when args 'b' and 'c' above
are not numeric when evaluated, then it may be
desirable to return an unevaluated symbolic result,
identical if possible to the original expression,
hence that result must be built again
from the original arguments, which again
requires that args 'a' and 'd' remain unevaluated.

It is possible to solve the first problem by ensuring
that the "stepping variable" does not exist, or by
quoting the first and last arguments to the user function,
e.g. 'X' PURGE '\PI(X,2,3,SQ(X))' EVAL
or '\PI(QUOTE(X),2,3,QUOTE(SQ(X)))' EVAL

It is even possible to solve it by evaluating the
expression in another context where user variables
can not be found, such as the hidden directory context.

However, in this post we supply yet another method,
which is to write the formula as if it were a summation,
e.g. '\GS(X=2,3,SQ(X))'
and then apply the program SIGPI to change \GS into \PI;
this takes advantage of the built-in compiler's
understanding of how to quote the original arguments properly.

Any of these methods works, so take your pick;
it would of course be nicer to put it into an installed library
with whatever would make the compiler and decompiler treat \PI
the same as they treat the built-in summation function,
but that detail is left to the interested reader as an exercise :)

I haven't tried it on any "nested" instances,
such as that proposed elsewhere in this thread
(neither have I bothered to try those nested summations
on the 48G or 49G), so there's something else to pursue later.

I even have yet another idea in mind, which is to provide
a product function via the summation function itself,
e.g. via a form such as '\GS(X=2,3,PROD(SQ(X)))'

What PROD would have to do is to interact with the internals
of the \GS implementation -- yep, you guessed it,
it would have to grab the currently saved sum from its
lambda variable, replace it by the current product, and then
return a zero value for \GS to "add" to what it thinks
is the running "sum."

Of course, one more hack would be necessary, to recognize
the very first iteration and start off at 1, rather than at zero.


Here are SIGPI and \PI user functions,
whipped up for this demonstration in UserRPL,
to illustrate that nothing is beyond the realm of possibility.

You must first install the "extable" library,
then perform HOME 256 ATTACH,
then you may transfer or type the following
(on HP49 series calcs):

\<< \->LST 1. \<< CASE DUP { \GS } HEAD SAME NSUB ENDSUB == AND
THEN DROP { \PI } \->ALG 4. R~SB "xFCNAPPLY" GETADR A\-> END
NSUB 1. == NSUB 4. == OR THEN "symcomp" GETADR SYSEVAL END
END \>> DOSUBS \->ALG \>> 'SIGPI' STO

\<< \-> n. t. u. v. \<< t. I\->R TYPE u. I\->R TYPE OR
{ n. t. u. v. ::\GS DTAG 5. \->LIST SIGPI }
{ n. DUP TYPE 9. == { \->LST HEAD } IFT DUP ::n. STO
DUP TYPE 6. \=/ { STOVX } IFT
1. R\->I DUP ROT "CREATE" GETADR SYSEVAL IFERR
t. u. FOR i. i. n. STO v. EVAL * NEXT
THEN 1. ELSE 0. END n. PURGE { ERRN DOERR } IFT } IFTE
\>> \>> '\PI' STO

@ To create some test cases:
'\GS(X=2,3,SQ(X))' SIGPI
'\GS(X=2,3,Y^X)' SIGPI
'\GS(X=W,Z,SQ(X))' SIGPI

123 'X' STO @ an existing 'X' is no obstacle
{ Y Z } PURGE @ let 'Y' and 'Z' be undefined
2 'W' STO @ but 'W' doesn't have to be

@ [r->] [OFF]
 | 
Pages: 1
Prev: HP28S (ROM)
Next: how to solve integrals