Code Comments

Programming Forum and web based access to our favorite programming groups.
For Programmers: Free Programming Magazines | New: Database administration forum
Registration is free! Edit your profileCalendarFind other membersFrequently Asked QuestionsSearch -> 
Post New Thread











Thread
Author

Re: My First C# (warning - long post)
William M. Klein<wmklein@nospam.netcom.com> 02/08/07 8:41 PM >>>
>WithOUT getting into the whole procedural vs OO debate,  the recent posts
in
>this thread really DO remind me of "highly-modularized" procedural code
that was
>becoming semi-common in the late 80's and 90's (before COBOL lost its
>"glitter").  In several IBM mainframe shops (which is what I knew best in
those
>days), the use of dynamic CALL statements with sub-programs with procedure

>division  that "could print on a single page of laser paper" gained a
certain
>(good and bad) reputation.  OBVIOUSLY, the same goal of "encapsulating"
logic
>(and reuse of existing logic) was behind this.
>
>It may or may not have anything to do with why OO hasn't caught on with IBM

>mainframers, but the "highly-modularized" approach turned out to be a VERY
bad
>decision for some shops that were early implementors of IBM's LE (and, yes,
I
>still think it is similar to .NET CLR).  In early IBM LE environments, the

>overhead for doing "dynamic CALL" statements in COBOL was HORRENDOUS
(especially
>between old and new programs).  Therefore, these "highly modularized"
>applications came to screaming halts in actual mainframe production
>environments.  No change to code, just to run-times. (FYI, this has
improved in
>recent years.  See LE "XPLINK" for example)
>
>This may (or may not) have anything to do with why mainframers are
"hesitant" to
>move to many classes with small method applications.
>
>(Just my $.02)

I am still a fan of 'shared subroutines', though with some caveats.
Performance is not one of them, though.  I've never done any empirical
testing, but I've never noticed much in the way of performance degradation
when using them.

In any case, my biggest problem with using them is lack of flexibility when
"extending" them.  Let me give a real world example...

We have a subroutine called TXND.  It's goal is to take in "transaction
data" from a database and return a formatted transaction description.

01  TXND-SUBROUTINE                  PIC X(8)  VALUE 'TXND'.
01  TXND-LINKAGE-AREA.

05 TXND-PASSED-DATA.
10  TXND-CALLER-ID            PIC X(8).
10  TXND-CURRENT-SUBROUTINE   PIC X(12).
10  TXND-COMPRESS-LINE-SW     PIC X.
88  TXND-COMPRESS-LINES             VALUE  'Y'.
10  TXND-1LOC-DESC-SW         PIC X.
88  1LOC-DESC-WANTED                VALUE  'Y'.
10  TXND-MSTR-SEGMENT         PIC X(1500).
10  TXND-TRAN-SEGMENT         PIC X(50).
10  TXND-DESC-SEGMENT         PIC X(55).

05 TXND-RETURNED-DATA.
10  TXND-SHORT-DESC           PIC X(10).
10  TXND-LONG-DESC-1          PIC X(75).
10  TXND-LONG-DESC-2          PIC X(75).
10  TXND-LONG-DESC-3          PIC X(75).
10  TXND-SHORT-DESC-NUM       PIC 9(9).
10  TXND-CONVERTED-CHECK-SW   PIC X.
88  TXND-CONVERTED-CHECK            VALUE  'Y'.
10  TXND-ICM-TRAN-TYPE        PIC X(10).
10  FILLER                    PIC X(50).


PROCEDURE DIVISION.
*   after retreiving the "master segment", a "transaction segment" and a
"transaction 'description' segment" from the database.
*   (the transaction description segment is really just an extension of the
transaction segment with additional information that is needed for some, but
not all, transactions)
MOVE DMDMSTR                   TO TXND-MSTR-SEGMENT
MOVE DMDTRAN                   TO TXND-TRAN-SEGMENT
MOVE TRANS-DESCRIPTION-SEGMENT TO TXND-DESC-SEGMENT
MOVE 'CICSDD11'                TO TXND-CALLER-ID
MOVE 'N'                       TO TXND-COMPRESS-LINE-SW
MOVE 'N'                       TO TXND-CONVERTED-CHECK-SW
CALL TXND-SUBROUTINE USING TXND-LINKAGE-AREA

Originally when this subroutine was designed the 05 level TXND-RETURNED-DATA
did not include the TXND-CONVERTED-CHECK-SW and TXND-ICM-TRAN-TYPE fields.
When these were added later it required a recompile of every program that
called this subroutine, even if those programs did not care about the new
fields.

Obviously this is the reason for the now 50 bytes of filler.  But of course
50 bytes is just a wild guess as to what may be needed in the future.

With OO it's much more dynamic, in that the invoked class creates the
storage, rather than the invoking program, so there is (I believe!) no need
for silly things like filler in anticipation of future needs.

Now I didn't write the TXND routine, but I imagine that if I were to rewrite
it I might do something like this...

***BEGIN TXNDLINK COPYBOOK***
01 TXND-PASSED-DATA.
05  TXND-PASSED-DATA-LEN      COMP PIC S9(4).
05  TXND-CALLER-ID            PIC X(8).
05  TXND-CURRENT-SUBROUTINE   PIC X(12).
05  TXND-COMPRESS-LINE-SW     PIC X.
88  TXND-COMPRESS-LINES             VALUE  'Y'.
05  TXND-1LOC-DESC-SW         PIC X.
88  1LOC-DESC-WANTED                VALUE  'Y'.
05  TXND-MSTR-SEGMENT         PIC X(1500).
05  TXND-TRAN-SEGMENT         PIC X(50).
05  TXND-DESC-SEGMENT         PIC X(55).

