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

HOw to pass stems as procedure arguments

729 views
Skip to first unread message

Achim Hasenmueller

unread,
Dec 20, 1998, 3:00:00 AM12/20/98
to
Hi,

I have two questions about OS/2 Rexx (should be quite general) and stem
variables

/* */
test.0 = 3
test.1 = 1
test.2 = 2
test.3 = 3
call TestFunc test.
exit

TestFunc: procedure
ARG n
do i = 1 to n.0
SAY n.i
end
return 1

First, why can't I pass a stem variable to my function? Is the syntax
wrong? Also, is there any way to
automatically determine the number of items in a stem dimension (i.e.
test.0 will be set by the interpreter)

Thanks for your help,
Achim

poole

unread,
Dec 20, 1998, 3:00:00 AM12/20/98
to

try EXPOSE TEXT. in the procedure rather than ARG.

Mike Ruskai

unread,
Dec 20, 1998, 3:00:00 AM12/20/98
to
On Sun, 20 Dec 1998 16:12:02 +0100, Achim Hasenmueller wrote:

>Hi,
>
>I have two questions about OS/2 Rexx (should be quite general) and stem
>variables
>
>/* */
>test.0 = 3
>test.1 = 1
>test.2 = 2
>test.3 = 3
>call TestFunc test.
>exit
>
>TestFunc: procedure
>ARG n
>do i = 1 to n.0
> SAY n.i
>end
>return 1
>
>First, why can't I pass a stem variable to my function? Is the syntax
>wrong? Also, is there any way to
>automatically determine the number of items in a stem dimension (i.e.
>test.0 will be set by the interpreter)

You can't pass stem variables, unless you're using Object REXX, where you'd
use 'use arg' instead of just 'arg' (or 'parse arg').

You can, however, expose stem variables in SAA REXX, by putting 'expose
stemname.' after the procedure label (has to be on the same line, whether
literally or with line continuation).

The only way to get a value for the number of stem values is with Object
REXX, by using the makearray method. That makes an array of the values for
every tail of the given stem, which includes additional tails for that stem
(which would have to be tacked onto the original stem to get at their
values).

For example:

svar.1=1
svar.2=2
svar.3=3
svar.1.1=11
svar.2.1=22
svar.3.1=33

tvar=svar.~makearray

do i=1 to tvar~items
say tvar[i]
end

do i=1 to tvar~items
cval=tvar[i]
if cval~pos('.')>0 then say svar.cval
end

Running the above should give you an idea of what's going on.


--
- Mike

Remove 'spambegone' to send e-mail.

Patrick TJ McPhee

unread,
Dec 20, 1998, 3:00:00 AM12/20/98
to
In article <367D13C2...@innotek.de>,
Achim Hasenmueller <ach...@innotek.de> wrote:

% I have two questions about OS/2 Rexx (should be quite general) and stem
% variables

You can't pass stem variables to functions in ANSI rexx, but you can
in object rexx. If you have OS/2 4.0 or higher, object rexx can be made
active by running a command script (which I think is called switchrx or
something like that). If you have OS/2 3.0, you can down-load object
rexx from some IBM site.

