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

How To Question -- passing all of a stem variable contents -- NOT homework

1,804 views
Skip to first unread message

Steve Thompson

unread,
Jan 16, 2013, 4:47:52 PM1/16/13
to
I've been battling something for most of the day. Something that I kinda
remember doing about 5 years ago, but I just can't recall how.

Here is the issue.

I have a mainline routine that will invoke an internal subroutine. One of
the arguments passed to it is a stem variable. Specifically, I need to
pass the whole thing so I do something like the following:

FIX_DATA(p_list1. "blanks asa")


Now, in the subroutine I have something like this:

FIX_DATA: NOP

PARSE ARG UPPER fixlist remove_list .


What comes in in fixlist is"P-LIST1." and I have been unable to figure out
how to use VALUE or INTERPRET to get "fixlist" to be treated as p_list1.
(I am expecting to pass other lists with other names as I work on this).

I have tried various ways to do an assign to get this work work (again,
using INTERPRET), but I can't seem to get it to resolve correctly.

Sorry, doing a stack or buffer is not going to work too well, as once I
get done with this, I am going to replace, line for line, what is in this
stem.

Regards,
Steve Thompson

----------------------------------------------------------------------
For TSO-REXX subscribe / signoff / archive access instructions,
send email to LIST...@VM.MARIST.EDU with the message: INFO TSO-REXX

Walter Pachl

unread,
Jan 16, 2013, 5:14:41 PM1/16/13
to
use
internal: Procedure Expose stem.
You can't pass a sem and all its 'members' as argument!
Walter

btw: ooRexx introduced this functionality but ain't available on TSO

Steve Thompson

unread,
Jan 16, 2013, 5:35:35 PM1/16/13
to
<SNIPPAGE>
use
internal: Procedure Expose stem.
You can't pass a sem and all its 'members' as argument!
Walter

<SNIPPAGE>

Doesn't this presume that I am using the same stem variable over and over,
which is *not|* what I'm doing.

I will be passing different stems depending on where I am in the code.

Regards,
Steve Thompson

Grinsell, Don

unread,
Jan 16, 2013, 6:21:05 PM1/16/13
to
How about something like this:

/* rexx */
outer.0 = 3
outer.1 = 1
outer.2 = 2
outer.3 = 3
do i = 0 to outer.0
inner.i = outer.i
end
call subr inner.
exit
subr: procedure expose inner.
do i = 1 to inner.0
say inner.i
end
return

--

Donald Grinsell
State of Montana
406-444-2983
dgri...@mt.gov

"The secret of being miserable is to have leisure to bother about whether you are happy or not. The cure for it is occupation."
~ George Bernard Shaw (1856-1950)

Grinsell, Don

unread,
Jan 16, 2013, 6:38:59 PM1/16/13
to
Actually, after re-reading your question, I think this might do it for you:

icommand = 'do I = 1 to' fixlist||'0;say' fixlist||'I;end'
interpret icommand

Remember to separate your commands with semicolons and if you are creating a do loop for interpret, the do and end have to be included in icommand. The abuttal operator (||) isn't strictly necessary but it helps clarify the code. When the interpret executes it should resolve out as this:

do I = 1 to p_list1.0;say p_list1.I;end

Regards.

--

Donald Grinsell
State of Montana
406-444-2983
dgri...@mt.gov

"Think you can, think you can't, either way you'll be right."
~ Henry Ford

-----Original Message-----
From: TSO REXX Discussion List [mailto:TSO-...@VM.MARIST.EDU] On Behalf Of Steve Thompson

Glenn Knickerbocker

unread,
Jan 16, 2013, 6:44:16 PM1/16/13
to
On 1/16/2013 5:14 PM, Walter Pachl wrote:
> internal: Procedure Expose stem.

You can get slightly more modern in TSO REXX. Expose the stem by name:

internal: Procedure Expose (stem)

And then use VALUE() to read and write it:

/* TAIL in this example also contains the *name* of a variable.
Suppose stem = 'X.' and tail = 'I'
*/
y = Value(stem || tail) /* sets Y to the value of X.I */
Call Value stem || tail, z /* sets X.I to the value of Z */

¬R

Roberto Halais

unread,
Jan 16, 2013, 6:48:22 PM1/16/13
to
Check out this (might help):

http://tech.groups.yahoo.com/group/rexxlist/message/5630
--
"Men will never be free until the last king is strangled with the entrails
of the last priest." Denis Diderot

Grinsell, Don

unread,
Jan 16, 2013, 6:53:02 PM1/16/13
to
Hmm. That seems cleaner and easier to work with than constructing a command string for interpret.

/* rexx */
outer.0 = 3
outer.1 = 1
outer.2 = 2
outer.3 = 3
call subr outer.
exit
subr: nop
arg inner
do i = 1 to value(inner || '0')
say value(inner || 'i')
end
return

--

Donald Grinsell
State of Montana
406-444-2983
dgri...@mt.gov

"Hope is not a plan."
~ Gen. Peter Pace, USMC

Paul Gilmartin

unread,
Jan 16, 2013, 7:03:15 PM1/16/13
to
On 2013-01-16 16:18, Grinsell, Don wrote:
> How about something like this:
>
> /* rexx */
> outer.0 = 3
> outer.1 = 1
> outer.2 = 2
> outer.3 = 3
> do i = 0 to outer.0
> inner.i = outer.i
> end
> call subr inner.
> exit
> subr: procedure expose inner.
> do i = 1 to inner.0
> say inner.i
> end
> return
>
And what if the tails are not consecutive positive integers?

-- gil

Roberto Halais

unread,
Jan 16, 2013, 7:27:18 PM1/16/13
to
/* rexx */
st.1 = 1
st.3 = 3
st.0 = 2
stemvar = 'st.'
call c
exit 0
c: procedure expose (stemvar)
say stemvar
say stemvar||'1=' value(stemvar||'1')
say stemvar||'2=' value(stemvar||'2') /* does not have a value just for
test */
say stemvar||'3=' value(stemvar||'3')
say stemvar||'0=' value(stemvar||'0')
return

On Wed, Jan 16, 2013 at 5:42 PM, Steve Thompson <stho...@us.ibm.com>wrote:

--
"Men will never be free until the last king is strangled with the entrails
of the last priest." Denis Diderot

Ted MacNEIL

unread,
Jan 16, 2013, 7:34:11 PM1/16/13
to
It's not a matter of presumption.
As the quoted passage said, you CAN'T pass a stem as an argument to a function.
So, it's a matter of choice; you have none.
-
Ted MacNEIL
eama...@yahoo.ca
Twitter: @TedMacNEIL

-----Original Message-----
From: Steve Thompson <stho...@US.IBM.COM>
Sender: TSO REXX Discussion List <TSO-...@VM.MARIST.EDU>
Date: Wed, 16 Jan 2013 16:33:02
To: <TSO-...@VM.MARIST.EDU>
Reply-To: TSO REXX Discussion List <TSO-...@VM.MARIST.EDU>
Subject: Re: [TSO-REXX] How To Question -- passing all of a stem variable contents -- NOT homework

Paul Gilmartin

unread,
Jan 16, 2013, 8:19:36 PM1/16/13
to
On 2013-01-16 14:42, Steve Thompson wrote:
> I've been battling something for most of the day. Something that I kinda
> remember doing about 5 years ago, but I just can't recall how.
>
> Here is the issue.
>
> I have a mainline routine that will invoke an internal subroutine. One of
> the arguments passed to it is a stem variable. ...
>
This is pretty close to what Glenn (and others) suggested, but perhaps
more detail. It relies on Exposed variables rather than arguments, but
even those are pretty well encapsulated:

