RE: HP-48 programming problem
Lines: 52

>
>I had a problem debugging a program today, and I was wondering if anyone
>had encountered the same problem before.  The problem isn't a bug, but
>it is annoying behavior.
>
>Suppose you have the following variables:
>
>P1: \<< \-> a \<< 'a' INC \>> \>>
>INC: \<< \-> a \<< a INCR DROP \>> \>>
>
>Executing 5 P1 gives INCR Error: Bad Argument Type.
>If you change the local variable in either of the programs to something
>different, you get 6, as you would expect.  Apparently, INC thinks
>that the 'a' on the stack refers to the innermost local variable,
>rather than the one belonging to P1.  If this behavior is documented
>in the manuals, I haven't seen it.

It looks like all you are trying to do is pass the current value of 'a'
in P1 to the 'a' in INC.  If that is what you're doing whats wrong with

P1:  /<< /-> a /<<  a INC />>

removing the ''s around the a the 48 recalls the value of a to the stack where
the second program picks it up.  The problem is not that the machine thinks
you are referring to the value of 'a' in P1 it thinks you are referring to the
name 'a' you have put on the stack.  Thus in the second program the machine
sees

1:           'a'
 -> a

thats like saying 'a' 'a' STO.  Store 'a' into itself doesn't make much
sense.

Incidentally if you rename one of the two local variables its fine because
the HP sees

1:            'b'
 -> a

So 'b' gets stored into 'a' and the EVAL works down the chain and eventually
recalls the value of 'b'.

I hope that explains the problem.  And I hope I've understood the problem
If not (and since I'm kinda dense sometimes I probably haven't) just
scream.  And I or someone else will give another shot.