The test.0 thing is really just a convention -- stems per se don't have
a concept of the highest index or number of valid stems. Object rexx
has `do over', which works like this:
andover.'albert' = 'janice'
andover.'tom' = 'sally'

do it over andover.
say it 'and' andover.it
end

which would print
albert and janice
tom and sally

I would love to see this make its way into ANSI rexx, because it's
a real deficiency in the stem concept.
--

Patrick TJ McPhee
East York Canada
pt...@interlog.com

Juergen Kehr

unread,
Dec 20, 1998, 3:00:00 AM12/20/98
to Achim Hasenmueller
Hello,
I think the problem you mentioned isn't a problem of subroutines, in fact
it's the problem that you can't use the stem only on the RIGHT side of an
assignment. (i.e. abc = test. , say test. ) This normally doesn't make
sense. The only context where it make sense is test. = 'Default' , to give
any possible extended variable with stem test. the value 'Default' (besides
some special usings in EXECIO (other platforms) etc.)
For your second question I think within standard REXX ( and ObjectREXX too
) there is no way to determine the "number of items" in a stem, but I've
heard of some extensions in some other REXX implementations (I think
WinREXX).
BTW: The variable i within test.i hasn't to be numerically, so the REXX
stem isn't exactly the same as an array in other languages.
Kind regards.

Achim Hasenmueller schrieb:

> Hi,


>
> I have two questions about OS/2 Rexx (should be quite general) and stem

> variables
>
> /* */
> test.0 = 3
> test.1 = 1
> test.2 = 2
> test.3 = 3
> call TestFunc test.
> exit
>
> TestFunc: procedure
> ARG n
> do i = 1 to n.0
> SAY n.i
> end
> return 1
>
> First, why can't I pass a stem variable to my function? Is the syntax
> wrong? Also, is there any way to
> automatically determine the number of items in a stem dimension (i.e.
> test.0 will be set by the interpreter)
>

> Thanks for your help,
> Achim

___________________________________________________________

Freundliche Gruesse

Dipl.-Math. Juergen Kehr
Senior Consultant
rubin Software GmbH

Tel. +49-511-463050
Fax +49-511-463055
Mobil +49-172-5129389

e-Mail KehrJ...@t-online.de
KehrJ...@netscape.net
KehrJ...@csi.com

Fax -> e-Mail +49-40-3603022846
___________________________________________________________

Jerry McBride

unread,
Dec 20, 1998, 3:00:00 AM12/20/98
to
In article <75jm44$bct$1...@news.interlog.com>,

pt...@interlog.com (Patrick TJ McPhee) wrote:
>In article <367D13C2...@innotek.de>,
>Achim Hasenmueller <ach...@innotek.de> wrote:
>
>% I have two questions about OS/2 Rexx (should be quite general) and stem
>% variables
>
>You can't pass stem variables to functions in ANSI rexx, but you can
>in object rexx. If you have OS/2 4.0 or higher, object rexx can be made
>active by running a command script (which I think is called switchrx or
>something like that). If you have OS/2 3.0, you can down-load object
>rexx from some IBM site.
>

That "some site" is http://www2.hursley.ibm.com/orexx. While you're there have
a look at www2.hursley.ibm.com/netrexx. Netrexx really is, much better.

--

/--------------------\
| Jerry McBride |
| mcbr...@erols.com |
\--------------------/


Lueko Willms

unread,
Dec 21, 1998, 3:00:00 AM12/21/98
to
Am 20.12.98
schrieb pt...@interlog.com (Patrick TJ McPhee)
auf /COMP/LANG/REXX
in 75jm44$bct$1...@news.interlog.com
ueber Re: HOw to pass stems as procedure arguments

PTM> Achim Hasenmueller <ach...@innotek.de> wrote:
PTM>
PTM> % I have two questions about OS/2 Rexx (should be quite general) and stem
PTM> % variables
PTM>
PTM> You can't pass stem variables to functions in ANSI rexx, but you can
PTM> in object rexx.

One can also pass the Stem variable _name_ and use the VALUE
function. Thats what I did.

Yours,
Lüko Willms
/------------ L.WI...@LINK-F.rhein-main.de -- Will...@compuserve.com
/------------ Lueko....@T-Online.de -- "Get PGP Key" im Betreff

"Ohne Pressefreiheit, Vereins- und Versammlungsrecht ist keine
Arbeiterbewegung möglich" - Friedrich Engels (Februar 1865)

Stan Irish

unread,
Dec 22, 1998, 3:00:00 AM12/22/98
to

Lueko Willms wrote:

The VALUE method is documented in REXX Tips & Techniques - Writing general
purpose routines for compound variables. See RXTT28.ZIP.

This allows your procedure to see the stem variable contents but I don't think it
can update them. Correct me if I am wrong here.

I have settled on using a "holding" array for the subroutine. I move the contents
of my target array into the holding array, call the procedure (which has an EXPOSE
clause for the holding array), then move the contents of the holding array back to
the target array. Ugly, but it works.

--
Stan


dan...@crosslink.net

unread,
Dec 22, 1998, 3:00:00 AM12/22/98
to
A few points regarding stem variables:

1) The REXXLIB or RXU procedure libraries (for classic rexx) offer a few
means of "passing stems to procedures" (even external procedures).

REXXLIB (and RXU) have a "save a stem variable to a special file"
procedure -- one could have the
a) calling procedure save a stem to a file (a "stemfile")
b) call a procedure, passing the "stemfile" name as an argument c) called
procedure reads stemfile, does it's business, and
saves results back to the stemfile
d) calling procedure rereads stem file
It's clunky and slow, but easy to implement.

Or. ..

RXU implements an RxPassByName as an alternative to using
expose; you call a procedure as an argument of rxpassbyname, and also list
variables (including stem variables) to pass "by value or by reference" to
this (possibly external) procedure.


BTW: VALUE can be used to set values -- just give a second
argument.

2) Since REXX tails can be anything (including strings containing spaces),
REXX stem variables offer a cheap way of creating
database structures. That is, you can read information into
a stem array (say, CUSTOMERS.NAME, where name is the
actual customer's name), and then later lookup data
(say id=CUSTOMERS.JoeSmith.!ID). REXX takes care of
matching the stem.tail to an actual memory location,
and does it relatively efficiently (using b-trees?).

Thus, one does NOT need to implement sorted lookup tables (or whatever) --
just let REXX do the dirty work (assuming your
databases are small enough to fit into memory).

There is one issue -- how to detect "uninitialized" records....

3) Recently, Peter S Tillier <pet...@eq1152.demon.co.uk> noted that use of

foo.=0
to initialize the foo stem; the effect being to set values of foo.0,
foo.1, etc. equal to 0. This was interesting news, since I often have
need to check "has this stem.tail been initialized", and have used
methods like
if datatype("FOO."||tailvalue)<>'VAR' then ...
or
if translate(foo.tailvalue)="FOO.TAILVALUE" then ...

Setting
foo.tailvalue='N.A.'
and then checking
if foo.tailvalue='N.A.'
is a lot easier on my eyes!

Unfortunately (also pointed out by Peter), this method has
limits: foo.1.=0 does NOT initialize foo.1.3 (that is, foo.1.3 is given a
value of FOO.1.3, not a value of 0. It seems
one can initialize and entire stem, but not portions of a stem (again,
this is under classic os/2 rexx; other variants may be different).


Juergen Kehr

unread,
Dec 22, 1998, 3:00:00 AM12/22/98
to
Hello,

dan...@crosslink.net schrieb:

> There is one issue -- how to detect "uninitialized" records....
>
> 3) Recently, Peter S Tillier <pet...@eq1152.demon.co.uk> noted that use of
>
> foo.=0
> to initialize the foo stem; the effect being to set values of foo.0,
> foo.1, etc. equal to 0. This was interesting news, since I often have
> need to check "has this stem.tail been initialized", and have used
> methods like
> if datatype("FOO."||tailvalue)<>'VAR' then ...
> or
> if translate(foo.tailvalue)="FOO.TAILVALUE" then ...
>
> Setting
> foo.tailvalue='N.A.'
> and then checking
> if foo.tailvalue='N.A.'
> is a lot easier on my eyes!
>
> Unfortunately (also pointed out by Peter), this method has
> limits: foo.1.=0 does NOT initialize foo.1.3 (that is, foo.1.3 is given a
> value of FOO.1.3, not a value of 0. It seems
> one can initialize and entire stem, but not portions of a stem (again,
> this is under classic os/2 rexx; other variants may be different).

I think most REXX implementations have the SYMBOL build-in function, which
gives an easy tool to determine if a variable is initialised or not. The
function works perfect for compound variables too. So the mentioned methods
are not necessary anyway if you use this function:

Here an example:

/* REXX */

a.1 = 'init string'
k = 5
a.k = 'init string'
b. = 'init string'
say symbol('a.1') /*will give VAR (for initialized)*/
say symbol('a.2') /*will give LIT (for not initialized)*/
say symbol('a.k') /*will give VAR*/
say symbol('b.1') /*will give VAR*/

But nevertheless your solution has some advantages, because it's not easy to
work with uninitialized variables if you plan to use the SIGNAL ON NOVALUE
statement.

Kind regards.

dan...@crosslink.net

unread,
Dec 22, 1998, 3:00:00 AM12/22/98
to
In <36802104...@t-online.de>, on 12/22/98
at 11:45 PM, KehrJ...@t-online.de (Juergen Kehr) said:

>> need to check "has this stem.tail been initialized", and have used
>> methods like
>> if datatype("FOO."||tailvalue)<>'VAR' then ...
>> or
>> if translate(foo.tailvalue)="FOO.TAILVALUE" then ...
>>

>I think most REXX implementations have the SYMBOL build-in function,
>which gives an easy tool to determine if a variable is initialised or
>not. The function works perfect for compound variables too. So the

Oooops- -- I did mean SYMBOL, not DATATYPE.

Do note that one must have a string representing that is the variable name
when using SYMBOL; in contrast, DATATYPE expects
the variable.

For example:
bb=symbol('A.1') /* bb will be VAR */
cc=datatype(a.1) /* cc will be NUM */
bb2=symbol('A.2') /* bb2 will be LIT */
cc2=datatype(a.2) /* cc2 will be CHAR */

a.3='HELP'
bb3=symbol('A.3') /* bb will be VAR */
cc3=datatype(a.3) /* cc will be CHAR */

Thus, datatype is NOT appropriate for detecting uninitialize stem tails
(unless all the tails are numeric, in which case you could check for a
CHAR value of datatype).

Basically, if find that the symbol type can be painful to code, especially
if you got long tails. That is:
ok=symbol('ASTEM.'||tail1_val||'.'||tail2_val)
is not the most pleasing thing to behold!

>___________________________________________________________
--
-----------------------------------------------------------
dan...@crosslink.net
-----------------------------------------------------------


Patrick TJ McPhee

unread,
Dec 23, 1998, 3:00:00 AM12/23/98
to
In article <367F79EE...@acepia.net.au>,
Stan Irish <sir...@acepia.net.au> wrote:

% Lueko Willms wrote:

% > One can also pass the Stem variable _name_ and use the VALUE
% > function. Thats what I did.

While this is true, you must either expose the names of all the possible
stem variables you might use, or forego the use of procedure. There are
probably good reasons, but it's a bit limiting.

% This allows your procedure to see the stem variable contents but I don't think it
% can update them. Correct me if I am wrong here.

call afunc 'STEM.'
say stem.0
exit 0

afunc:
call value arg(1) || 0, 27
return

will set stem.0 to 27.

Ed Panker

unread,
Dec 23, 1998, 3:00:00 AM12/23/98
to
On Sun, 20 Dec 1998 17:22:08, "Mike Ruskai" <tha...@spambegone.home.com>
wrote:

> You can't pass stem variables, unless you're using Object REXX, where you'd
> use 'use arg' instead of just 'arg' (or 'parse arg').

Not so.

> You can, however, expose stem variables in SAA REXX, by putting 'expose
> stemname.' after the procedure label (has to be on the same line, whether
> literally or with line continuation).

The restriction is that you have to hard-code the name.

What I would do to pass a stem, was to have an open "bridge" routine that
would accept the stem as a string ...

Call bRoutine "Stem."

The "bRoutine" procedure would accept the argument and set a variable in MY
control:

plist - Arg(1)

.. then call the actual routine wait other paramaters BUT NOT THE PLIST:

Call bWorker

.. in bWorker, the procedure statement would have the following:

bWorker Procedure Expose (plist)

In this context, "plist" contains the name of the stem and in this fashion,
the user can pass me any name for a stem they want. When I needed to work the
stem ...

Interpret plist"0 = 0"

.. a couple of things now: my bridge routtine had to ensure that the name of
the stem ended in a period, and the worker routine had to do as little as
possible. The reason? INTERPRETing statements carries extremely HUGE
overhead - like 200 to 1 over a basic assignment statement.

Ed Panker
Panker Systems Ltd.
Remove the asterisks and "nospam." to reply


Jeff

unread,
Dec 24, 1998, 3:00:00 AM12/24/98
to
I know it sounds kind of silly, but one solution would be to remove the
procedure statement:


Achim Hasenmueller wrote in message <367D13C2...@innotek.de>...


>/* */
>test.0 = 3
>test.1 = 1
>test.2 = 2
>test.3 = 3
>call TestFunc test.
>exit
>
>TestFunc: procedure


Would be:
TestFunc:

>ARG n
The arg statement would then not be needed.


>do i = 1 to n.0
> SAY n.i
>end
>return 1
>


Technically this procedure would then become a subroutine in which all
variables would then be global. If you need to be able to substitute the
stem to which you are referring you could:

TestFunc:
ARG n /* n is the name of the prefix of the stem
*/
interpret "do i = 1 to "n".0" /* for n="STEM1", "do i = 1 to STEM1.0"
after substitution */
interpret "SAY "n".i" /* "say STEM1.i" */
end
return 1

In the above example "n" holds the string name of the prefix of the stem.
Note you must be careful how you use variables inside the subroutine because
all variables will then be visible to all other subroutines and the main
subroutine.


>First, why can't I pass a stem variable to my function?

My guess would be that a STEM is not a variable it is a variable structure.
In my experiance with many simple languages most don't allow passing of
structures. With newer languages such as object rexx and vb.


>Is the syntax wrong?
The syntax is not necessarily wrong, just not implemented in your version of
REXX.

>Also, is there any way to automatically determine the number of items in a
stem dimension (i.e.
>test.0 will be set by the interpreter)

As long as you place the stem count in the ".0" entry the above example
should work. I have used something similar in MVS/TSO REXX to load files
from a particular DDNAME:

/* REXX */

CALL LOAD_FILE 'CARDIN' 'USERID.CONTROL.CARDS.IN'
CALL LOAD_FILE 'FILEIN' 'USERID.FILE.IN'

CALL PROCESS_FILE
RETURN
/***************************************/
LOAD_FILE:
ARG DDNAME FILE_NAME
INTERPRET "ALLOC FI("DDNAME") DA('"FILE_NAME"'" SHR REUSE"
INTERPRET "EXECIO * DISKR "DDNAME" (STEM "DDNAME".L. FINIS"
RETURN

This would load the file associated with CARDIN into stem CARDIN.L., and
FILEIN into stem FILEIN.L. . Where both would have the count of records in
their ".L.0" stem variables.

Rex Swain

unread,
Dec 28, 1998, 3:00:00 AM12/28/98
to
See my web page <http://www.pcnet.com/~rhswain/rexx.html> and follow the link
to "SORTSTEM.REX" for some sample techniques for sorting, which involves
passing a stem to a subroutine.

Personally, I prefer the method demonstrated in sort3() and sort4().

__________________________________

Rex Swain ; Independent Consultant
Tel: 860-868-0131 ; Fax: 860-868-9970
Mail: 8 South Street ; Washington, CT 06793 ; USA
Email: rhs...@acm.org ; Web: http://www.pcnet.com/~rhswain

Metz, Seymour

unread,
Dec 28, 1998, 3:00:00 AM12/28/98
to
It's not clear that that posibility was overlooked by anyone. I doubt that
I'm the only one to consider it undesirable, since data are then passed
independently of the arguments. Global variables and the like are sometimes
necessary, but their use should be considered to be a last resort.

Shmuel (Seymour J.) Metz

> -----Original Message-----
> From: Ross Patterson [SMTP:RO...@SS1.RESTON.VMD.STERLING.COM]
> Sent: Monday, December 28, 1998 9:45 AM
> To: REXX...@UGA.CC.UGA.EDU
> Subject: Re: HOw to pass stems as procedure arguments


>
> Achim Hasenmueller <ach...@innotek.de> writes:
> >I have two questions about OS/2 Rexx (should be quite general) and stem

> >variables
>
> Several responders have noted that REXX does not allow you to pass an
> entire stem array as an argument to a procedure (ala "X = Y(Z.)") and
> offered the option of exposing the stem array to the called routine.
> That works well for subroutines where the name of the stem array never
> varies, or can at least be constrained to a small enough list so you can
> put them all on a PROCEDURE EXPOSE clause. One possibility that has
> been overlooked so far is the ability to expose variables dynamically.
>
> REXX level 4.00 (circa 1990) added support on the PROCEDURE EXPOSE
> clause for "variable references". To quote from "The REXX Language"
> (2nd ed.), section 7 "Keyword Instructions" (pp. 65):
>
> "PROCEDURE [EXPOSE variablelist];
>
> ...
>
> The symbols in variablelist must be valid variable names and are
> exposed in sequence from left to right. If the variable name is
> enclosed in parentheses (blanks are not necessary either inside or
> outside the parentheses, but may be added if desired) then it is a
> variable reference. The variable itself is exposed and then its
> value is immediately used as a subsidiary variable list which must
> follow the same rules as the original list except that no
> parentheses are allowed. ..."
>
> In other words, a caller can allow a subroutine to expose a stem that the
> author of the subroutine was not aware of. For example:
>
> /* */
> Trace R
>
> A. = 1 /* Set A.<whatever> to 1 */
> A.1 = 2 /* Set A.1 to 2 */
> B = 'A.' /* We'll pass "A." to C */
> Call C
> Say 'A.2=' A.2 /* Display changed A.2 */
>
> Exit
>
> C: Procedure expose (B) /* Expose B and its contents */
>
> Say 'B=' B /* What stem are we using? */
> Say B || '1=' Value(B || '1') /* Display <stem.>1 */
> Say B || '2=' Value(B || '2', '3') /* Display and change <stem.>2 */
>
> Return
>
> produces:
>
> 4 *-* A. = 1
> >>> "1"
> 5 *-* A.1 = 2
> >>> "2"
> 6 *-* B = 'A.'
> >>> "A."
> 7 *-* Call C
> 12 *-* C:
> *-* Procedure expose (B)
> 14 *-* Say 'B=' B
> >>> "B= A."
> B= A.
> 15 *-* Say B || '1=' Value(B || '1')
> >>> "A.1= 2"
> A.1= 2
> 16 *-* Say B || '2=' Value(B || '2', '3')
> >>> "A.2= 1"
> A.2= 1
> 18 *-* Return
> 8 *-* Say 'A.2=' A.2
> >>> "A.2= 3"
> A.2= 3
> 10 *-* Exit
>
> Ross Patterson
> VM Software Division
> Sterling Software, Inc.

Metz, Seymour

unread,
Dec 28, 1998, 3:00:00 AM12/28/98
to
Mike is correct. The code that you showed does not pass stem variables; it
passes a string. There is a differences between passing a variable and
exposing it.

Shmuel (Seymour J.) Metz

> -----Original Message-----
> From: Ed Panker [SMTP:*ve6yj*@NOSPAM.COMPUSMART.AB.CA]
> Sent: Wednesday, December 23, 1998 11:08 PM
> To: REXX...@UGA.CC.UGA.EDU
> Subject: Re: HOw to pass stems as procedure arguments
>

> .. a couple of things now: my bridge routtine had to ensure that the name
> of

jeff

unread,
Jan 12, 1999, 3:00:00 AM1/12/99
to
This works well. I Tried in both classic Rexx and Regina. Note that there
is a bug in Regina that you need to capitalize the stem that you are
passing.

Here is a simple test program that I made based on the sort routines:

/* passstem.rexx */

stemname = 'FOO.' /* use CAPs workaround bug in Regina */

foo.0 = 1
foo.1 = 'something'

call func

say foo.0
say foo.1

exit 0


func: procedure expose stemname (stemname)
/* trace ?i */

do i = 1 to value(stemname||0)
r = value(stemname||i,'something else')
end

return 0


Rex Swain <rhs...@acm.org> wrote in message news:R_Oh2.66$Le1.2...@news.pcnet.com...

Shmuel (Seymour J.) Metz

unread,
Jan 13, 1999, 3:00:00 AM1/13/99
to
jeff wrote:
>
> This works well. I Tried in both classic Rexx and Regina. Note that there
> is a bug in Regina that you need to capitalize the stem that you are
> passing.

I believe that Regina is working according to specifications.

--

Shmuel (Seymour J.) Metz
Reply to host nsf (dot) gov, user smetz

0 new messages