/* Rexx */ signal on novalue /* ----------------------
Doc: experiment with variable global compound names.
*/
say 'Defining compound members:'
ArgName = 'X.'; call P
ArgName = 'Y.'; call P

say
say 'Results of definition:'
say X.WOMBAT
say Y.WOMBAT
return

P: procedure expose SIGL ArgName ( ArgName )
say SIGL': ' value( ArgName'WOMBAT', 'P called from' SIGL 'for' ArgName )
return
/* ------------------------------ */

Prints:

Defining compound members:
5: X.WOMBAT
6: Y.WOMBAT

Results of definition:
P called from 5 for X.
P called from 6 for Y.

-- gil

Adrian Stern

unread,
Jan 17, 2013, 6:17:46 AM1/17/13
to
Since by now you will have heard from many of us that a stem variable cannot
be passed to a subroutine I would have thought your thought processes would
have questioned both the need for stem variables and the need for a
subroutine.

What I have used in the past has been a virtual file - allocated once and
written to instead of a stem and emptied in the subroutine. It's IO, yes but
IO to a virtual file is no real overhead if you have no better solution.

Sometimes a string will work well for you, like "jim=1 fred=3 joe=33" -
which can then be handled by using the words function and simple parsing.

Don't let your mind be fixed to a single approach - if you can't do it one
way there's always another.

-----Original Message-----
From: TSO REXX Discussion List [mailto:TSO-...@VM.MARIST.EDU] On Behalf Of
Steve Thompson
Sent: den 16 januari 2013 22:42
To: TSO-...@VM.MARIST.EDU
Subject: [TSO-REXX] How To Question -- passing all of a stem variable
contents -- NOT homework

Stocker, Herman

unread,
Jan 17, 2013, 8:59:58 AM1/17/13
to
HI,

Check out Willy Jensen's TSO REXX Global Variable function at:
http://www.wjensen.com/WJTECH/mypgm/mypgm.html
I think it will do every thing you need.

Regards,
Herman Stocker

It is impossible to make anything foolproof, because fools are so ingenious.
-- Robert Heinlein


-----Original Message-----
From: TSO REXX Discussion List [mailto:TSO-...@VM.MARIST.EDU] On Behalf Of Steve Thompson
Sent: Wednesday, January 16, 2013 4:42 PM
To: TSO-...@VM.MARIST.EDU
Subject: [TSO-REXX] How To Question -- passing all of a stem variable contents -- NOT homework

---

The sender believes that this E-mail and any attachments were free of any
virus, worm, Trojan horse, and/or malicious code when sent. This message and
its attachments could have been infected during transmission. By reading the
message and opening any attachments, the recipient accepts full
responsibility for taking protective and remedial action about viruses and
other defects. The sender's employer is not liable for any loss or damage
arising in any way from this message or its attachments.

---

Steve Thompson

unread,
Jan 17, 2013, 10:07:06 AM1/17/13
to
I thank you all for your various solutions. You might be surprised to
learn that I am migrating FROM a Java oriented tool to REXX. I do not get
to use assembler routines and the like, because this has to port as a
single REXX based PDS/PDSE. And it is a hybrid system, with part running
under ISPF the other in batch.

I find myself in the position of trying to do a function for function
migration/conversion and not line for line. But the OMVS side of
things....

I was looking for the simplest way of doing this, that uses the least CPU
cycles, since I do not want a TSO/ISPF user to get put in period 3/4 doing
the initial processing for driving the "batch" oriented processing. But I
need to balance that with simplicity.

So this is what I decided to do. All the variables that are being used for
holding certain data that must be massaged, will be numbered. This allows
the following:

x = FIX_DATA(1 "blanks asa")
:
:
:
FIX_DATA: NOP

PARSE UPPER ARG file_no remove_list

ADDRESS TSO

SELECT
WHEN file_no = 1 THEN DO
FIX_DATA. = p_list1.
END
WHEN file_no = 2 THEN DO
FIX_DATA. = p_list2.
END
WHEN file_no = 3 THEN DO
FIX_DATA. = p_list3.
END
:
:
[Lots of Logic]

SELECT
WHEN file_no = 1 THEN DO
p_list1. = FIX_DATA.
END
WHEN file_no = 2 THEN DO
p_list2. = FIX_DATA.
END
:
:


I am not afraid of using PROCEDURE EXPOSE. I already have functions of
that type in this initial driver. I am after simple things because I do
not know the skill levels of who will follow. And while I have been the
tool guy (automated analysis of dumps under IPCS) for a development group
for the past several years (while also doing development in HLASM), this
is a lot more fun. I'm having to remember things I had totally forgotten
from my years doing VM/REXX stuff.

And yes, I write lots of comments. I'm too old to remember what I wrote
and why for stuff six months ago!!

Hobart Spitz

unread,
Jan 17, 2013, 11:26:53 AM1/17/13
to
The brilliance of REXX is that you can pass a reference to a variable,
stem, subroutine or function just by putting the name in quotes, as you
would for symbol(), e.g. Use value() or interpret as needed:

Example 1 - Pass a Stem:

MyStem.0 = 0
call StemAppend "MyStem.", "The quick brown"
call StemAppend "MyStem.", "fox jumps over"
...
StemAppend:
arg StemName, NewValue
Tail = value(StemName"0") + 1
call value StemName || Tail, NewValue
call value StemName"0", Tail
return

Example 2 - Pass a function:

call Invoke "MyFunct", "a,b"
call Invoke "word", "'x y z', 2. 1
...
Invoke:
arg FunctName, ArgList
interpret "call" FunctName ArgList
if symbol("result") ="VAR" then
return result
return


Think of value() as an analog to the C/C++ * operator and the quoted name
as an analog to the C/C++ & operator. (Note, "analog" does not mean
equivalent.)

Think of interpret as a run-time macro analog.

I'll leave the determining applicability of passing by reference versus
passing by value to the reader.
--
OREXXMan

Grinsell, Don

unread,
Jan 17, 2013, 11:48:34 AM1/17/13
to
Steve,

I'm glad you found a solution that works. I enjoy these "how to" discussions because inevitably I discover better ways of doing things myself.

Regards to all.

--

Donald Grinsell
State of Montana
406-444-2983
dgri...@mt.gov

"When they kick out your front door, how you gonna come? With your hands on your head or on the trigger of your gun?"
~ The Clash

Thomas Berg

unread,
Jan 18, 2013, 4:51:22 AM1/18/13
to
I'm somewhat worried that you *may* have misunderstood something.
When you write "FIX_DATA. = p_list1." what do you want to happen ?

Consider this:

p_list. = 'A'
p_list.1 = 'B'
p_list.2 = 'C'

FIX_DATA. = p_list1.

/* This will result in:
FIX_DATA. = 'A'
FIX_DATA.1 = 'A'
FIX_DATA.2 = 'A'
*/

Just to be sure...



Regards
Thomas Berg
________________________________________________________________
Thomas Berg Specialist z/OS/IT Delivery SWEDBANK AB (Publ)

