XploRe offers a variety of possibilities to implement sophisticated structures in your programs. With the commands introduced in the following you are able to make your program react on conditions; you can handle failures while avoiding or provoking a program's stop, and last but not least, you can give your program a well-structured, understandable shape.
|
When you are working with procedures, you have to know whether the variables used in the procedures are accessible in the main program and vice versa. The answer is: XploRe strictly distinguishes between globally and locally defined variables.
Variables in procedures can take on the values of global ones. The
procedure then can use the values, change them, and
compute various results, but it cannot change the value of the original
global variable.
However,
XploRe
helps you to overcome this restriction by using the
putglobal
and
getglobal
commands. Note that these
as well as the
existglobal
only work within procedures.
XploRe offers you the possibility to easily transfer a variable from the procedure to the main program. A locally defined variable can then (when the procedure has been run at least once) be accessed and changed in the main program.
Consider the following example:
proc() = test(a, b) c = a + b ; computes c as the sum of a and b, ; c is now a local variable putglobal("c") ; declares c to be also GLOBAL variable endp x = 1 y = 2 test(x, y) ; runs the procedure test taking the ; values of the globals x and y for ; the locals a and b c ; output of c, c is accessible here ; because it has been transferred by ; the putglobal command
Contents of c [1,] 3
You can also do this the other way around. Normally in a procedure it is not possible to access global variables with the exception of those transferred in the head of the procedure's definition.
For this purpose, you use the
getglobal
command, which can
transfer the value of a global variable to a local
variable. The value can then be used, changed, and results can be computed
in the procedure. However, it will not change the global variable in the
main program.
proc() = test(a, b) z = getglobal("z") ; the local z takes on the value of ; the global z z = a +b +z ; computes the local z as a sum z ; output of the "local" z endp x = 1 y = 2 z = 3 test(x, y) ; runs the procedure test with the ; values of x and y for the locals ; a and b, respectively, prints the ; local z z ; prints the global z
Contents of z [1,] 6 Contents of z [1,] 3We want to remark here that the existence of a global variable can be checked by
In
XploRe
, you have the possibility to let the execution of
one or several commands depend on a logical condition.
XploRe
is able to
check whether a certain condition is fulfilled or not and
then executes the relevant commands in either case.
Note that the
if
-
else
-
endif
construct only works within procedures.
For example: To
compute the square root of a number, you have to make sure that the
number is not negative. To this aim it is advisable to use the
following
if
-
else
-
endif
construction:
proc() = squareroot(a) if(a >= 0) ; if this condition is true, ; XploRe will execute the next ; commandline sqrt(a) ; computes the squareroot of a else ; in case the condition above is not ; fulfilled XploRe runs the else branch "number is negative" ; output of the else branch endif ; end of the if construction endp ; end of the procedure
You can check the effect if you call this procedure with a negative argument, e.g.
squareroot(-10) ; runs the procedure with value -10You obtain the following output:
Contents of _tmp [1,]"number is negative"
By running the procedure squareroot with a positive argument
squareroot(9) ; runs the procedure with value 9you obtain the desired result
Contents of sqrt [1,] 3Note that the
|
If you want to make more than two branching points within your program,
you may use the
switch
-
case
-
endsw
construction.
The following procedure can distinguish whether its argument is positive, negative or zero:
proc() = signum(x) ; defines a procedure named "signum" switch ; opens the switch branch case (x > 0) "positive number" ; output in the case that x > 0 break case (x < 0) "negative number" ; output in the case that x < 0 break default "number is zero" ; output in the case that x = 0 break endsw ; end of the switch branch endp ; end of the procedure
By calling it with different arguments
signum(10) ; runs the procedure with value 10 signum(-5) ; runs the procedure with value -5 signum(0) ; runs the procedure with value 0you obtain, respectively, the following results
Contents of _tmp [1,]"positive number" Contents of _tmp [1,]"negative number" Contents of _tmp [1,]"number is zero"
You may execute one or several commands repeatedly -- as long as
a certain condition is fulfilled. For this purpose
you have the
while
-
endo
loop at your disposal.
Note that the
while
-
endo
construct only works within procedures.
This kind of loop executes one or several commands as long as a logical condition is fulfilled. The following example explains how the factorial of a natural number can be computed using this loop:
proc(j) = factorial(x) ; defines a procedure named "factorial" j = 1 ; defines the variable j as 1 while (x >= 2) ; as long as this condition is fulfilled, ; XploRe executes the following commands j = j * x ; computes j as the product of j and x x = x - 1 ; reduces x by 1 endo ; end of the while loop endp ; end of the procedure
factorial(5) ; runs the procedure with value 5you obtain the factorial
Contents of j [1,] 120
Another possibility for looping inside
XploRe
procedures is provided by
the
[3]
do
-
until
construction.
As with the
while
-
endo
construct, the
do
-
until
works only within procedures.
In contrast to the
while
-
endo
loop,
the
do
-
until
loop executes
one or several commands
until a certain condition is fulfilled. Since the condition
will be checked at the end of the loop, it runs at least once.
An example follows:
proc(j) = factorial(x) ; defines a procedure named "factorial" j = 1 ; defines the variable j as 1 do ; opens the do loop j = j *x ; computes j as the product of j and x x = x -1 ; reduces x by 1 until (x < 2) ; if the condition is not fulfilled, ; the loop will be run again endp ; end of the procedure
Calling the procedure with argument 5
factorial(5) ; runs the procedure with value 5produces the desired result:
Contents of j [1,] 120
Both the input and output parameters of a procedure quantlet are in fact lists. For more information on lists, see Matrix Handling (16).
Due to this list concept, all input and output parameters can be
optional. The existence of input parameters can be checked with
the
exist
command. Table 17.1
gives all possible return values for
exist
.
|
Consider the following example:
proc(a,b)=myquant3(x,y) error(exist("x")<>1, "input x is not numeric!") if (exist("y")==0) ; y does not exist y=0 endif switch case (exist("y")==2) ; if y is a string a=x break case (exist("y")==1) ; if y is numeric a=x b=y break default; error(1, "y is neither numeric nor string!") break endsw endp
The switch environment produces different results for the cases that y is string or numeric, respectively. We added an error message for the case that y is neither string nor numeric. You may now test the procedure with different input values:
result=myquant3(1,2) resultgives
Contents of result.a [1,] 1 Contents of result.b [1,] 2This means that the resulting output object is a list comprising the components result.a and result.b, which contain just the input values.
We can also call myquant3 without specifying the input y, i.e.
result=myquant3(1) resultThe result is similar, except that the missing y value is replaced by 0:
Contents of result.a [1,] 1 Contents of result.b [1,] 0
In the case that a string input y is used, the result is again different:
result=myquant3(1,"hallo") resultproduces only one output
Contents of result.a [1,] 1
To be on the safe side, we assign the output always to the same
variable result. This captures the case of two outputs as
well as of one output.
The function
exist
can be used again to check whether
the output variable result contains valid component
result.b. For our last example
exist(result.b)yields
Contents of exist [1,] 0which indicates that the component result.b is empty.
You have the opportunity to give to the user some hints about problems
which occurred when the program is run. With the
error
and
warning
commands, you can transmit messages to the user
of the program.
Both commands check whether a certain condition is true (equal to 1) or not (equal to 0). If the condition is true, a window will be displayed containing a message that has been specified within the command. If the condition is false, the program continues with the next command.
The
error
command displays the error box and stops immediately if the
given condition is fulfilled. All data and
changes to variables that have not been saved before this moment will
be lost.
proc() = test(x) ; defines a procedure error(x<0,"Negative argument!") ; displays an error box containing the ; specified text and stops the program ; in case x is negative sqrt(x) ; computes the square root in case the ; preceding command did not lead to ; a break of the program endp ; end of the procedure
test(-4) ; runs the procedure with value -4will display only this error message:
If you do not want to stop the program immediately after checking
a problem, you can use
the
warning
command. In this case there is no data loss.
If the condition in the
warning
command is fulfilled, the program
continues and shows a warning box after it finishes:
proc() = test(x) ; defines a procedure warning(x<0,"Negative argument!") ; displays a warning box containing the ; specified text in case x is ; negative at the end of the program sqrt(abs(x)) ; computes the squareroot of abs(x), ; whatever the above command found ; about x endp ; end of the procedure
test(-9) ; runs the procedure with value -9will produce the result
Contents of sqrt [1,] 3accompanied with the warning