The big difference between a subroutine and a program is that a subroutine runs in the memory space already allocated to the current process. A program, by comparison, has to allocate additional memory space to keep it distinct from anything else going on. This is the basic underpinnings that allows subroutines to pass and receive parameters so freely.
When making the decision of program vs. subroutine, it's usually a matter of context. For example, if you're writing something that uses SB+ subroutine calls, you'll need SB+'s common memory and therefore you'll probably want a subroutine. If the code is to be run from TCL and has no need to connect to other subroutines, then a program is likely the best choice. If you're writing a SUBR-type field definition, then the decision is made; you'll write a subroutine.
Bottom line, to paraphrase Jiminy Cricket: "Let the context be your guide"!