> -----Ursprungligt meddelande-----
> Från: TSO REXX Discussion List [mailto:TSO-...@VM.MARIST.EDU] För
> Steve Thompson
> Skickat: den 17 januari 2013 16:04
> Till: TSO-...@VM.MARIST.EDU
> Ämne: Re: [TSO-REXX] How To Question -- passing all of a stem variable
> contents -- NOT homework
>

Steve Thompson

unread,
Jan 18, 2013, 9:25:37 AM1/18/13
to
From: Thomas Berg <thoma...@SWEDBANK.SE>
Date: 01/18/2013 03:52 AM




I'm somewhat worried that you *may* have misunderstood something.
When you write "FIX_DATA. = p_list1." what do you want to happen ?

Consider this:

p_list. = 'A'
p_list.1 = 'B'
p_list.2 = 'C'

FIX_DATA. = p_list1.

/* This will result in:
FIX_DATA. = 'A'
FIX_DATA.1 = 'A'
FIX_DATA.2 = 'A'
*/

Just to be sure...
<SNIPPAGE>

I had expected the one stem to take on the values of the other stem. Since
that did not work, I fixed it with do loops.

There are days when I really wish I could just do assembly. Man I miss
DSECTs.

Paul Gilmartin

unread,
Jan 18, 2013, 10:32:13 AM1/18/13
to
On Jan 18, 2013, at 07:10, Steve Thompson wrote:

> From: Thomas Berg <thoma...@SWEDBANK.SE>
> Date: 01/18/2013 03:52 AM
>
> Consider this:
>
> p_list. = 'A'
> p_list.1 = 'B'
> p_list.2 = 'C'
>
> FIX_DATA. = p_list1.
>
> I had expected the one stem to take on the values of the other stem. Since
> that did not work, I fixed it with do loops.
>
How can you be certain that your loop accesses every member of
the compound? Suppose I extend Thomas's example:

p_list. = 'A'
p_list.1 = 'B'
p.list.MARSUPIAL = 'WOMBAT'
p_list.2 = 'C'

What does your loop do? How do you even code it?

-- gil

Steve Thompson

unread,
Jan 18, 2013, 10:53:19 AM1/18/13
to
From: Paul Gilmartin <PaulGB...@AIM.COM>
Date: 01/18/2013 09:34 AM


<SNIPPAGE>
How can you be certain that your loop accesses every member of
the compound? Suppose I extend Thomas's example:

p_list. = 'A'
p_list.1 = 'B'
p.list.MARSUPIAL = 'WOMBAT'
p_list.2 = 'C'

What does your loop do? How do you even code it?
<SNIPPAGE>

Shirley: you jest.

DO i=1 to a.0
b.i = a.i
END

Thankfully, you do not work on code that I deal with. So we don't have to
worry about your extensions that would break the whole EXEC.

Regards,
Steve Thompson

Thomas Berg

unread,
Jan 18, 2013, 10:57:48 AM1/18/13
to
Just for the record, the software REXXTOOLS have a function STEMCOPY that does what you want also.
(Somewhat related, there is the functions STEMPUSH and STEMPULL at cbttape.org. They let you use a stem that is created in another rexx than the current.)



Regards
Thomas Berg
________________________________________________________________
Thomas Berg Specialist z/OS/IT Delivery SWEDBANK AB (Publ)

Paul Gilmartin

unread,
Jan 18, 2013, 11:27:01 AM1/18/13
to
On Jan 18, 2013, at 08:57, Thomas Berg wrote:

> Just for the record, the software REXXTOOLS have a function STEMCOPY that does what you want also.
>
I bet I can break it.

What does it do with:

OLD. = 'Wrong!'
drop OLD.42
STEMCOPY( OLD., NEW. ) /* Whatever the syntax. */

say 'OLD.42 is' value( 'OLD.42' )
say 'NEW.42 is' value( 'NEW.42' )

???

-- gil

Grinsell, Don

unread,
Jan 18, 2013, 11:30:33 AM1/18/13
to
-----Original Message-----

How can you be certain that your loop accesses every member of the compound? Suppose I extend Thomas's example:

p_list. = 'A'
p_list.1 = 'B'
p.list.MARSUPIAL = 'WOMBAT'
p_list.2 = 'C'

What does your loop do? How do you even code it?

-- gil

Now that's just plain silly. I believe you have to assume that the stem has some sort of structure. Since the OP is in control of both the outer code and the subroutine, I think this wouldn't happen. That said, if somebody gave me gave me that particular structure, some remedial programming standards instruction would be in order.

--

Donald Grinsell
State of Montana
406-444-2983
dgri...@mt.gov

"Security has become the smokescreen for incompetent and robotic managers the world over."
~ Simon Davies, http://www.privacyinternational.org

Paul Gilmartin

unread,
Jan 18, 2013, 11:44:31 AM1/18/13
to
On Jan 18, 2013, at 08:52, Steve Thompson wrote:
>
> How can you be certain that your loop accesses every member of
> the compound? Suppose I extend Thomas's example:
>
> p_list. = 'A'
> p_list.1 = 'B'
> p.list.MARSUPIAL = 'WOMBAT'
> p_list.2 = 'C'
> ...
> Thankfully, you do not work on code that I deal with. So we don't have to
> worry about your extensions that would break the whole EXEC.
>
"[my] extensions"!? Nonsense; no extensions. RTFM (TRPL1). You
wrote that you wanted to be prepared for what future maintainers
might do. It seems that you're not prepared.

-- gil

Walter Pachl

unread,
Jan 18, 2013, 11:46:58 AM1/18/13
to
Without extra tools I usually use a list of tails
Zlist=''
Z=tail
Stem.z=data
Zlist=zlist translate(z,'_',' ')
Etc.
Do While zlist<>''
Parse Var zlist z zlist
Z=translate(z,' ','_')
Say z '->' stem.z
End
(Untested)
Regards
Walter

Ken MacKenzie

unread,
Jan 18, 2013, 11:54:33 AM1/18/13
to
There's also my RXVARS routine, discussed earlier this year. It can
return all variables or all variables whose names begin with a certain
string.

https://www.dropbox.com/s/ea4jp2wexvsxs3i/RXVARS-read_me.txt

https://www.dropbox.com/s/6a41tgt8zzy94x2/rxvars.xmi



From: Paul Gilmartin <PaulGB...@AIM.COM>
To: TSO-...@VM.MARIST.EDU,
Date: 18/01/2013 16:28
Subject: Re: [TSO-REXX] SV: [TSO-REXX] SV: [TSO-REXX] How To
Question -- passing all of a stem variable contents -- NOT homework

Paul Gilmartin

unread,
Jan 18, 2013, 11:57:30 AM1/18/13
to
On Jan 18, 2013, at 09:29, Grinsell, Don wrote:

> -----Original Message-----
>
> How can you be certain that your loop accesses every member of the compound? Suppose I extend Thomas's example:
>
> p_list. = 'A'
> p_list.1 = 'B'
> p.list.MARSUPIAL = 'WOMBAT'
> p_list.2 = 'C'
>
> What does your loop do? How do you even code it?
>
> -- gil
>
> Now that's just plain silly. I believe you have to assume that the stem has some sort of structure. Since the OP is in control of both the outer code and the subroutine, I think this wouldn't happen. That said, if somebody gave me gave me that particular structure, some remedial programming standards instruction would be in order.
>
"standards"!? How about the structure specified in:

Title: z/OS V1R12.0 TSO/E REXX Reference
Document Number: SA22-7790-09
2.4.3 Compound symbols

