Saturday, November 22, 2008

LEARNINGS OF THE WEEK (Nov. 17-21)
By: Frea Diane T. Bautista

This week, we discussed about Function Calls. He also taught us how t use them.
But what does Function Call really mean?
Function call operator ( )
A function call is an expression containing the function name followed by the function call operator, (). If the function has been defined to receive parameters, the values that are to be sent into the function are listed inside the parentheses of the function call operator. The argument list can contain any number of expressions separated by commas. It can also be empty.
The type of a function call expression is the return type of the function. This type can either be a complete type, a reference type, or the type void. A function call expression is always an rvalue. A function call is an lvalue if and only if the type of the function is a reference.
Here are some examples of the function call operator:
stub()
overdue(account, date, amount)
notify(name, date + 5)
report(error, time, date, ++num)
The order of evaluation for function call arguments is not specified. In the following example:
method(sample1, batch.process--, batch.process);
the argument batch.process-- might be evaluated last, causing the last two arguments to be passed with the same value.
Below is also another explanation of Function and Parameters.
A function is similar to a subroutine (Gosub) except that it can accept parameters (inputs) from its caller. In addition, a function may optionally return a value to its caller. Consider the following simple function which accepts two numbers and returns their sum:
Add(x, y)
{
return x + y ; "Return" expects an expression.
}
The above is known as a function definition because it creates a function named "Add" (not case sensitive) and establishes that anyone who calls it must provide exactly two parameters (x and y). To call the function, assign its result to a variable with the := operator. For example:
Var := Add(2, 3) ; The number 5 will be stored in Var.
Also, a function may be called without storing its return value:
Add(2, 3)
But in this case, any value returned by the function is discarded; so unless the function produces some effect other than its return value, the call would serve no purpose.
Since a function call is an expression, any variable names in its parameter list should not be enclosed in percent signs. By contrast, literal strings should be enclosed in double quotes. For example:
if InStr(MyVar, "fox")
MsgBox The variable MyVar contains the word fox.
In v1.0.47.06+, a function (even a built-in function) may be called dynamically via percent signs. For example, %Var%(x, "fox") would call the function whose name is contained in Var. Similarly, Func%A_Index%() would call Func1() or Func2(), etc., depending on the current value of A_Index. The called function's definition must exist explicitly in the script by means such as #Include or a non-dynamic call to a library containing the function. If the function does not exist -- or if the wrong number or type of parameters is passed to it -- the expression containing the call produces an empty string.
Finally, functions may be called in the parameters of any command (except OutputVar and InputVar parameters such as those of StringLen). However, parameters that do not support expressions must use the "% " prefix as in this example:
MsgBox % "The answer is: " . Add(3, 2)
The "% " prefix is also permitted in parameters that natively support expressions, but it is simply ignored.
Parameters
When a function is defined, its parameters are listed in parentheses next to its name (there must be no spaces between its name and the open-parenthesis). If a function does not accept any parameters, leave the parentheses empty; for example: GetCurrentTimestamp().
ByRef Parameters: From the function's point of view, parameters are essentially the same as local variables unless they are defined as ByRef as in this example:
Swap(ByRef Left, ByRef Right)
{
temp := Left
Left := Right
Right := temp
}
In the example above, the use of ByRef causes each parameter to become an alias for the variable passed in from the caller. In other words, the parameter and the caller's variable both refer to the same contents in memory. This allows the Swap function to alter the caller's variables by moving Left's contents into Right and vice versa.
By contrast, if ByRef were not used in the example above, Left and Right would be copies of the caller's variables and thus the Swap function would have no external effect.
Since return can send back only one value to a function's caller, ByRef can be used to send back extra results. This is achieved by having the caller pass in a variable (usually empty) in which the function stores a value.
When passing large strings to a function, ByRef enhances performance and conserves memory by avoiding the need to make a copy of the string. Similarly, using ByRef to send a long string back to the caller usually performs better than something like Return HugeString.
Known limitations:
• It is not possible to pass Clipboard, built-in variables, or environment variables to a function's ByRef parameter, even when #NoEnv is absent from the script. Passing a built-in variable to a ByRef parameter causes an error dialog to be displayed.
• Although a function may call itself recursively, if it passes one of its own local variables or non-ByRef parameters to itself ByRef, the new layer's ByRef parameter will refer to its own local variable of that name rather than the previous layer's. However, this issue does not occur when a function passes to itself a global variable, static variable, or ByRef parameter.
• If a parameter in a function-call resolves to a variable (e.g. Var or ++Var or Var*=2), other parameters to its left or right can alter that variable before it is passed to the function. For example, func(Var, Var++) would unexpectedly pass 1 and 0 when Var is initially 0, even when the function's first parameter is not ByRef. Since this behavior is counterintuitive, it might change in a future release.
Optional Parameters
When defining a function, one or more of its parameters can be marked as optional. This is done by appending an equal sign followed by a default value. The following function has its Z parameter marked optional:
Add(X, Y, Z = 0)
{
return X + Y + Z
}
When the caller passes three parameters to the function above, Z's default value is ignored. But when the caller passes only two parameters, Z automatically receives the value 0.
It is not possible to have optional parameters isolated in the middle of the parameter list. In other words, all parameters that lie to the right of the first optional parameter must also be marked optional.
In v1.0.46.13+, ByRef parameters also support default values; for example: Func(ByRef p1 = ""). Whenever the caller omits such a parameter, the function creates a local variable to contain the default value; in other words, the function behaves as though the keyword "ByRef" is absent.
A parameter's default value must be one of the following: true, false, a literal integer, a literal floating point number, or a quoted/literal string such as "fox" or "" (but versions prior to 1.0.46.13+ allow only "").

No comments: