Question from Paul K. Dick:
When modularizing a program is there any general guidelines when a callnat/fetch return/perform (an external subroutine) works better?
Is an external subroutine a program, a subprogram, or its own animal?
Grogory DeSalva answered:
I seem to recall from a presentation at SAGA Tech that Natural 2.3 had a lot more overhead when calls were made to external objects using parameters (with significant performance impact). This primarily involves subprograms, but includes anything using a parameter list. At least that's what I recorded in my notes.
Scott Sinclair answered:
If you are modularizing with the goal of achieving code reuse (as opposed to just splitting up a large program) I would always choose subprograms as the preferred option.
Subprograms offer the cleanest interface of the options you mentioned and will allow the greatest reuse. If you need to access a subprogram from the command line/stack you can always wrap it with a program interface. Similarly, you can wrap a helproutine around it if required.
I avoid external subroutines because they can access the calling programs globals which means that you can't easily tell (without examining the code or checking xref) what GDA variables the subroutine uses/assigns. Furthermore, this reduces the applicability of the subroutine to only those programs that share the same GDA. Similarly, I don't advocate defining GDAs within helproutines.
FETCH RETURN limits you to using the stack or GDA to exchange data. The stack is not a very clean (formal) interface and its problematic because it interferes with INPUT ... REINPUT logic. For example you can't do something like
INPUT ... FETCH RETURN 'PGM' 'DATA' ... REINPUT 'msg'
Exchanging data with the fetch returned program via the GDA has the same problems I described regarding external subprograms.
In conclusion, the only modularization techniques I recommend are Internal subroutines, copycode and subprograms (along with data areas, maps and helproutines).
Thanks to Kim Canavan, Fredericksburg, VA (540) 899-9005