... The value of a tail can be any character string, including
the null string and strings containing blanks. For example:

taila='* ('
tailb=''
stem.taila=99
stem.tailb=stem.taila
say stem.tailb /* Displays: 99 */
/* But the following instruction would cause an error */
/* say stem.* ( */

It's an extraordinarily useful feature of Rexx and many other
languages (which tend to call the construct an "associative
array"). If any program manager who discourages its use where
appropriate, "some remedial programming standards instruction
would be in order."

I used the construct last week to process a list of file names
and identify the unique ones. How would you code that using
only positive integers as tails?

It's said, "You can code FORTRAN in any language." But why
would you do so.

-- gil

Adrian Stern

unread,
Jan 18, 2013, 12:23:52 PM1/18/13
to
But as has already been pointed out it must be impossible to copy stems
unless they are simple and numbered. In which case you don't need a stem
variable at all; you can do the same thing with a string which can be passed
to both internal and external procedures.

-----Original Message-----
From: TSO REXX Discussion List [mailto:TSO-...@VM.MARIST.EDU] On Behalf Of
Thomas Berg
Sent: den 18 januari 2013 16:57
To: TSO-...@VM.MARIST.EDU
Subject: [TSO-REXX] SV: [TSO-REXX] SV: [TSO-REXX] How To Question -- passing
all of a stem variable contents -- NOT homework

Adrian Stern

unread,
Jan 18, 2013, 12:26:30 PM1/18/13
to
Crap! I often use stems like hashes in other languages - this is quite
common behaviour

-----Original Message-----
From: TSO REXX Discussion List [mailto:TSO-...@VM.MARIST.EDU] On Behalf Of
Grinsell, Don
Sent: den 18 januari 2013 17:29
To: TSO-...@VM.MARIST.EDU
Subject: Re: [TSO-REXX] SV: [TSO-REXX] How To Question -- passing all of a
stem variable contents -- NOT homework

Adrian Stern

unread,
Jan 18, 2013, 12:29:11 PM1/18/13
to
Hear hear

-----Original Message-----
From: TSO REXX Discussion List [mailto:TSO-...@VM.MARIST.EDU] On Behalf Of
Paul Gilmartin
Sent: den 18 januari 2013 17:47
To: TSO-...@VM.MARIST.EDU
Subject: Re: [TSO-REXX] SV: [TSO-REXX] How To Question -- passing all of a
stem variable contents -- NOT homework

Jeff Byrum

unread,
Jan 18, 2013, 1:12:22 PM1/18/13
to
-----Original Message-----
From: TSO REXX Discussion List [mailto:TSO-...@VM.MARIST.EDU] On Behalf Of Paul Gilmartin
Sent: Friday, January 18, 2013 11:47 AM
To: TSO-...@VM.MARIST.EDU
Subject: Re: SV: [TSO-REXX] How To Question -- passing all of a stem variable contents -- NOT homework

<snippage>
>
> It's an extraordinarily useful feature of Rexx and many other languages (which
> tend to call the construct an "associative array"). If any program manager who
> discourages its use where appropriate, "some remedial struction would be in order."
>
> I used the construct last week to process a list of file names and identify the unique
> ones. How would you code that using only positive integers as tails?
>
> It's said, "You can code FORTRAN in any language." But why would you do so.
>
> -- gil
>

I couldn't agree more about the usefulness of strings as the tails for stem variables. It is a *very* powerful programming tool.

I have some stem variable structures that are simply numerically indexed, if that's what the application calls for. In other cases, as with Gil's routine to recognize only unique values, I use only strings as tails:

STR. = ''
Do while [something]
[get next string_value]
If STR.string_value = '' then Do
STR.string_value = 'Y'
Call Process_This_One
End
End

Certainly seems to me to be better than having to loop through the entire structure every time through the main loop.

But I very often "cross-reference" the structure, so that I can access it sequentially or associatively. For example:

STR. = ''; strx = 0
Do while [something]
[get next string_value]
strx = strx + 1
STR.strx = string_value /* index the value */
STR.string_value = strx /* cross-reference it */
End

This even allows associating two structures based on some common variable (like joining two DB2 tables over a common column). And if the absence of sequential access capability causes one anxiety, there's really no significant cost to always doing this, even if you don't currently need to ever loop through the structure using the numeric index.

If I had to go back to Assembler, the first thing I'd have to do is create a service that emulates stem variables in Rexx.

Vitonis, Tony

unread,
Jan 18, 2013, 1:32:09 PM1/18/13
to
I'm pretty sure the original poster was asking about copying the entire contents of one stem to another. There was no indication that the contents be structured in a particular way. I'm surprised to hear that your remedial programming instruction would teach folks to ignore legal edge cases. To my way of thinking, *that* is silly.

I think the CBT solution is for passing stems from one REXX exec to another in different source. There's probably a simpler (assembler) function-package technique for copying stems within a single source exec.

-----Original Message-----
From: Grinsell, Don

Now that's just plain silly. I believe you have to assume that the stem has some sort of structure. Since the OP is in control of both the outer code and the subroutine, I think this wouldn't happen. That said, if somebody gave me gave me that particular structure, some remedial programming standards instruction would be in order.

-----Original Message-----
From: Paul Gilmartin

How can you be certain that your loop accesses every member of the compound? Suppose I extend Thomas's example:

p_list. = 'A'
p_list.1 = 'B'
p.list.MARSUPIAL = 'WOMBAT'
p_list.2 = 'C'

What does your loop do? How do you even code it?

Robert Zenuk

unread,
Jan 18, 2013, 2:43:06 PM1/18/13
to
IF you are willing to download something... Ken MacKenzie's RXVARS would work great for this PLUS you get a great diagnostic tool to easily insert in code during debugging sessions...

Ken just resent the links a few hours ago.

Rob



-----Original Message-----
From: Vitonis, Tony <Tony.V...@CA.COM>
To: TSO-REXX <TSO-...@VM.MARIST.EDU>
Sent: Fri, Jan 18, 2013 11:30 am
Subject: Re: SV: [TSO-REXX] How To Question -- passing all of a stem variable contents -- NOT homework


I'm pretty sure the original poster was asking about copying the entire contents
f one stem to another. There was no indication that the contents be structured
n a particular way. I'm surprised to hear that your remedial programming
nstruction would teach folks to ignore legal edge cases. To my way of thinking,
that* is silly.
I think the CBT solution is for passing stems from one REXX exec to another in
ifferent source. There's probably a simpler (assembler) function-package
echnique for copying stems within a single source exec.
-----Original Message-----
rom: Grinsell, Don
Now that's just plain silly. I believe you have to assume that the stem has
ome sort of structure. Since the OP is in control of both the outer code and
he subroutine, I think this wouldn't happen. That said, if somebody gave me
ave me that particular structure, some remedial programming standards
nstruction would be in order.
-----Original Message-----
rom: Paul Gilmartin
How can you be certain that your loop accesses every member of the compound?
uppose I extend Thomas's example:
p_list. = 'A'
p_list.1 = 'B'
p.list.MARSUPIAL = 'WOMBAT'
p_list.2 = 'C'
What does your loop do? How do you even code it?
----------------------------------------------------------------------
or TSO-REXX subscribe / signoff / archive access instructions,

Don Williams

unread,
Jan 18, 2013, 4:27:48 PM1/18/13
to
I've used a stem as a lookup table:

