Answer to question 11

We hope you have understood that it is always possible to call a function instead of using an assignment.  The difference is that you don't get the result of the function back in a variable.  The result can however be found in the reserved variable called RESULT.

There are 3 reserved variable names in REXX.  The one you know probably best is RC, containing the return code of a host command.  Then there is SIGL that contains the line number of the SIGNAL command that caused the jump to a label, so that you can know from where you were called.  Finally, RESULT contains the result of a called subroutine or function.

So, for example, the statement

    trc=translate('ABC',' ','B')

is equivalent to

    call translate 'ABC',' ','B'
    trc=result

For the call to the trace() function, the result (hence the value of variable trc), is the current trace setting value, that is, the first letter of the trace setting as it was before the call was issued.

Pay also special attention to the coding rules.  Many beginners continually make the same mistakes here.

  1. When functions are issued via the call instruction, the parameters must not be coded between parentheses.  Coding call trace('?i') for example, is invalid.
  2. When functions are not issued via the call instruction, the parentheses are needed, even if no parameters are specified.  So, for example, abc=trace().
    If the parentheses are missing, REXX doesn't consider it to be a function call.
  3. The left parenthesis needs to be adjacent to the name of the function, with no intervening blank.

Furthermore, avoid the typical error of coding a function call on its own.  For example, if you would code

     diag(8,'QUERY V DASD')

the function would indeed execute, and return a result, which in this particular case, is a list of virtual DASDs, as diag(8) executes a CP command, specified as second parameter. 

Because the function is not coded as an assignment, the result is passed unchanged to the currently active environment, maybe CMS, which will probably have great difficulties to execute the list of DASD addresses...

There is one more thing to mention !

As there is no label TRACE: in the procedure, CALL TRACE forces the interpreter to search for the corresponding REXX function.

Indeed, if you would have a label TRACE: in your procedure, REXX would branch to that label instead of executing the trace function ! 

As always, there is a solution to this problem.  If you code:

   call 'TRACE' '?i'
      or
   trc='TRACE'('?i')

REXX is forced to use the built-in function.  Note the quotes surrounding the function and the uppercase characters.

In general, if you would code all built-in functions that way, it would be a little bit faster for REXX too, as REXX has not to look for the corresponding label, but can execute the internal function immediately.

You might think now that with the good old address command statement, the REXX interpreter would also try to find a TRACE EXEC.

This isn't true at all.  The address command has no influence here, it only instructs REXX on how to pass commands to CMS.

Note how REXX searches for a function:

  1. an internal routine, unless it is bypassed via quotes ;
  2. a built-in function ;
  3. an external routine.

So, as TRACE() is a known built-in function, a TRACE EXEC will not be executed, even if it exists.

If you would really like to execute the external TRACE EXEC, then you would need to code :

      'EXEC TRACE ?i'

Still more

By the way, the question in the text reads call trace off instead of call trace 'off' which can be something completely different if you have defined a variable named 'off'.  This may be considered a sin against our rules.

Use the backward navigation button of your browser to return to the lesson.