
M Tutorial
(Part 3)
By
Chris Bonnici
Two or More
Both procedures and functions can take more than one
parameter. A comma separates each parameter. When dealing
with multiple parameters, the method of how parameters
are assigned to values in the calling module is by
position; i.e. the first value is assigned to the first
parameter, the second value to the second parameter, etc.
This is known as parameter passing by position.
MSM supports a dynamic type of parameter passing not very
common in other programming languages. The examples that
follow will demonstrate.
PROC003Þ;Parameter Characteristics - ACB -
July 1997
Þ;M Web Magazine @
http://www.geocities.com/SiliconValley/7041/mwm.html
Þ;You are using this program
at your own risk
Þ;
ÞW #,"1. You have passed
",$$HOWMANY("A","B","C"),"
parameter(s) to the function"
ÞW !,"2. You have passed
",$$HOWMANY(1,2,3)," parameter(s) to the
function"
ÞW !,"3. You have passed
",$$HOWMANY("A",66)," parameter(s) to
the function"
ÞW !,"4. You have passed
",$$HOWMANY("A")," parameter(s) to
the function"
ÞW !,"5. You have passed
",$$HOWMANY()," parameter(s) to the
function"
ÞQ
Þ;*** EOR ***
HOWMANY(PARAM1,PARAM2,PARAM3,PARAM4)Þ;Returns
parameter(s) to the calling module the number of
parameters defined.
ÞN CNT
ÞS CNT=0
ÞI $D(PARAM1) S CNT=CNT+1
ÞS:$D(PARAM2) CNT=CNT+1
ÞS:$D(PARAM3) CNT=CNT+1
ÞI $D(PARAM4) S CNT=CNT+1
ÞQ CNT
From PROC003 we can conclude the following:
- One can pass a variable number of parameters to
the procedure or function. In our program we pass
anything between 0 and 3.
- Parameters are not type bound (just like M). In
our example program, we sometimes pass character
strings, then pass numbers.
The function HOWMANY uses the function $DATA
($D) to check if a parameter has been set. If it
is, the function variable CNT is incremented.
Finally CNT is returned to the calling program.
$D is very important if the number of
parameters can vary. Trying to reference a parameter that
does not exist will result in an error. This method helps
prevent such an outcome.
What is the maximum
number of parameters PROC003 can take? Modify the
main program to verify your answer.
PROC004Þ;Parameter Characteristics - ACB -
July 1997
Þ;M Web Magazine @
http://www.geocities.com/SiliconValley/7041/mwm.html
Þ;You are using this program
at your own risk
Þ;
ÞW #,"1. You have passed
",$$HOWMANY("A","B","C","D"),"
parameter(s) to the function"
ÞW !,"2. You have passed
",$$HOWMANY("A","","C","D"),"
parameter(s) to the function"
ÞW !,"3. You have passed
",$$HOWMANY("A","B","C","D","E"),"
parameter(s) to the function"
ÞQ
Þ;*** EOR ***
HOWMANY(PARAM1,PARAM2,PARAM3,PARAM4)Þ;Returns
parameter(s) to the calling module the number of
parameters defined.
ÞN CNT
ÞS CNT=0
ÞI $D(PARAM1) S CNT=CNT+1
ÞS:$D(PARAM2) CNT=CNT+1
ÞS:$D(PARAM3) CNT=CNT+1
ÞI $D(PARAM4) S CNT=CNT+1
ÞQ CNT
In this program we show you some no-dos. You
cant pass more values than there are parameters.
You cant leave a parameter undefined. Try changing
line $$HOWMANY("A","","C","D")
to $$HOWMANY("A",,"C","D").
You get a syntax error.
So what happens if one needs to pass the first, third
and forth parameter but not the second? "Teach"
your function what an empty parameter is. One easy way to
do it is to pass null values as we did in our
example. The problem here is that even though it is empty
the parameter is still defined and $D will
correctly report it.
Modify the HOWMANY function
in PROC004 so that it also ignores parameters that
are equal to null. Hint: For each parameter first
check that it is defined ($D) then
check for null. Use two separate IF
commands IF $D(
IF
.
One Way?
As we demonstrated in PROC001 parameters are
one way. The calling module passes a value to the called
routine, but this value is not returned back. We shall
now explain how to make parameters pass values both in
and out.
PROC005Þ;Parameter Characteristics - ACB -
July 1997
Þ;M Web Magazine @
http://www.geocities.com/SiliconValley/7041/mwm.html
Þ;You are using this program
at your own risk
Þ;
Þ;*** main ***
ÞS VARIABLE=10
ÞW !!,"Before calling
procedure PROC, the value of VARIABLE in the calling
module is ",VARIABLE
ÞW !!!,"After calling
procedure PROC, the value of VARIABLE in the calling
module is ",VARIABLE
ÞQ
Þ;*** EOR ***
PROC(VARIABLE)ÞD
SETBGCOL^COLLIB("YELLOW")
ÞW !!!,?10,"Just entered
procedure PROC. Value of VARIABLE is ",VARIABLE
ÞS VARIABLE=VARIABLE+1
ÞW !!,?10,"After adding 1
to VARIABLE in procedure PROC, value of VARIABLE is
",VARIABLE
ÞD
SETBGCOL^COLLIB("BLACK")
ÞQ
We took PROC001 and changed only one line (we
have coloured it differently, as it might be difficult to
see). To make a parameter in-out, in the calling module
simply precede the variable name with the period. The
output you get when you run PROC005 is
Before calling procedure
PROC, the value of VARIABLE in the calling module is 10
Just
entered procedure PROC. Value of VARIABLE is
10
After
adding 1 to VARIABLE in procedure PROC, value
of VARIABLE is 11
|
After calling
procedure PROC, the value of VARIABLE in the calling
module is 11
Everything else remains the same.
Different programming languages link the variable and
parameter in an in-out scenario differently. Let us
analyze how M does it.
PROC006Þ;Parameter Characteristics - ACB -
July 1997
Þ;M Web Magazine @
http://www.geocities.com/SiliconValley/7041/mwm.html
Þ;You are using this program
at your own risk
Þ;
Þ;*** main ***
ÞS VARIABLE=10
ÞW !!,"Before calling
procedure PROC, the value of VARIABLE in the calling
module is ",VARIABLE
ÞD PROC(.VARIABLE)
ÞW !!!,"After calling
procedure PROC, the value of VARIABLE in the calling
module is ",VARIABLE
ÞQ
Þ;*** EOR ***
PROC(PARAM)ÞD
SETBGCOL^COLLIB("YELLOW")
ÞW !!!,?10,"Just entered
procedure PROC. Value of PARAM is ",PARAM
ÞW !,?5,"(Value of
VARIABLE in main is ",VARIABLE,")"
P10ÞS PARAM=PARAM+1
ÞW !!,?10,"After adding 1
to PARAM in procedure PROC, value of PARAM is
",PARAM
ÞW !,?5,"(Value of
VARIABLE in main is ",VARIABLE,")"
ÞD
SETBGCOL^COLLIB("BLACK")
ÞQ
Weve modified the procedure PROC in the
program PROC005 slightly to report the value of VARIABLE
in the calling module. In order to "see"
the value of VARIABLE, weve had to change
the name of the parameter. Within PROC we report
the value of VARIABLE. As soon as PARAM is
incremented, VARIABLE is incremented as well. This
means that the variables are linked (in actual fact, the
procedure parameter points to the memory location holding
the passed variable).
Before we conclude on this topic, there is one thing
you should remember with in-out parameter passing; you
can only perform this type of operation with variables
and will get an error if you attempt this with literals
(string or numeric). Why?
Modify PROC003 so that
function HOWMANY is changed from a function to a
procedure with in-out parameter passing.
You are writing a function that regulates the
temperature inside a compartment within a liquid
cooled supercomputer. Your function will control a
coolant release valve through an in-out parameter.
The formula for calculating the amount of coolant is V
= 10 * t / 10000, where V is the valve
setting and t is the temperature. Your
function must work out V and return it back to the
calling module within the second parameter of the
function. It must also return the string "Red:
Shutdown" if t > 1000, "Yellow: Switch
some of the CPUs off" if t > 750. All
lesser values of t should cause the function to
return the string "Green: Temperature OK".
This is to be done via the QUIT command.
Goodbye
Next time we will start delving into intrinsic
function, that is those functions that are standard in M.
Each M implementation has a number of functions that
provide quite a lot of functionality. We have already had
to use some functions in the past, but now we will go
through them in a proper and thorough manner.
Before we signoff we would like to re-remind you that
in programming practice is an essential factor to
mastering the syntax of any language. So get those
fingers moving. If you have any code of your own you
would like to share with others, please send it over to
us at mwm@mcenter.com.
We will print any code we think is appropriate.
Boolean Variables
Variables in M are untyped meaning that what
can be stored within them does not have to be
defined before. A program may set the variable
A=10 meaning that A is storing a number after
which the contents of A are changed to
"Hello World" (a string). In this
section we are going to talk a bit about Boolean
variables. These variables are named after the
mathematician George Boole. This man was
fascinated by the two numbers 0 and 1 (and as
some texts claim) in these numbers he saw the
absence and presence of God).
A Boolean variable is a switch variable. If we
place a 1 in it we mean that the variable is
"on". A 0 would be equivalent to
"off". When using properly
named variables, Boolean variables can make your
programs easy to understand and maintain.
This little game (Lander) should help you
understand how you can use Boolean Variables
effectively.
BOOL001Þ;Boolean Variables - ACB - Feb
1997
Þ;M Web Magazine @
http://www.geocities.com/SiliconValley/7041/mwm.html
Þ;You are using this
program at your own risk
Þ;
ÞW #,/CUP(1,1),"A
- Left | S - Right | W - Up | Z - Down"
ÞD LAND
ÞQ
Þ;*** EOR ***
LANDÞN
CRAFT,X,Y,FUEL,GRAVITY,FALL,FLYING,KEYREAD
Þ;The $RANDOM function
adds a touch of variability
ÞS
FUEL=100,GRAVITY=1,FALL=0,X=$RANDOM(79)+1,Y=1,CRAFT="@"
ÞS FLYING=1
;The craft is still in air
L10ÞI 'FLYING
D SCORE(FUEL,FALL,X) Q ;Quit if the craft is not
flying
ÞW
/CUP(24,1),/EL(2),"Fuel: ",FUEL,"
| Fall: ",FALL,/CUP(24,40),"BASE"
ÞW /CUP(Y,X),CRAFT
Þ;Get the ASCII key
press (causes screen not to echo)
ÞR
/CUP(24,79),*KEYREAD:1
ÞW /CUP(Y,X),"
" ;Erase craft position
ÞS:KEYREAD=65
X=X-1,FUEL=FUEL-1
ÞS:KEYREAD=83
X=X+1,FUEL=FUEL-1
ÞS:KEYREAD=87
Y=Y-2,FALL=FALL-3,FUEL=FUEL-3 ;Moving 'UP'= dec
Row position
ÞS:KEYREAD=90
Y=Y+1,FALL=FALL+2,FUEL=FUEL-1 ;Moving 'DOWN'= inc
Row position
Þ;Play Gravity
ÞS Y=Y+1
ÞS
FUEL=FUEL-1,FALL=FALL+1
Þ;Check if craft moved
off screen
ÞS:X<1 X=79
ÞS:X>79 X=1
ÞS:Y<1 Y=1
ÞS:Y=24 FLYING=0
;Hit the ground
ÞS:FUEL<1 FLYING=0
;Out of Fuel. Can't Fly
ÞS:FALL>50 FLYING=0
;Too Fast. Craft tumbles to ground
ÞW /CUP(Y,X),CRAFT
ÞG L10
Þ;*** EOR ***
SCORE(FUEL,FALL,LANDPOS)Þ;Tells User if s/he has won.
The winner must still have fuel, land at a fall
of less than 10 and land in position 40-43
ÞN WONGAME
ÞS WONGAME=1
;Assume player has won
ÞS:LANDPOS<40!(LANDPOS>43)
WONGAME=0
ÞS:FUEL=0 WONGAME=0
ÞS:FALL>10 WONGAME=0
ÞI WONGAME
W /CUP(12,30),"YOU WON"
ÞE W
/CUP(12,30),"YOU LOST"
ÞQ
|

|
Showcase
your work here
If you
would like to send in your M-related code, simply
attach a description to it, zip it up and send it
to us. The description should list the files in
the archive, installation notes, what the program
does and copyright information. Please clarify if
your submission is shareware / trialware /
freeware and other information you see
appropriate.
When e-mailing information for this section
please set the subject line to MWM Programs. The
e-mail address is mwm@mcenter.com.
|
E&OE


|