text = 'Now is the time for all good men to come to the aid of their country
every good boy does fine'
count. = 0
list. = ""
list.0 = 0
do i = 1 to words(text)
word = word(text,i)
j=count.word+1
count.word=j
if j=1 then do
j=list.0+1
list.0=j
list.j=word
end
end
do i = 1 to list.0
word = list.i
say word "occurs" count.word "times"
end

-----Original Message-----
From: TSO REXX Discussion List [mailto:TSO-...@VM.MARIST.EDU] On Behalf Of
Steve Thompson
Sent: Friday, January 18, 2013 10:52 AM
To: TSO-...@VM.MARIST.EDU
Subject: Re: [TSO-REXX] SV: [TSO-REXX] How To Question -- passing all of a
stem variable contents -- NOT homework

Glenn Knickerbocker

unread,
Jan 18, 2013, 7:05:00 PM1/18/13
to
On 17 Jan 2013 07:07:06 -0800, Steve Thompson wrote:
> WHEN file_no = 1 THEN DO
> FIX_DATA. = p_list1.
> END

I don't think that's going to get you any closer. That still assigns
only the default value, not the whole stem.

The more usual way to do this kind of thing is to use "substems."
Instead of a separate stem for each list, put them all into one stem, and
have the first segment of the tail identify each list. Instead of
p_list1.something and p_list2.whatever, you could use p_list.1.something
and p_list.2.whatever. Then you just expose the whole P_LIST. stem in
your routine, and pass the number of the list in the argument:

Call Fix_Data 1, 'blanks asa'

...

Fix_Data: Procedure Expose p_list.
Arg fixlist, remove_list
If WordPos(p_list.fixlist.1, remove_list) > 0 Then /* for instance */

If you wanted names rather than numbers for the lists, a convention some
people find useful is to start them with a digit so that they're not
valid variable names. Then you can use them as symbols without having to
worry about putting them in quotes or into a variable:

p_list.0color.1 = 'blue'
p_list.0shape.1 = 'pyramid'

ŹR "I love Blip just because it's the absolute opposite of fun"
http://users.bestweb.net/~notr/travelog/19990710.html --Kibo

Paul Gilmartin

unread,
Jan 19, 2013, 10:34:56 AM1/19/13
to
On Jan 18, 2013, at 17:04, Glenn Knickerbocker wrote:
>
> If you wanted names rather than numbers for the lists, a convention some
> people find useful is to start them with a digit so that they're not
> valid variable names. Then you can use them as symbols without having to
> worry about putting them in quotes or into a variable:
>
> p_list.0color.1 = 'blue'
> p_list.0shape.1 = 'pyramid'
>
Of course, quotes alone don't help because expressions are not allowed
in compound tails. For example:

p_list.'color'.1 = 'blue'

I consider this a grievous deficiency of Rexx. Others argue that it
makes recognition of symbols and assignments easier, whether by the
processor or by the programmer/reviewer.

-- gil

Bob Bridges

unread,
Jan 19, 2013, 10:42:56 AM1/19/13
to
Am I missing something? I agreed with all the others who said "yeah, you
can't pass a stem" until Glenn Knickerbocker and Roberto Halais pointed out
in the REXX manual how it's done. I'd completely forgotten that
possibility. But I wonder how many people noticed those three posts,
because the conversation went merrily on about alternative methods (which
has been an interesting enough conversation in its own right). I'm not
picking on Adrian; others seemed to have missed it too.

---
Bob Bridges
rhb...@attglobal.net, cell 336 382-7313
bbridge...@foodlion.com, 704 310-4526

/* With the government essentially shut down, it became necessary to
furlough all "non-essential" workers; this effort required the formation of
an Emergency Task Force To Determine Which Workers Are Non-Essential, which
within weeks had become a permanent federal agency with a staff of 278 000
and a budget of $13.7 billion. -Dave Barry, December 29, 1996 */

-----Original Message-----
From: Adrian Stern
Sent: Friday, January 18, 2013 12:20

But as has already been pointed out it must be impossible to copy stems
unless they are simple and numbered. In which case you don't need a stem
variable at all; you can do the same thing with a string which can be passed
to both internal and external procedures.

-----Original Message-----
From: Thomas Berg
Sent: den 18 januari 2013 16:57

Just for the record, the software REXXTOOLS have a function STEMCOPY that
does what you want also.

(Somewhat related, there is the functions STEMPUSH and STEMPULL at
cbttape.org. They let you use a stem that is created in another rexx than
the current.)

Paul Gilmartin

unread,
Jan 19, 2013, 11:04:43 AM1/19/13
to
On Jan 19, 2013, at 08:42, Bob Bridges wrote:

> Am I missing something? I agreed with all the others who said "yeah, you
> can't pass a stem" until Glenn Knickerbocker and Roberto Halais pointed out
> in the REXX manual how it's done. I'd completely forgotten that
> possibility. But I wonder how many people noticed those three posts,
> because the conversation went merrily on about alternative methods (which
> has been an interesting enough conversation in its own right). I'm not
> picking on Adrian; others seemed to have missed it too.
>
Their techniques work; they're certainly not the equivalent of
facilities available in other languages where the actual
parameter is associated with the name of the formal parameter
with no syntactic overburden such as "VALUE( 'name', expression)
or introducing another tail component to make it work.

C falls somewhat short in this respect. Rather than supporting
arguments passed by reference it supports only pointers passed
by value. Each reference to such a formal parmeter must be
preceded by '*' to access the actual value. FORTRAN and Pascal
do better: the formal parameter appears as a local variable name,
not pointer-to-something.

-- gil

Bob Bridges

unread,
Jan 19, 2013, 11:08:30 AM1/19/13
to
I used to grieve over this as well, Paul, but now I'm inclined to think the
"deficiency" makes it not just easier to parse, it makes it POSSIBLE. If
expressions of any kind were allowed in stem tokens, could the interpreter
be sure what was intended? Consider this common example:

nstem.count=nstem.count+1

If REXX were to allow expressions to be embedded in stem tokens, how could
the interpreter (or I, for that matter) know what that statement meant?

nstem.count=(nstem.count)+1 /* the only possible meaning currently */
nstem.count=nstem.(count+1) /* an alternate meaning */

...or, if you want to get really ugly:

nstem.(count=nstem.(count+1)) /* ok, I said it was ugly */

If you argue that simple string literals are an easy enough exception, I'm
tempted to agree. But then, I've never tried to write a full language
interpreter; maybe if I had, I'd know that even this exception causes
insoluable problems.
/* Winning isn't everything, but then losing is nothing. */

-----Original Message-----
From: Paul Gilmartin
Sent: Saturday, January 19, 2013 10:34

Of course, quotes alone don't help because expressions are not allowed
in compound tails. For example:

p_list.'color'.1 = 'blue'

I consider this a grievous deficiency of Rexx. Others argue that it
makes recognition of symbols and assignments easier, whether by the
processor or by the programmer/reviewer.

--- On Jan 18, 2013, at 17:04, Glenn Knickerbocker wrote:
> If you wanted names rather than numbers for the lists, a convention some
> people find useful is to start them with a digit so that they're not
> valid variable names. Then you can use them as symbols without having to
> worry about putting them in quotes or into a variable:
>
> p_list.0color.1 = 'blue'
> p_list.0shape.1 = 'pyramid'

Paul Gilmartin