01 TXND-RETURNED-DATA.
05  TXND-RETURNED-DATA-LEN    COMP PIC S9(4).
05  TXND-SHORT-DESC           PIC X(10).
05  TXND-LONG-DESC-1          PIC X(75).
05  TXND-LONG-DESC-2          PIC X(75).
05  TXND-LONG-DESC-3          PIC X(75).
05  TXND-SHORT-DESC-NUM       PIC 9(9).
05  TXND-CONVERTED-CHECK-SW   PIC X.
88  TXND-CONVERTED-CHECK            VALUE  'Y'.
05  TXND-ICM-TRAN-TYPE        PIC X(10).
***END TXNDCOPYBOOK***
---------------------------------------
WORKING-STORAGE SECTION.
COPY TXNDLINK.
PROCEDURE DIVISION.

MOVE LENGTH OF TXND-PASSED-DATA TO TXND-PASSED-DATA-LEN
MOVE LENGTH OF TXND-RETURNED-DATA TO TXND-RETURNED-DATA-LEN
CALL TXND-SUBROUTINE USING TXND-PASSED-DATA
TXND-RETURNED-DATA

TXND itself would look something like this:

PROGRAM-ID. TXND.
WORKING-STORAGE SECTION.
COPY TXNDLINK.
LINKAGE SECTION.
01  PASSED-DATA.
05  PASSED-DATA-LEN               COMP PIC S9(4).
05  PASSED-DATA-AREA.
10                            PIC X OCCURS 1 TO 9999
DEPENDING ON PASSED-DATA-LEN.
01  RETURNED-DATA.
05  RETURNED-DATA-LEN             COMP PIC S9(4).
05  RETURNED-DATA-AREA.
10                            PIC X OCCURS 1 TO 9999
DEPENDING ON RETURNED-DATA-LEN.

PROCEDURE DIVISION USING PASSED-DATA, RETURNED-DATA.
MOVE PASSED-DATA TO TXND-PASSED-DATA
MOVE RETURNED-DATA TO TXND-RETURNED-DATA
PERFORM MAINLINE
MOVE TXND-PASSED-DATA TO PASSED-DATA
MOVE TXND-RETURNED-DATA TO RETURNED-DATA
EXIT PROGRAM.

MAINLINE.
*    DO STUFF HERE USING TXND-PASSED-DATA AND SETTING TXND-RETURNED-DATA

END PROGRAM TXND.

I don't like the need for the calling program to set those length fields,
but I guess that's a minor complaint.  If my COBOL supported the ANY LENGTH
phrase I think that would eliminate the need for the LEN fields altogether,
since (I guess) COBOL would implicitly pass the length values.  That would
be very nice!

Of course even this method is not without it's problems.  If a field,
particularly a numeric field, is added to the PASSED-DATA area you would
have to make sure to check that field for valid values prior to utilizing
it, otherwise assume some sort of default.

And then imagine that we want to change the three "LONG-DESC" fields from 75
bytes to 100.  Well, now we're recompiling everything again!  Or adding new
fields to the end.

More than anything, this kind of thing gives me a desire for "object
oriented programming".  The fields in TXND-PASSED-DATA would be input
properties and the fields in TXND-RETURNED-DATA would be output properties.

Anyway, if anyone can see anything wrong with my thoughts about how to 'fix'
my TXND routine without the use of OO COBOL I'd be interested, as I may well
make these changes at some point.  Or at least to something similar for
future subroutines we might develop.

Another thing that would be nice is if COBOL had a way of counting the
number of parameters passed to it.  Actually, I think the OPTIONAL and
OMITTED, were they availible in my COBOL, would work.  Something like the
following:

PROGRAM-ID. MY-SUBR.
PROCEDURE DIVISION USING REQUIRED-FIELD1, REQUIRED-FIELD2, OPTIONAL
OPTIONAL-FIELD1, OPTIONAL OPTIONAL-FIELD2.

IF OPTIONAL-FIELD-1 NOT OMITTED
MOVE SOMETHING TO OPTIONAL-FIELD1
END-IF

----
* IN CALLING PROGRAM...
CALL 'MY-SUBR' USING FIELD1, FIELD2
CALL 'MY-SUBR' USING FIELD1, FIELD2, FIELD3
CALL 'MY-SUBR' USING FIELD1, FIELD2, OMITTED, FIELD4

But given that this is *not* available, other than passing a field
containing the number of fields passed, is there anything I can do?

Frank


---
Frank Swarbrick
Senior Developer/Analyst - Mainframe Applications
FirstBank Data Corporation - Lakewood, CO  USA

Report this thread to moderator Post Follow-up to this message
Old Post
Frank Swarbrick
02-09-07 11:55 PM


Sponsored Links




Last Thread Next Thread Next
Search this forum -> 
Post New Thread

Cobol archive

Show a Printable Version Send to friend Email This Page to Someone! subscribe to this thread Receive updates to this thread
Computer Consultants
Programming Jobs
Visual Basic Controls
SQL Server Programming
Webservices
Java Security
Visual Studio
C# Programming
Visual J++
Software engineering
Open source Software
Perl Programming
PHP Programming
ASP Programming
ASP .NET Programming
Visual Basic Programming
Windows Scripting Host
Java Programming
Java Help
Java Beans
VBScript
Cobol
MAC Applications
Unix Programming
Forum Jump:
All times are GMT. The time now is 06:17 PM.

 
Free MCSE Braindumps | Real Estate Topics

Programming forum archive

Copyrights CodeComments.com 2004 - 2006

Powered by vBulletin Copyright 2000-2006 Jelsoft Enterprises Limited.