Re: Regarding EVALUATE TRUE
- From: "klshafer@xxxxxxx" <klshafer@xxxxxxx>
- Date: Thu, 16 Aug 2007 08:50:07 -0700
Hmmmm.... all the posts have been helpful to me, helping me figure out
what is going on; ah yes, to the interested, just be patient, for I
think we are getting somewhere with this...
Reply'd here under Mr. Swarbrick, but with some liberal inclusion of
the Doc's feedback as well...
<Frank.Swarbr...@xxxxxxxxxxxxxx> wrote:
no! No! NO!!
This is exactly why I prefer (a normal) EVALUATE to the IF ELSE IF ELSE step
ladder. With a normal evaluate each of the possible branches is at the same
'level'. With IF ELSE stepping and your corruption (sorry) of EVALUATE
you're constantly increasing the level. That's just, umm, yucky. :-)
Couple of points worth making here... First off, once again, for
reasons which will be made more clear, my reservations are with
EVALUATE TRUE, not with EVALUATE "in general." Secondly, I'm not
_necessarily_ prescribing IF ... ELSE IF as an alternative. I'm
_working out_ the alternative with all of you. As for IF... ELSE IF
stepping, the ol' rule of thumb was go three deep and no more. I think
it still applies.
This leaves us with your contention that "With a normal evaluate each
of the possible branches is at the same 'level'." Yes, that is the
crux of the matter. With the form of EVALUATE which is EVALUATE data-
element-name I would agree 100%. But with EVALUATE TRUE it is another
story, I believe. There are infinitely-dimensional ways that TRUE can
be satisfied. Placing each of these ways "on the same level" in the
EVALUATE can actually, in my opinion, disguise a hiearchy which is
going on. More on that later...
EVALUATE TRUE
WHEN CASE-IN-COMPLETE
SET IN-COMPLETE-CASE TO TRUE
PERFORM 1000-SET-CASE-TYPE-MSG
WHEN NO-CASE-EXISTS
SET NON-EXISTING-CASE TO TRUE
PERFORM 1000-SET-CASE-TYPE-MSG
WHEN WEA1CAS-STATUS = IND-TYPE-OF-CASE
CONTINUE
WHEN WEA1CAS-STATUS > SPACE
AND CASE-OPEN OF WEA1CAS-SACSTAT
PERFORM 2000-FINISH-CASE-EDIT-S
WHEN WEA1CAS-STATUS > SPACE
AND CASE-CLOSED OF WEA1CAS-CASE-STATUS
PERFORM 3000-FORMAT-WEA1CASA
PERFORM 4000-UPDATE-WEA1CASA-6CASH
WHEN WEA1CAS-STATUS = SPACE
AND CASE-OPEN OF WEA1CAS-CASE-STATUS
IF CASE--OPEN OF CSN-CASE-STATUS
PERFORM 3000-FORMAT-WEA1CASA
PERFORM 4000-UPDATE-WEA1CASA-6CASH
ELSE
CONTINUE
END-IF
WHEN OTHER
CONTINUE
END-EVALUATE
Hmm, that looks fairly readable to me. I certainly don't think > that hanging it to an IF/ELSE step ladder would make it any > better. To me it would make it a lot worse.
Ahhh, yes, allow me to agree with you, and with the Doc as well,
insofar as there is no improvement to be had by morphing it into an IF/
ELSE structure. There is something about the design of it all, some
deficiency, which may be at work. Yes, it is "readable". But the
empiricist in me has to ask: "Why has this area of code, and its
"neighbors", been the source and focus of so many defects some 10
years after it was originally written?" Something else must be going
on too...
Keeping with good _Structured Design_ principles of high functional
cohesion, can somebody summarize in a sentence or two what single
function the above EVALUATE performs?
No, but I doubt you could do that in any case. It's simply complex business
logic. Complex business logic requires at least somewhat complex
programming logic. Not sure how you can get around that!
Many "competent" programmers can take what appears to be complex
business logic and solve it with program complexity. However, it is
worthwhile, in my opinion, to spend some time "getting to the heart of
the matter", to take what is only _apparently_ complex, reduce its
complexity, simplify it, and then program the "simplified"
representation. Hierarchy is one way to do this.
Sorry, I still don't agree. I actually find your example to be quite
elegant! Sorry. :-)
Then why has it been the source of so many bugs? Something must be
wrong with it, and "wrong" with the style...
Anyway, I realize that the above could be done without the EXIT PARAGRAPH
statements, and rather with connecting ELSEs, but again, if I were do that
It'd end up with this:
IF CASE-IN-COMPLETE
SET IN-COMPLETE-CASE TO TRUE
PERFORM 1000-SET-CASE-TYPE-MSG
ELSE
IF NO-CASE-EXISTS
SET NON-EXISTING-CASE TO TRUE
PERFORM 1000-SET-CASE-TYPE-MSG
ELSE
IF WEA1CAS-STATUS = IND-TYPE-OF-CASE
CONTINUE
ELSE
IF WEA1CAS-STATUS > SPACE
AND CASE-OPEN OF WEA1CAS-SACSTAT
PERFORM 2000-FINISH-CASE-EDIT-S
ELSE
IF WEA1CAS-STATUS > SPACE
AND CASE-CLOSED OF WEA1CAS-CASE-STATUS
PERFORM 3000-FORMAT-WEA1CASA
PERFORM 4000-UPDATE-WEA1CASA-6CASH
ELSE
IF WEA1CAS-STATUS = SPACE
AND CASE-OPEN OF WEA1CAS-CASE-STATUS
IF CASE--OPEN OF CSN-CASE-STATUS
PERFORM 3000-FORMAT-WEA1CASA
PERFORM 4000-UPDATE-WEA1CASA-6CASH
END-IF
END-IF
END-IF
END-IF
END-IF
END-IF
END-IF.
This, in my opinion, is atrocious! Readable, yes. But hard to extend
because you end up running out of room on the right!
Anyway, I'll stick with EVALUATE.
Yes, indeed, it is very atrocious! And perhaps, not accidentally, I
see quite a lot of seven and eight deep IF's in this same system. I
would contend that this type of IF staircase'ing testing is the same
quagmire as EVALUATE TRUE operating upon multiple data-element
conditions.
But now to some better awareness, which you all have helped me
attain...
Let's revisit the, uhhh, problematic legacy code... actually, as I
snipped it, I removed some of the junk, and left out another WHEN, so
let's revisit it...
EVALUATE TRUE
WHEN CASE-IN-COMPLETE
SET IN-COMPLETE-CASE TO TRUE
PERFORM 1000-SET-CASE-TYPE-MSG
WHEN NO-CASE-EXISTS
SET NON-EXISTING-CASE TO TRUE
PERFORM 1000-SET-CASE-TYPE-MSG
WHEN CASE-EXISTS-BUT-NOT-EXACT
SET NON-MATCHING-CASE TO TRUE
PERFORM C110-SET-CASE-TYPE-MSG
WHEN WEA1CAS-STATUS = IND-TYPE-OF-CASE
CONTINUE
WHEN WEA1CAS-STATUS > SPACE
AND CASE-OPEN OF WEA1CAS-SACSTAT
PERFORM 2000-FINISH-CASE-EDIT-S
WHEN WEA1CAS-STATUS > SPACE
AND CASE-CLOSED OF WEA1CAS-CASE-STATUS
PERFORM 3000-FORMAT-WEA1CASA
PERFORM 4000-UPDATE-WEA1CASA-6CASH
WHEN WEA1CAS-STATUS = SPACE
AND CASE-OPEN OF WEA1CAS-CASE-STATUS
IF CASE--OPEN OF CSN-CASE-STATUS
PERFORM 3000-FORMAT-WEA1CASA
PERFORM 4000-UPDATE-WEA1CASA-6CASH
ELSE
CONTINUE
END-IF
WHEN OTHER
CONTINUE
END-EVALUATE
Ahhh, yes, my peers in CLC, and my peers in my shop, helped me look
further... hmmmm... it turns out the first three WHEN's refer to 88's
on a single data element. This is a good thing... the next set refer
to booleans on a status... this starts to get confusing. The awareness
to be had comes from your discussion of the "fall through" and the
WHEN OTHER considerations. As well as Doc's insistence, and my
agreement, that Mr. Swarbrick, yes, you had it exactly right the first
time, when your coded your WIRE logic specifying all the conditions,
instead of allowing on the WHEN OTHER to "catch" the last one.
In the above example, what it turns out to be, is that there is a
_missing_ WHEN which is obscuring the true essence of what is going
on. Let me put it in the code, and then rewrite it just a bit...
EVALUATE TRUE
WHEN CASE-IN-COMPLETE
SET IN-COMPLETE-CASE TO TRUE
PERFORM 1000-SET-CASE-TYPE-MSG
WHEN NO-CASE-EXISTS
SET NON-EXISTING-CASE TO TRUE
PERFORM 1000-SET-CASE-TYPE-MSG
WHEN CASE-EXISTS-BUT-NOT-EXACT
SET NON-MATCHING-CASE TO TRUE
PERFORM C110-SET-CASE-TYPE-MSG
WHEN CASE-EXISTS-EXACTLY
* *** NOW PROCESS VERY GOOD CASE ACCORDING TO ITS STATUS...
EVALUATE TRUE
WHEN WEA1CAS-STATUS = IND-TYPE-OF-CASE
CONTINUE
WHEN WEA1CAS-STATUS > SPACE
AND CASE-OPEN OF WEA1CAS-SACSTAT
PERFORM 2000-FINISH-CASE-EDIT-S
WHEN WEA1CAS-STATUS > SPACE
AND CASE-CLOSED OF WEA1CAS-CASE-STATUS
PERFORM 3000-FORMAT-WEA1CASA
PERFORM 4000-UPDATE-WEA1CASA-6CASH
WHEN WEA1CAS-STATUS = SPACE
AND CASE-OPEN OF WEA1CAS-CASE-STATUS
IF CASE--OPEN OF CSN-CASE-STATUS
PERFORM 3000-FORMAT-WEA1CASA
PERFORM 4000-UPDATE-WEA1CASA-6CASH
ELSE
CONTINUE
END-IF
WHEN OTHER
CONTINUE
WHEN OTHER
DISPLAY "BAD INTERNAL ERROR - SHOULD NOT REACH HERE!"
PERFORM 999-ABEND-EXIT
END-EVALUATE
The first-level EVALUATE now works _only_ on 88-levels for a _single
data element_. The second-level evaluate is applicable to _only_ one
of them, namely when CASE-EXISTS-EXACTLY. If one doesn't like the
staircased second level evaluate, then just replace it with a PERFORM
paragraph. This might even be preferable, keeping in the spirit of the
other imperative sections in the first level EVALUATE.
Also notice how this now makes the first-level EVALUATE completely
order-independent, since the 88's now form an exhaustive partition of
the single-data-element. This would allow for the order of the WHEN's
to be re-arranged for execution efficiency, in those (rare?)
occurrences when very, very tight loops are called for.
Now it is certainly OK to agree to disagree, but I return to my
original contention, which is EVALUATE TRUE, when operating upon
conditions which are predicated upon _multiple_ data-elements, can
lead to obscure code. When one reflects a bit, this is very plausible.
EVALUATE data-element, even though data-element may have a very-large-
number of values, at least is, um, what I might call "uni-
dimensional". The WHEN's will refer to values on only a single data
element.
But now looking at EVALUATE TRUE - gasp! there must be a many, many
dimensional way that 'TRUE' might be satisfied with boolean constructs
operating upon who-knows-how-many data elments in working-storage.
This temptation is what leads to what the structured enthusiasts
called "concidental cohesion", the weakest kind, the kind which is the
most difficult to understand and maintain.
The above rewrite doesn't get us to very high cohesion yet, but it is
a step in that direction, and can begin to accommodate better
modularization.
So, see Doc, I have no real objections to 88's. I just have objections
to 88's referring to _different data elements_, all operating at the
same level of EVALUATE. If present, they are masking a hierarchy whose
understanding is probably important.
Can't take the time right now to reply to all of you... but I did very
much appreciate everyone who chimed in...
Maybe more later,
Ken
.
- Follow-Ups:
- Re: Regarding EVALUATE TRUE
- From: Frank Swarbrick
- Re: Regarding EVALUATE TRUE
- From:
- Re: Regarding EVALUATE TRUE
- References:
- Regarding EVALUATE TRUE
- From: klshafer@xxxxxxx
- Re: Regarding EVALUATE TRUE
- From: Frank Swarbrick
- Re: Regarding EVALUATE TRUE
- From: klshafer@xxxxxxx
- Re: Regarding EVALUATE TRUE
- From: Frank Swarbrick
- Regarding EVALUATE TRUE
- Prev by Date: Re: Regarding EVALUATE TRUE
- Next by Date: Browser standards was Re: field validation (was Re: COBOL/DB2 Date edit question)
- Previous by thread: Re: Regarding EVALUATE TRUE
- Next by thread: Re: Regarding EVALUATE TRUE
- Index(es):