unread,
Jan 19, 2013, 11:25:26 AM1/19/13
to
On Jan 19, 2013, at 09:06, Bob Bridges wrote:
>
> Consider this common example:
>
> nstem.count=nstem.count+1
>
> If REXX were to allow expressions to be embedded in stem tokens, how could
> the interpreter (or I, for that matter) know what that statement meant?
>
> nstem.count=(nstem.count)+1 /* the only possible meaning currently */
> nstem.count=nstem.(count+1) /* an alternate meaning */
>
> ...or, if you want to get really ugly:
>
> nstem.(count=nstem.(count+1)) /* ok, I said it was ugly */
>
> If you argue that simple string literals are an easy enough exception, I'm
> tempted to agree. But then, I've never tried to write a full language
> interpreter; maybe if I had, I'd know that even this exception causes
> insoluable problems.
>
The problem arises _only_ because function names are allowed to
end with a period. Your example is a function call:

nstem.(count=nstem.(count+1)) /* ok, I said it was ugly */

to, for example:

nstem.:
say arg( 1 )
return

if the ".(" sequence were always taken as introducing an expression
used as a compound tail, this restriction could vanish. Or a new
symbol could be introduced to the syntax. This is hardly an unsolvable
problem. Other languages such as C and awk both accept and handle
intuitively such as:

nstem[ count == nstem[ count + 1 ] ]

the nightmare of EBCDIC code pages makes the Rexx developers intensly
averse to extending the character set in such fashion.

-- gil

Bob Bridges

