ByVal
Category domino lotusscript
I'm often asked why I typically use ByVal on input parameters to Subs and Functions in LotusScript. Tommy had a great article today on making a distinction between input parameters and output parameters in order to maintain strong object typing.
When the Sub is done trying to do whatever it's supposed to, it updates the status variable to indicate whether or not it was able to do what was asked of it, and duration to indicate how long it took. This would be one way to approach agent profiling and true error handling (not just error logging). In fact, a lot of Notes API calls have some variation on a result input parameter, so the Sub behaves like what I consider to be a Function in that its only purpose is to determine the result value.
This model can be rather confusing to someone who's expecting Functions to return values and Subs to execute an action without returning a value, which brings us back to ByVal. Specifying ByVal is a promise to anyone maintaining your code (including you) that whatever is passed into the routine won't be modified by it - it can't be, because the variable's value is passed to the routine, not a reference to the variable itself. This makes it safe to structure the code calling that routine with the assumption that whatever variable was passed to it will retain the same value when the routine returns control to the caller. Objects are always passed by reference, but so are scalars if you don't specifically include ByVal, so if you're making any changes to the variable within the routine, and whatever is calling the routine is expecting its value to stay the same, things can go awry rather rapidly.
Because passing a parameter by value temporarily duplicates the memory storage for that particular variable, some developers prefer to just pass everything by reference. But each is only a couple bytes out of the billions available (assuming the users have at least 1 GB), and (supposedly) will be garbage collected as soon as the routine has completed, so I don't view the temporary increase in memory consumption as enough of a disadvantage to outweigh the self-documenting nature of knowing at a glance which parameters are read and which are read/write. This is one of many advantages of having each routine do only one thing: as soon as a routine completes its work, the user gets (most of) that memory back.
I'm often asked why I typically use ByVal on input parameters to Subs and Functions in LotusScript. Tommy had a great article today on making a distinction between input parameters and output parameters in order to maintain strong object typing.
This enables you to capture coding-errors at compile-time, instead of at runtime.Another advantage is allowing a routine to "return" multiple values at once. You could do this with a UDT or class, of course, but it's just easier to do something like this:
Sub executeWhatever(target As SomeClass, status As Boolean, duration As Long)
When the Sub is done trying to do whatever it's supposed to, it updates the status variable to indicate whether or not it was able to do what was asked of it, and duration to indicate how long it took. This would be one way to approach agent profiling and true error handling (not just error logging). In fact, a lot of Notes API calls have some variation on a result input parameter, so the Sub behaves like what I consider to be a Function in that its only purpose is to determine the result value.
This model can be rather confusing to someone who's expecting Functions to return values and Subs to execute an action without returning a value, which brings us back to ByVal. Specifying ByVal is a promise to anyone maintaining your code (including you) that whatever is passed into the routine won't be modified by it - it can't be, because the variable's value is passed to the routine, not a reference to the variable itself. This makes it safe to structure the code calling that routine with the assumption that whatever variable was passed to it will retain the same value when the routine returns control to the caller. Objects are always passed by reference, but so are scalars if you don't specifically include ByVal, so if you're making any changes to the variable within the routine, and whatever is calling the routine is expecting its value to stay the same, things can go awry rather rapidly.
Because passing a parameter by value temporarily duplicates the memory storage for that particular variable, some developers prefer to just pass everything by reference. But each is only a couple bytes out of the billions available (assuming the users have at least 1 GB), and (supposedly) will be garbage collected as soon as the routine has completed, so I don't view the temporary increase in memory consumption as enough of a disadvantage to outweigh the self-documenting nature of knowing at a glance which parameters are read and which are read/write. This is one of many advantages of having each routine do only one thing: as soon as a routine completes its work, the user gets (most of) that memory back.
Comments
Using passed parameters to return values to calling routines == worst practice.
I would detail, but it's late.
And the saving grace about passing scalar values instead of scalar references is that IN LOTUSCRIPT CODE, you really ought to be passing objects around, which you have to do by reference anyway.
But returning a status by changing the value of a passed reference? UGH. SPAGHETTI!!!!
Posted by Nathan T. Freeman At 10:25:23 PM On 11/27/2007 | - Website - |
ByVal is something I've never used, but thought that I should use. I'll (try to) be better and implement it in my code from now on.
Posted by Tommy Valand At 12:05:13 PM On 11/28/2007 | - Website - |