|
>>> rpg400-l@xxxxxxxxxxxxxxxx 08/23/2004 16:11:25 >>> > >> The main argument for using subroutines is to allow you to make your >> code more readable. > >You think that subroutines are more readable than subprocedures? Can you >explain that a little bit? It doesn't make any sense to me. Consider the >following sample code: > > > SubProc(); > > P SubProc B > D SubProc PI > // Do Something // > P E > > > exsr SubRout; > > SubRout begsr; > // do something // > endsr; > > >You're saying that the latter is easier to read? Frankly, if that's the >case, it's just because you're used to it. To me, they're about the same. I didn't say that subroutines are more readable that subprocedures, I don't think that one is intrinsically more readable than the other. They both serve the purpose, among others, of making code more readable. > >> It is true that there is no reason you must use >> subroutines, but I find them useful for breaking my code into smaller, >> more manageable segments, where the code in each segment is directly >> related to a single task, but where there is no advantage to placing it >> in a procedure. > >There may not be an advantage to placing it in a procedure, but there's >also no disadvantage. > >There may be an advantage that you're not considering, however. For >example, keeping all of your routines consistent by having them all coded >the same way. Or, the fact that a subprocedure can be called from another >subprocedure, which you may not need today, but it could come up in the >future. Or, the fact that some day in the future, you might want to >declare a local variable. > >Turn the question around... what's the advantage of making it a >subroutine? There isn't one. > An advantage of using a subroutine instead of a subprocedure is that it isn't a subprocedure. There is a distinct disadvantage to using subprocedures where they aren't appropriate. If your subprocedure uses global variables you can no longer tell if the variables in the subprocedure are local or global, without checking the D-specs. If your subprocedure needs to access global variables it should only be done through the interface. I see no advantage to having all routines coded the same if that means that I have to limit myself to one or the other. If the subprocedure needs to call a subroutine from the main code then either the subroutine needs to be a subprocedure, with the associated restrictions on global variables, or maybe the subprocedure should be a subroutine. On the other hand since a subroutine is nothing more than a section of the main code that has been segmented for readability purposes it has the same rules regarding global variables as any other portion of the main code. And since you can't use local variables in a subroutine no one will be tempted to add them. > >> For instance if you have a program which contains large nested if or >> select statements, where there is a large amount of code between each >> if,else, when, etc statement. I find it easier to read something like >> this: >> >> if condition x >> exsr handle_x >> else >> select >> when condition y >> exsr handle_y >> when condition z >> exsr handle_z >> endsl >> endif >> where each of the "handle" subroutines is several pages of code. > > >But you can do that just as easily with subprocedures, can't you? For >example, why do you think that > > if condition x > exsr handle_x > endif > >is better than > > if condition x > callp handle_x > endif > >they seem to have the exact same advantages for readability, but the >subprocedure has other features that even if you don't need them at the >moment, you might need some other day. What's the advantage of using a >subroutine. I can't think of any! > Neither of those examples is more readable than the other, and if the code being called was appropriate for a subprocedure I would code it that way. Don't get me wrong I like subprocedures and use them whenever I can, but I don't just say subprocedures are new and subroutines are old, and since they both do approximately the same thing I must use subprocedures instead of subroutines. > >> Than I find reading the same code with the subroutines inline. True you >> may be able to do some of this via subprocedures, and if you can you >> probably should. But if the code in question gains no advantage from >> being in a subprocedure other than being split up into more manageable >> chunks, then I believe that a subroutine is the better solution. > >If the code gains no advantage from being a subroutine, I think a >subprocedure is a better solution. You seem to think the opposite. Why? >Why is a subroutine ever a better solution? That's the question. > The question as I see it is does having the code as a subprocedure disadvantage you. > >> Another place I use a subroutine is in rpg cgi programs. I usually have >> a "getvars" subroutine where I place all the code that retrieves form >> variables from an incoming request. If I were to do this in a >> subprocedure I would have to change the interface every time I needed to >> add a form variable. However with a subroutine I have a single section >> of code, with a single purpose, that does not need to be in the mainline >> of the code for readability. > >No, sorry.. you can do exactly the same thing with subprocedures if you >want to. > >I wouldn't code it that way myself -- but I wouldn't code it that way with >EITHER subprocedures or subroutines. You seem to be of the opinion that >it's okay to write 1980's style code if you use a subroutine to do it >instead of a subprocedure. > Well this is a separate discussion, I find exsr getvars easier to read in the main code than eval username = getvarval('remoteuser') eval report = getvarval('report') eval year = getvarval('year') eval month = getvarval('month') . . . etc. and while you could do it in a subprocedure without changing the interface, you could only do it by having the subprocedure use global variables. >IMHO, it's a better idea to write reusable code. There's more to >modularity than just breaking your code up into pieces! But, if you ARE >going to write a single routine that handles all of the variables on your >form, there's no advantage to doing it in a subroutine! Do it in a >subprocedure, it'll work just as well. > Subroutines aren't about modularity, it used to be that they were one of the only ways you could achieve any modularity but I don't think you should use them for it now. Subroutines are about making your code easier to maintain. If something should be a "module" then it should probably be in a subprocedure, but if it is truly a module then it should be able to stand on its own without depending on its hosts global variables. > >> I know that running the getvars subroutine reads all the form variables, >> and if I have defined them in a single section of the D specs I know >> what those variables are. I don't need to have that code cluttering up >> the mainline code. > ><broken record> but you can do that with subprocedures as well... > > >> I disagree that "If you're going to throw the advantages away, then >> there's absolutely no value to avoid doing it in a subprocedure.", >> rather I would say that just because you can't use the advantages of a >> subprocedure in a subroutine, there is no reason to throw those >> advantages away, for suprocedures, by using a subprocedure instead of a >> subroutine. > >Huh? How does using global variables in one procedure throw away the >advantages of not using them in another procedure? And how does using a >subroutine solve this problem? > >Are you saying that you use "begsr" as documentation that tells the next >programmer "this uses globals" and the P-spec as documentation that says >"this doesn't use globals?" > >If that's what you're after, why not just use a comment? > If you use a global variable in one subprocedure how do I know you only did it in that subprocedure? I wasn't saying that begsr means globals And a P-spec means locals, but now that I think about it, it is implicit in a properly scoped program. > >> If you accept the argument that it is "bad" to use global variables in >> a subprocedure then it is completely valid and logical to argue that one >> of the reasons for using a subroutine is to set a number of global >> variables. > >You seem to think that if it's "bad" to use global variables, that >everything is okay if you use them in subroutines instead. How does using >them in subroutines solve the problem? Why is it okay to do it in >subroutines and not subprocedures? It's ok to use global variables in a subroutine because the subroutine is at the same scoping level as the main program. To the subroutine the global variables aren't global they are local because the subroutine is at the same scoping level as the main code. > >> One of the reasons to avoid using global variables in a subprocedure is >> that because you can have local variables with the same name as a global >> variable. > >That's a bad idea, it leads to very confusing code. I suggest using a >naming convention where local variables have different names from global >variables. > >For example, in my shop, global "work" variables (those that aren't coming >from files) start with the 2-char prefix "wk". So, if I have a customer >number that's a global variable, it'll be called wkCust. Local >work variables start with the prefix "ww"... a customer number field >that's local to a subprocedure would be called wwCust. That way there's >never confusion. > >Though, if I could start over again, I think I'd use "my" for the prefix >for local variables. I'm not even sure where I came up with "ww." > Local variables in a procedure with the same name as the global variables in a program are only confusing if you can't be sure that they are ALWAYS local. When you create a subprocedure in a separate module do you check every program it may ever be used with to make sure you aren't using the same variable names? > >> If you ever mix local and global variables in a subprocedure >> it makes it much harder to determine which variable you are using in any >> given situation, and in fact throws away some of the advantages of a >> subprocedure. If on the other hand you never mix local and global >> variables, you can always know which you are using. > >Yes, but that doesn't mean that all variables should be global just to >avoid conflicting.... there are advantages to using local variables. I didn't say that all variables should be global. Actually I maintain that no, or almost no, variables should be global all variables should be local to the current scope. > >> As with everything, it depends on what you are doing. But I cannot >> agree that there are NO reasons to use a subroutine. There are far fewer >> reasons, but there still are some. > >Some reasons for using subroutines are INFSR, *PSSR, and *INZSR. Once IBM >gives us the ability to replace those with subprocedures, there will no >longer be a reason. > As I said in another response. In general a subprocedure should be able to be placed in a module by itself and compiled. If it can't then likely it should be a subroutine. Joe Lee
As an Amazon Associate we earn from qualifying purchases.
This mailing list archive is Copyright 1997-2024 by midrange.com and David Gibbs as a compilation work. Use of the archive is restricted to research of a business or technical nature. Any other uses are prohibited. Full details are available on our policy page. If you have questions about this, please contact [javascript protected email address].
Operating expenses for this site are earned using the Amazon Associate program and Google Adsense.