unread,
Jan 20, 2013, 10:09:59 AM1/20/13
to
Paul, this is getting complicated. I can't tell whether you mistook my
meaning, or understood it just fine and your answer is relevant even though
it took a twist I didn't expect. Let me try again, and we'll see: When I
inserted parens in my examples, last time, I didn't mean them literally. In
fact I started out deliberately to use square brackets, to make it clear
that I was talking about precedence of handling rather than actual parens in
the REXX code. Let's express it this way and see whether your reply changes
(and if it doesn't maybe I'll understand it better the second time around:

nstem.count=nstem.count+1 /* example */

If REXX were to allow expressions to be embedded in stem tokens, how could
the interpreter (or I, for that matter) know what that statement meant?
Let's say count=3, nstem.3=100 and nstem.4=200; as REXX is defined now this
statement means

v=nstem.count /* v=nstem.3, that is, v=100 */
v=v+1 /* v=101 */
nstem.count=v /* nstem.3=101 */

But if expressions are allowed in stem tokens, it might also mean this:

v=count+1 /* v=4 */
nstem.count=nstem.v /* nstem.3 = nstem.4, ie nstem.3=200 */

...or, if you want to get really ugly:

v=count+1 /* v=4 */
if count=nstem.v, /* if 3=nstem.4, ie if 3=200 */
then v=1
else v=0
nstem.v /* execute the command in nstem.0 or nstem.1 */

Yeah, I understand better now; I should not have used parens. In the last
example, count+1 is evaluated first so the statement becomes
"nstem.count=nstem.4", or nstem.count=200. Then "count=200" is evaluated,
ie "3=200", which is false or 0. So the command in nstem.0 is executed.

It's a silly example, of course. My point is just that if we're to allow
expressions inside stem tokens, doesn't that open the door to an impossible
situation?
/* My aunt has rather selfishly suspended her production of chocolate cake
because of the whole "broken hip" thing, leaving me to try to find a
worthwhile substitute....I purchased a box with a picture of a cake on it,
but inside were all these so-called "ingredients" that, once I'd mixed them
and baked them and put out the flames, tasted suspiciously like one of my
mother's chocolate hockey pucks. -Bruce Cameron */

-----Original Message-----
From: Paul Gilmartin
Sent: Saturday, January 19, 2013 11:25

The problem arises _only_ because function names are allowed to
end with a period. Your example is a function call:

nstem.(count=nstem.(count+1)) /* ok, I said it was ugly */

to, for example:

nstem.:
say arg( 1 )
return

if the ".(" sequence were always taken as introducing an expression
used as a compound tail, this restriction could vanish. Or a new
symbol could be introduced to the syntax. This is hardly an unsolvable
problem. Other languages such as C and awk both accept and handle
intuitively such as:

nstem[ count == nstem[ count + 1 ] ]

the nightmare of EBCDIC code pages makes the Rexx developers intensly
averse to extending the character set in such fashion.

--- On Jan 19, 2013, at 09:06, Bob Bridges wrote:
> Consider this common example:
>
> nstem.count=nstem.count+1
>
> If REXX were to allow expressions to be embedded in stem tokens, how could
> the interpreter (or I, for that matter) know what that statement meant?
>
> nstem.count=(nstem.count)+1 /* the only possible meaning currently */
> nstem.count=nstem.(count+1) /* an alternate meaning */
>
> ...or, if you want to get really ugly:
>
> nstem.(count=nstem.(count+1)) /* ok, I said it was ugly */
>
> If you argue that simple string literals are an easy enough exception, I'm
> tempted to agree. But then, I've never tried to write a full language
> interpreter; maybe if I had, I'd know that even this exception causes
> insoluable problems.

Paul Gilmartin

unread,
Jan 20, 2013, 12:05:18 PM1/20/13
to
On Jan 20, 2013, at 08:09, Bob Bridges wrote:

> Paul, this is getting complicated. I can't tell whether you mistook my
> meaning, or understood it just fine and your answer is relevant even though
> it took a twist I didn't expect. Let me try again, and we'll see: When I
> inserted parens in my examples, last time, I didn't mean them literally. In
> fact I started out deliberately to use square brackets, to make it clear
> that I was talking about precedence of handling rather than actual parens in
> the REXX code. Let's express it this way and see whether your reply changes
> (and if it doesn't maybe I'll understand it better the second time around:
>
I understood that, which is why I imagined adding a pair
of new symbols to the grammar: '[' ... ']', which _always_
serve to denote and delimit a compound tail element.

> nstem.count=nstem.count+1 /* example */
>
... which might be written either that way, or superfluously:

nstem.[count]=nstem.[count]+1

> If REXX were to allow expressions to be embedded in stem tokens, how could
> the interpreter (or I, for that matter) know what that statement meant?
> Let's say count=3, nstem.3=100 and nstem.4=200; as REXX is defined now this
> statement means
>
> v=nstem.count /* v=nstem.3, that is, v=100 */
> v=v+1 /* v=101 */
> nstem.count=v /* nstem.3=101 */
>
> But if expressions are allowed in stem tokens, it might also mean this:
>
> v=count+1 /* v=4 */
> nstem.count=nstem.v /* nstem.3 = nstem.4, ie nstem.3=200 */
>
But that would be written, instead, as:

nstem.count=nstem.[count+1]

> ...or, if you want to get really ugly:
>
> v=count+1 /* v=4 */
> if count=nstem.v, /* if 3=nstem.4, ie if 3=200 */
> then v=1
> else v=0
> nstem.v /* execute the command in nstem.0 or nstem.1 */
>
and that as:

nstem.[count=nstem.count+1]

Or, even:

nstem.[count=nstem.count]+1 /* execute the command which is
gotten by adding 1 to either nstem.0 or nstem.1 */

> It's a silly example, of course. My point is just that if we're to allow
> expressions inside stem tokens, doesn't that open the door to an impossible
> situation?
>
Without additional syntax, correct. Parens don't suffice only
because with the current specification this:

nstem.(count=nstem.count+1)

... means call function "nstem." with argument "count=nstem.count+1"
and execute the result as a function.

I have sufficient experience with Pascal as a compiler developer,
and with C and awk as a user to know that allowing expressions in
array subscripts introduces no unmanageable problems as long as
the syntax is unambiguous. Rexx compound variables are sufficiently
similar to awk's associative arrays that the problem should be
solvable.

-- gil

Glenn Knickerbocker

unread,
Jan 20, 2013, 2:59:40 PM1/20/13
to
On 20 Jan 2013 09:05:18 -0800, Paul Gilmartin wrote:
>I understood that, which is why I imagined adding a pair
>of new symbols to the grammar: '[' ... ']', which _always_
>serve to denote and delimit a compound tail element.

And, in fact, that's exactly what Object Rexx did.

¬R / Darla: Leftovers aren't the mark of a man. \ www.bestweb.net/~notr
Andrew Reid: Actually, they are, because that's how men's shirts button.

Paul Gilmartin

unread,
Jan 20, 2013, 6:10:02 PM1/20/13
to
On Jan 20, 2013, at 12:59, Glenn Knickerbocker wrote:

> On 20 Jan 2013 09:05:18 -0800, Paul Gilmartin wrote:
>> I understood that, which is why I imagined adding a pair
>> of new symbols to the grammar: '[' ... ']', which _always_
>> serve to denote and delimit a compound tail element.
>
> And, in fact, that's exactly what Object Rexx did.
>
And it causes the processor no grief in determining the
programmer's intent (which seems to be the recent focus
of this thread)?

Of course '[' and ']' are repugnant to MVS and CMS programmers
because they aren't stable EBCDIC characters.

-- gil

Leslie Turriff

unread,
Jan 20, 2013, 7:26:28 PM1/20/13
to
You might like to take a look at Open Object Rexx (ooRexx)
<http://www.oorexx.org/>, which has this capability with stems.

Leslie

John McKown

unread,
Jan 20, 2013, 7:36:00 PM1/20/13
to
Too bad that a version for z/OS, both TSO and UNIX, are not generally
available. Or are they?

Walter Pachl

unread,
Jan 21, 2013, 12:46:55 AM1/21/13
to
Not much help on TSO I should think
Walter

Höglund Lars

unread,
Jan 21, 2013, 2:49:40 AM1/21/13
to
Example of STEMPUSH and PULL

/* REXX STEMTST1 */
token = STEMTST2() /* call the creator of STEM */
rcode = STEMPULL(token) /* Fetch data from stack */
do ix = 1 to STEMTST2.0
say STEMTST2.ix
end /*do ix = 1 to STEMTST2.0*/
exit



/* REXX STEMTST2 */
STEMTST2. = ''
do ix = 1 to 5
STEMTST2.ix = ix
end /*do ix = 1 to 5*/
drop STEMTST2.2
STEMTST2.0 = 5
token = STEMPUSH('STEMTST2.') /* Put stem-result on stack */
return token

//Lasse


-----Ursprungligt meddelande-----
Från: TSO REXX Discussion List [mailto:TSO-...@VM.MARIST.EDU] För Thomas Berg
Skickat: den 18 januari 2013 16:59
Till: TSO-...@VM.MARIST.EDU
Ämne: [TSO-REXX] SV: [TSO-REXX] SV: [TSO-REXX] How To Question -- passing all of a stem variable contents -- NOT homework

Just for the record, the software REXXTOOLS have a function STEMCOPY that does what you want also.
(Somewhat related, there is the functions STEMPUSH and STEMPULL at cbttape.org. They let you use a stem that is created in another rexx than the current.)



Regards
Thomas Berg
________________________________________________________________
Thomas Berg Specialist z/OS/IT Delivery SWEDBANK AB (Publ)

Paul Gilmartin

unread,
Jan 22, 2013, 7:41:48 AM1/22/13
to
On Jan 18, 2013, at 08:57, Thomas Berg wrote:

> Just for the record, the software REXXTOOLS have a function STEMCOPY that does what you want also.
> (Somewhat related, there is the functions STEMPUSH and STEMPULL at cbttape.org. They let you use a stem that is created in another rexx than the current.)
>
Does either of these deal well with:

o Sparse compounds (X.1 = "First"; X.1000000 = "Last")

o Non-numeric tails (including null string)

o Universal assignment (Stem. = 'value')

o Dropped members

All the examples in CBTTAPE 411 show only positive integer tails.

And, of course, the back-and-forth copy is undesirable overhead for
a large compound in a tight loop.

-- gil

Don Imbriale

unread,
Jan 22, 2013, 8:29:59 AM1/22/13
to
Although these other methods are possible, I suspect that most use of stems
involves non-sparse, consecutive, positive integer tails. The STEMPUSH and
STEMPULL functions are tools to handle these; if those other specialized
cases are used, then other specialized tools would be needed. However
desirable it may be to have a single tool that does everything, sometimes
the effort to provide such a tool just isn't worth it. I, for one,
appreciate the usefulness of the STEMPULL and STEMPUSH tools and understand
under what circumstances they can be used effectively.

- Don Imbriale

Paul Gilmartin

unread,
Jan 22, 2013, 9:49:29 AM1/22/13
to
On Jan 22, 2013, at 06:29, Don Imbriale wrote:

> Although these other methods are possible, I suspect that most use of stems
> involves non-sparse, consecutive, positive integer tails. The STEMPUSH and
> STEMPULL functions are tools to handle these; if those other specialized
> cases are used, then other specialized tools would be needed. However
> desirable it may be to have a single tool that does everything, sometimes
> the effort to provide such a tool just isn't worth it. I, for one,
> appreciate the usefulness of the STEMPULL and STEMPUSH tools and understand
> under what circumstances they can be used effectively.
>
The preponderance of my use of stems is for associative arrays
because they're so useful for that purpose. So I see it differently.
At very least, STEMPUSH/STEMPULL/STEMCOPY ought to return error
status on being passed a stem argument beyond its capabilities.
(But this may be difficult to detect, even with the assembler API.)

Rexx is unique among languages in my experience by supporting
assiciative arrays, but providing no way within the language
to enumerate the members of one.

Don Williams

unread,
Jan 22, 2013, 10:37:48 PM1/22/13
to
Many years ago, about an hour after I discovered stems, I wanted tail
expressions similar to subscript expressions in other languages:

stem.(expression_1)
stem.(expression_1).(expression_2)
...
stem.(expression_1).(expression_2)....(expression_n)

I felt that the parenthesis would prevent any syntaxic ambiguities.

p_list.('color').1 = 'blue'

It would also allow nesting stems in tails:

p_list.(color.1) = 'blue'

Don

-----Original Message-----
From: TSO REXX Discussion List [mailto:TSO-...@VM.MARIST.EDU] On Behalf Of
Paul Gilmartin
Sent: Saturday, January 19, 2013 10:34 AM
To: TSO-...@VM.MARIST.EDU
Subject: Re: [TSO-REXX] How To Question -- passing all of a stem variable
contents -- NOT homework

Thomas Berg

unread,
Jan 23, 2013, 3:45:06 AM1/23/13
to
> -----Ursprungligt meddelande-----
> Fr�n: TSO REXX Discussion List [mailto:TSO-...@VM.MARIST.EDU] F�r Paul
> Gilmartin
> Skickat: den 22 januari 2013 13:40
> Till: TSO-...@VM.MARIST.EDU
> �mne: Re: [TSO-REXX] How To Question -- passing all of a stem variable
> contents -- NOT homework
>
> On Jan 18, 2013, at 08:57, Thomas Berg wrote:
>
> > Just for the record, the software REXXTOOLS have a function STEMCOPY
> that does what you want also.
> > (Somewhat related, there is the functions STEMPUSH and STEMPULL at
> > cbttape.org. They let you use a stem that is created in another rexx
> > than the current.)
> >
> Does either of these deal well with:
>
> o Sparse compounds (X.1 = "First"; X.1000000 = "Last")
>
> o Non-numeric tails (including null string)
>
> o Universal assignment (Stem. = 'value')
>
> o Dropped members
>

AFAICS from the asm source, they (STEMPUSH, STEMPULL) loops through *all* variables to match the given stems/prefixes.

From the description on the source:
* Delivered directly from Rob Scott 2012-10-11!
* =============================================
*
* Name : STEMPUSH
*
* Function : This program provides an external REXX function
* to place REXX variables onto a stack that
* can be passed to another REXX exec running within
* the same address space.
*
* The 'stack' is in fact a dataspace whose STOKEN
* is passed back in EBCDIC form to the REXX result
* value. This 'token' can then be used in any
* other REXX as an argument to the STEMPULL
* function to retrieve the contents of the
* dataspace.
*
* Syntax : token = STEMPUSH(maxblk,'var1',,'varn')
*
* where : token - 16 byte token that identifies
* the 'stack' that the stems have
* been 'pushed' onto. If this
* is set to '0', then the
* function has failed.
*
* maxblk - Optional keyword that specifies
* the size of the 'stack'. The
* format is 'MAXBLOCKS=nnnnn'
* where 'nnnnn' is the size of
* 'stack' in 4K blocks.
* The minimum value is 10.
* The maximum value is 99999.
* The default value is 4000.
*
* varn - The variable(s) that are to be
* pushed onto the 'stack'. The
* variable names MUST be enclosed
* in quotes.
* There are three accepted forms
* (1) A single variable name.
* (2) A stem name (last char MUST
* be a dot). The entire stem
* array will be copied.
* (3) Generic name (last char
* MUST be '*'). Any variable
* whose name matches will be
* copied.



Regards
Thomas Berg
________________________________________________________________
Thomas Berg Specialist z/OS/IT Delivery SWEDBANK AB (Publ)

Phil Smith III

unread,
Jan 23, 2013, 7:20:21 AM1/23/13
to
Paul Gilmartin wrote:
>Does either of these deal well with:

>o Sparse compounds (X.1 = "First"; X.1000000 = "Last")

>o Non-numeric tails (including null string)

>o Universal assignment (Stem. = 'value')

>o Dropped members

I don't know about the specific implementation mentioned, but the Rexx
variable interface has a "get me the next one for this stem", so the first
two should be handled. I *think* the third one comes up too.

The last one only matters if there's a universal assignment active, and I
*think* it's also handled, but can't swear to it.

Phil Smith III

unread,
Jan 24, 2013, 7:55:20 AM1/24/13
to
Don Williams <don...@GMAIL.COM> wrote:
>I have long thought REXX should have a built-in feature to enumerate them.

OORexx does -- DO OVER. But IBM lost interest in "classic" Rexx before it
made it there, alas.

...phsiii

Paul Gilmartin

unread,
Jan 24, 2013, 8:10:32 AM1/24/13
to
On Jan 24, 2013, at 05:53, Phil Smith III wrote:

> Don Williams <don...@GMAIL.COM> wrote:
>> I have long thought REXX should have a built-in feature to enumerate them.
>
> OORexx does -- DO OVER. But IBM lost interest in "classic" Rexx before it
> made it there, alas.
>
How does it deal with the universal assignment followed by
individual DROPs? E.g.:

stem. = 'Everything"
drop stem.42

... not important for many purposes, but essential if you want to
copy a compound variable. Does it have a "copy compound" function?

Does OORexx provide arguments passed by reference?

-- gil

Glenn Knickerbocker

unread,
Jan 25, 2013, 11:02:46 AM1/25/13
to
On 24 Jan 2013 05:10:32 -0800, gil wrote:
>On Jan 24, 2013, at 05:53, Phil Smith III wrote:
>> Don Williams <don...@GMAIL.COM> wrote:
>>> I have long thought REXX should have a built-in feature to enumerate them.
>> OORexx does -- DO OVER.
>How does it deal with the universal assignment followed by
>individual DROPs? E.g.:
>
> stem. = 'Everything"
> drop stem.42

Magically--stem.42 seems to exist and not exist at the same time.
Symbol('STEM.42') returns 'LIT' and stem.[42] returns the default value,
as you'd expect. At the same time, stem.~hasindex(42) returns 0 and
stem.~allindexes returns an empty array, as if you'd never referenced it
at all.

>Does OORexx provide arguments passed by reference?

Yes, BUT! It provides the USE ARG instruction to to create references to
objects passed in the argument, but, as in many (all?) OO languages,
string objects are immutable and replaced on assignment, so the called
routine won't manipulate the contents of string variables in the caller.
So it'll work fine when you try it out by passing references to stem
objects, but you'll be confused and frustrated the first time you try to
pass a string by reference.

It's simple to create a class that contains a single string value, but
it's awkward to use because the = sign is always parsed as an operator
rather than a method name. Even if you create an '=' method, x='asdf'
will always assign a new string object to X rather than changing the
value of the container object. The simplest way around this is to use
the special name "[]" or "[]=" for assignment: x['asdf'] or x[]='asdf'

ŹR "I love Blip just because it's the absolute opposite of fun"
http://users.bestweb.net/~notr/travelog/19990710.html --Kibo

Bob Bridges

unread,
Jan 25, 2013, 5:50:42 PM1/25/13
to
You guys are making me hungry. I have GOT to get me a copy of OORexx. The
thought of having REXX string-parsing functions and stem variables AND the
ability to write classes, combined in one language, just sets me drooling.

Hey, wait a minute - is OORexx a compiler or an interpreter? Could I use it
to write a COM object that I can then turn around and use in VBS?
/* The well-meaning contention that all ideas have equal merit seems to me
little different from the disastrous contention that no ideas have any
merit. -Carl Sagan, from "Broca's Brain" */

-----Original Message-----
From: Glenn Knickerbocker
Sent: Friday, January 25, 2013 11:02

Yes, BUT! It provides the USE ARG instruction to to create references to
objects passed in the argument, but, as in many (all?) OO languages,
string objects are immutable and replaced on assignment, so the called
routine won't manipulate the contents of string variables in the caller.
So it'll work fine when you try it out by passing references to stem
objects, but you'll be confused and frustrated the first time you try to
pass a string by reference.

It's simple to create a class that contains a single string value, but
it's awkward to use because the = sign is always parsed as an operator
rather than a method name. Even if you create an '=' method, x='asdf'
will always assign a new string object to X rather than changing the
value of the container object. The simplest way around this is to use
the special name "[]" or "[]=" for assignment: x['asdf'] or x[]='asdf'

>--- On Jan 24, 2013, at 05:53, Phil Smith III wrote:
>> OORexx does -- DO OVER.

John McKown

unread,
Jan 25, 2013, 8:22:25 PM1/25/13
to
Interpreted. NetREXXcompiles to Java byte code (.class files) so will
interoperate with other JVM languages.
0 new messages