======================================================================
  ___
  I__)  _   _I  _   _   TIM STRONG <TDSTRONG%MTUS5.BITNET@CUNYVM.EDU>
  I  \ (_I (_I (_I I    MICHIGAN TECH.    HOUGHTON, MICHIGAN

======================================================================

Date: Tue, 9 Apr 1991 13:02 CST
Subject: Re: HP-48 programming problem
Lines: 50

>I had a problem debugging a program today, and I was wondering if anyone
>had encountered the same problem before.  The problem isn't a bug, but
>it is annoying behavior.

>Suppose you have the following variables:

>P1: \<< \-> a \<< 'a' INC \>> \>>
>INC: \<< \-> a \<< a INCR DROP \>> \>>

There is a way to do what you desire.  My reversi program for the hp28 made
extensive use of it.  You have to trick the parser into thinking that the
variable 'a' is a local variable without including '-> a' in the executable
code.

Write a Make_INC routine that looks like (I've labeled the double brakcets):

Make_INC: \<< \-> a \<< \<< a INCR DROP \>> 'INC' STO \>> \>>
            A         B   C              C             B   A

Then run this program and you have a version of INC that binds 'a' to
a local variable but it doesn't define 'a' itself.  The reason that this
works is that when the Make_INC routine is parsed 'a' is a local variable,
because it is defined at block level A and it is permitted to be used at
level B.  The parser then processes level C and says that 'a' is local.
When this is run, the block C is pushed onto the stack and then stored into
the variable INC, without re-evalulating the bindings.  This means that 'a'
(inside block C) still binds to a local variable.  When your program P1 calls
INC, the locally bound 'a' refers the the 'a' defined inside of P1 !!!
You can now have global, local variables.

If you try to run the new INC routine and there is no 'a' defined by any
context along the call chain then you get an error message (undefined local?).
Try this, it doesn't do any harm.

Cute feature isn't it.



        						Pauli
seeya

Paul Dale               | Internet/CSnet:            grue@cs.uq.oz.au
Dept of Computer Science| Bitnet:       grue%cs.uq.oz.au@uunet.uu.net
Uni of Qld              | JANET:           grue%cs.uq.oz.au@uk.ac.ukc
Australia, 4072         | EAN:                          grue@cs.uq.oz
                        | UUCP:           uunet!munnari!cs.uq.oz!grue
f4e6g4Qh4++             | JUNET:                     grue@cs.uq.oz.au
--

Date: Tue, 9 Apr 1991 13:05 CST
Subject: Re: HP-48 programming problem
Organization: University of Oregon Chemistry Stores
Lines: 93

In article <1991Apr9.021224.27070@usenet.ins.cwru.edu> rkb@po.CWRU.Edu
(Robert K. Brunner) writes:

   I had a problem debugging a program today, and I was wondering if anyone
   had encountered the same problem before.  The problem isn't a bug, but
   it is annoying behavior.

   Suppose you have the following variables:

   P1: \<< \-> a \<< 'a' INC \>> \>>
   INC: \<< \-> a \<< a INCR DROP \>> \>>

   Executing 5 P1 gives INCR Error: Bad Argument Type.
   If you change the local variable in either of the programs to something
   different, you get 6, as you would expect.  Apparently, INC thinks
   that the 'a' on the stack refers to the innermost local variable,
   rather than the one belonging to P1.  If this behavior is documented
   in the manuals, I haven't seen it.

The manuals attempt to document the scope rules of variables in
pages 473 ff., but while they imply that local variables follow
simple static scope rules, they only cite examples where static
and dynamic scope rules are equivalent because none of their
examples pass local names around as you did.

   By the way, I worked around the problem by using pass-by-value in
   the real program.  Unfortunately, the reason I use a sub-program
   is that I need the routine in three places, so I've got three
   extra " 'a' STO " 's, one after each call of the routine.  I may
   change the local variable in the routine, but it bothers me that
   subroutine calls are not transparent.  Suppose someone writes a
   library that uses a local variable which I unwittingly use elsewhere.

   Robert

You have discovered that RPL has dynamic scoping, not static
scoping, which is important to know because it will definitely
affect the way certain programs will work.  Even worse, RPL
doesn't support passing a reference token to a variable, which I
think is what you were thinking it would do.

Dynamic scoping means that you can't tell what variables are in
scope (that is, which names refer to which values in which
active functions) just by inspecting the program visually.  A
local name can refer to different local variables depending on
which function is doing the calling.

When you use the same local name 'a' in both P1 and INC, then
when INC is called from P1, INC's local name 'a' is bound to the
local name 'a'.  Because RPL represents the local name 'a' the
same in all scopes, when you evaluate the expression "a" to
recall its contents, you get the local name 'a'.  When INCR
retrieves the value bound to 'a', it again gets the local name
'a', and generates the "Bad argument type" message because that
isn't a real number.

This isn't as telling as the behavior shown when you use the
local name 'a' in P1 and 'b' in INC.  Then, the value of "b" in
INC is the local name 'a', so INCR is passed the local name 'a',
and increments the value bound to local name 'a' _in the calling
function_, P1.  This is possible because RPL lets you put a local
name on the stack, and because it clearly will attempt to resolve
a local name which isn't bound in the current scope by looking
for its binding in the function that called the current one, then
the function that called the function that called the current
one, and so on.  While dynamic scoping will act like static
scoping for the examples given in the manual, in this case it is
different.  In a statically scoped language, the variable would
have to be defined in the current function, or in the environment
that the current function is defined in, or in the environment
global to that, etc., or you would get an error at the time you
entered the statement.  The run-time nesting of functions would
not affect the resolution of binding of local names in any way.

RPL therefore has two features that will bite people who are used
to programming in most conventional programming languages.
First, it uses dynamic instead of static scoping, which makes it
far more difficult to predict what a name will refer to, because
that depends on which functions have called which.  Second,
unlike most languages which allow you to pass arguments by value
or by reference, RPL only allows you to pass arguments by value
or by _name_, which if I recall correctly hasn't been done much
since Algol faded from popularity.

RPL therefore fully lives up to the name "Reverse Polish LISP",
because the original LISP used dynamic instead of static scoping.
Ironically, Common LISP now uses static scoping (although dynamic
scoping is still available for backwards compatibility) and the
popular LISP dialect Scheme uses static scoping exclusively.
--
Steve VanDevender 	stevev@greylady.uoregon.edu
"Bipedalism--an unrecognized disease affecting over 99% of the population.
Symptoms include lack of traffic sense, slow rate of travel, and the
classic, easily recognized behavior known as walking."


Date: Wed, 10 Apr 1991 16:47 CST
Subject: Re: HP-48 programming problem
Lines: 53

Unfortunately, the technique you suggest won't do what I thought
the original poster really wanted, which was to be able to make a
subroutine that would apply INCR to an arbitrary variable.
Another poster didn't notice that INCR was being called and
thought that the original poster wanted to pass the value of a
local name 'a' to the subroutine, not the name itself.

You can pass local names into a subroutine to do operations that
need a local name and not just its contents, but you cannot make
the subroutine completely general because passing a local name
which is also used in the subroutine will cause the subroutine to
operate on its own local variable, not on the one in the caller.
There is no way to pass a reference pointer to a variable so that
a subroutine can operate on any variable in any scope in standard
RPL.

RPL has different scope rules for global names and local names,
which I find very interesting.

Global names are statically scoped based on the current PATH.
Global name references are resolved by searching the current
directory, then the parent of the current, then its parent, on up
to HOME.  The run-time nesting of functions has no effect on the
resolution of global name references.

Local names are dynamically scoped based on the run-time nesting of functions.
A local name reference is resolved by searching
the bindings of the current function, then in the function that
called it, then in the function that called that, and so on.  If
a function passes a local name into another function, and the
called function doesn't use the same local name, then references
to that local name get its value in the calling function.  A
function that refers to a local name without first creating it,
like the one you created with

\<< \-> a \<< \<< 'a' INCR \>> 'INC' STO \>> \>>

will end up being completely dependent on run-time function
nesting to determine its effect.

I don't want to say that this kind of dynamic scoping is bad, but
it can produce some very counterintuitive behavior and the kinds
of problems that the original poster reported.  Generally nobody
uses dynamic scoping any more in programming languages.  I think
that knowing it is used in RPL is very important because of the
subtle effects it can have.

--
Steve VanDevender 	stevev@greylady.uoregon.edu
"Bipedalism--an unrecognized disease affecting over 99% of the population.
Symptoms include lack of traffic sense, slow rate of travel, and the
classic, easily recognized behavior known as walking."




Date: Fri, 12 Apr 1991 00:00 CST
Subject: A Way to pass variables?


Something someone was trying to do with incrementing a local variable
in one program in another got me to thinking about an old technique
I used to use on the 28.  Unfortunately I haven't found a way to make
it do what he wanted but its still neat:

Try the following:

On the command line enter

 0 -> a << HALT

Then press return

Next without KILLing the above HALT make another program or algebraic using
'a' for example:

'2*a^3'  'EQT'  STO

STO it away then press KILL

Now try a new program such as

<< -> a << EQT EVAL >>  'TRYIT'

put a number on the stack an run it.  Notice that the inner program
EQT recognizes the local variable 'a' from the program that called it.
If you don't understand what I mean just quickly VISIT 'EQT' and put
it back unchanged and run 'TRYIT' again.  Notice this time 'a' is no longer
recognized in EQT.

Somebody from HP showed this to us a year or so back.  What happens is
that as long as you are HALTed in a program that has a local variable,
any program or algebraic you create will also be created using that name
as a local, not a global variable.

Maybe this could be used to pass variables

<< (some glorious operation with a)  'a' STO >>

Make it as above with the HALTed program currently going then I believe
you can pass the 'a' back to the orginal program.  This seems like a solution
to the problem of passing variables except one can only pass the variable of
the same name (which stinks).  Anyone think of a better way.  Maybe you
could check with an IF THEN.  {Maybe I'm just babbling to myself and no one
can understand a word of what I'm saying because I'm inept at saying it.}

======================================================================
  ___
  I__)  _   _I  _   _   TIM STRONG <TDSTRONG%MTUS5.BITNET@CUNYVM.EDU>
  I  \ (_I (_I (_I I    MICHIGAN TECH.    HOUGHTON, MICHIGAN

======================================================================

