WinBatch® Technical Support Forum

All Things WinBatch => WinBatch => Topic started by: jtrask on July 15, 2015, 07:17:02 AM

Title: Why pass values to a subroutine?
Post by: jtrask on July 15, 2015, 07:17:02 AM
What is the purpose of passing values to a subroutine?  For instance, when creating a dynamic dialog callback subroutine, it passes a number of values from the dialog.  Isn't the point of using a subroutine over a function so that it will have access to these values anyway?  Is this a 'belt and suspenders' type thing?
Title: Re: Why pass values to a subroutine?
Post by: td on July 15, 2015, 12:54:14 PM
It's a software design thing.
Title: Re: Why pass values to a subroutine?
Post by: DAG_P6 on July 15, 2015, 03:14:31 PM
Quote from: td on July 15, 2015, 12:54:14 PM
It's a software design thing.

Since a subroutine sees all script level variables (that is, all variables except those defined within a User Defined Function, it may initially seem illogical to pass variables into a subroutine. Nevertheless, the ability to pass data into a subroutine through its arguments gives you a degree of flexibility that cannot be easily duplicated using nothing but the global variables.

For example, suppose that your main script defines ten variables, each of which holds the diameters of ten objects, which, under various circumstances, could be circles, spheres, or ovals whose narrow dimension is some fraction of the diameter. So, we have the following.
Finally, suppose that you have a subroutine, Volume, that computes the volume of the object. In Circle and Oval modes, it returns an Area, while it returns a true volume in Sphere mode.

There are at least three ways to code the Volume subroutine.
Of the three, the third subroutine is by far the simplest to write, because it has only to use a simple Switch block to evaluate ObjectType, and feed the remaining variables into the appropriate formula.

Since nobody is likely to do any of the above, because it is even more simple, not to mention robust, to define three functions, AreaOfCircle, AreaOfOvel, and VolumeOfSphere, the above example is completely contrived to illustrate a point.

I cannot, in good conscience, leave the subject of subroutines without reminding lurkers of the inherent risks of using subroutines. Since a subroutine can see and change any script variable, you must code carefully to avoid accidentally changing the wrong variable, thereby introducing a bug that might not show up right away, and could be challenging to diagnose and correct when it rears its ugly head, probably when you can least afford to stop and deal with it. In the 20 years or so since user defined functions became part of the language, I can think of only one or two cases when I chose a subroutine over a function. Functions are so much safer, easier to write and test, and there are very few circumstances when I can justify the significantly increased risk that subroutines bring to the party.
Title: Re: Why pass values to a subroutine?
Post by: stanl on July 16, 2015, 04:32:53 AM
Ditto....  I use SubRoutine parms with all of my COM/NET apps.  For example, I would have scripts with multiple connections and several subs that depend on which connection is passed to them. DefineFunction does not always lend itself in these cases where some flexibility is needed.
Title: Re: Why pass values to a subroutine?
Post by: td on July 16, 2015, 07:06:29 AM
My favorite use of WIL (a.k.a., WinBatch) subroutines is as a performance enhancer of a specific types of CPU bound algorithm.  In algorithms that are implemented using one or more tight looping structures with largish blocks of conditionally executed code in those loops, placing the conditionally executed blocks in subroutines will produce dramatic performance improvements.  This effect is a WIL specific optimization and cannot be generalized to other scripting languages.   
Title: Re: Why pass values to a subroutine?
Post by: DAG_P6 on July 28, 2015, 05:56:07 PM
Interesting. Can you speculate about why this is so?
Title: Re: Why pass values to a subroutine?
Post by: td on July 28, 2015, 09:51:24 PM
Speculate is not necessary.  It is simply because conditional blocks are not jumped (think jne, jz, or je) in WIL.  Conditional blocks are parsed but not executed.  Using a subroutine in a block means that only one line gets parsed.
Title: Re: Why pass values to a subroutine?
Post by: DAG_P6 on July 30, 2015, 06:40:22 AM
It's been a while since I stepped through a script, but I remember the line at a time parsing, now that you mention it.

Quote from: td on July 28, 2015, 09:51:24 PM
Speculate is not necessary.  It is simply because conditional blocks are not jumped (think jne, jz, or je) in WIL.  Conditional blocks are parsed but not executed.  Using a subroutine in a block means that only one line gets parsed.

So the blocks get divided up into several subroutines, with a top level routine that makes the first cut?