On 23 Jul 2013 14:51, Dan Kimmel wrote:
Still, I like the concept. It'd be a way to get out of a block of
code without a GOTO. The Do .. EndDo marks the block of code. Are
there other  ways to jump out of a block in CL structured op codes?
  I agree with the desirability for the ability to use LEAVE in a 
non-looping DO group.  I was merely pointing out the restriction, as 
diagnosed in messages; having totally overlooked referring to the help 
text for the LEAVE command to find it even more clearly documented :-( 
as was pointed out by Scott.
  While I am not particularly fond of the GOTO, I am willing to use 
them when they are useful and not overly fraught with potential 
difficulties [likely to be seen only with later modifications to the 
code].  The use of Monitor Message (MONMSG) versus use of feedback from 
a function call, I think makes the use of the GOTO more 
preferable\easier than some might prefer, if having /well-structured/ 
code [or otherwise described as code that is free of GOTOs] is 
desirable.  And in this case [overlooking the fact that the original 
code seems easily modified instead, to just remove the redundancy] the 
code could probably somewhat safely be written using a GOTO, by having a 
LABEL established for the EndDo:
  Do
    chkobj ...
    monmsg cpf9800 exec(goto err9800)
    call ...
    ...
 err9800: /* this label must remain with the EndDo */ +
  EndDo
  That is of course effectively the same as the LEAVE.  The biggest 
problems for maintenance are the possibility of someone copying the line 
with the GOTO elsewhere, or adding a line before the EndDo such that the 
label becomes associated with that new line of code.  Copying the 
Do-group somewhere else is not an issue; that will be diagnosed as a 
duplicate label, and hopefully piquing the curiosity of the coder to 
review all references.  Moving the label in front of the EndDo to avoid 
the line continuation is an option to avoid an inserted line, but that 
may pose stylistic concerns [for aligning the Do\EndDo].
  To eliminate the GOTO, the code might best maintain an effective 
error indicator, much like how use of a function invocation might have 
one naturally coding that way.  In effect, making the code respond to 
return-codes versus messaging.  Consider the following two CLP samples 
whereby the first changes to move the processing of CHKOBJ to a function 
call, and the second continues to use MONMSG after the inline CHKOBJ, 
but both change to eliminate the GOTO and use conditional logic based on 
an effective indicator:
  dcl &Authorized *char 01 /* I think *LGL not allowed as RtnVal */
  ,,.
  Do
   callprc ChkForObj parm(...) RTNVAL(&Authorized)
   /* effectively: chgvar &Authorized value( ChkForObj(...) ) */
   If cond(&Authorized *eq '1') then(Do)
    call ...
    ...
   EndDo
  EndDo
  dcl &SkipCall *lgl
  ,,.
  Do
   chkobj ...
   monmsg cpf9800 exec(chgvar &SkipCall '1')
   If cond(*not &SkipCall) then(Do)
    call ...
    ...
   EndDo
  EndDo
  FWiW I think the restriction might exist in part, because all of the 
iterative control statements and the ITERATE itself were all going in 
together.  All of the code for LEAVE and ITERATE would be specific to 
only new CLP sources; i.e. none of DOWHILE, DOFOR, or DOUNTIL existed 
before.  Testing for non-looping Do-groups is limited to the compiler vs 
run-time; i.e. ensuring the compiler diagnosed them as errors, thus 
limiting the amount of testing.  Additionally it could have arisen in 
part as a side effect from the difficulty of establishing an unambiguous 
CMDLBL(*CURRENT) for the LEAVE.  While obvious with regard to DO groups 
that are standalone, most Do-groups are instead embedded in an IF\ELSE. 
 Like a GOTO LabelName can easily cause problems when code is changed 
or copied, so too could a LEAVE in an IF, given an ELSE was added; i.e. 
previously having processing continued in the implied ELSE, after adding 
an ELSE the processing LEAVE likely would have been defined to continue 
after the DO groups of both the IF and the ELSE.?  The question mark, 
because arguably [and documented as such, that] they are two distinct 
non-nested Do-groups; one as part of the THEN of the IF statement and 
the other as part of the ELSE which is its own separate statement.  Thus 
there is a possibly valid argument that the LEAVE CMDLBL(*CURRENT) would 
properly go to the ELSE.  If the CMDLBL() specification could extend to 
a LABEL for an IF versus a LABEL for a DO statement, and all of the 
DO\ENDDO under that IF were considered as one Do-group, then that could 
make a LEAVE in a non-looping Do-group seem somewhat reasonable [to me].
Regards, Chuck
As an Amazon Associate we earn from qualifying purchases.