home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Archive Magazine 1995
/
ARCHIVE95.iso
/
discs
/
pipeline
/
abacus
/
p_line
/
Custom02
/
ReadMe
< prev
Wrap
Text File
|
1992-08-08
|
16KB
|
320 lines
%OP%VS4.13 (28-Apr-92), Gerald L Fitton, R4000 5966 9904 9938
%OP%DP0
%OP%IRY
%OP%PL0
%OP%HM0
%OP%FM0
%OP%BM0
%OP%LM4
%OP%FX160
%OP%FY160
%OP%FS10000
%OP%PT1
%OP%PDPipeLine
%OP%WC1026,2262,184,1748,0,0,0,0
%CO:A,72,72%
%C%Custom Functions from the Beginning - Part 2
%C%by Gerald L Fitton
Keywords:
4ProL Custom Function Variables Sequence Fitton
Introduction to '4ProL'
This is the second tutorial article of a series which, I hope, will
help you to get to grips with one of the new features of PipeDreamá4,
custom functions. The first part of the series is in the directory
Custom01 and the [ReadMe] file describes how a custom function is
'called' and how it can 'return' a value. If you wish to use custom
functions then you need to learn '4ProL', the PipeDreamá4 custom
function programming language.
Let's see a custom function at work. If you have a deep screen mode
then it is preferable to use it because it will make it easier to see
substantial parts of the custom function without losing the document
which 'calls' it. If not, then you will have to use mode 12 and scroll
through the documents as is necessary. I am using the Atomwide VIDC
mode 102 with an Eizo 9070S multiscan and an A540 Archimedes. This
monitor-mode combination has a screen depth of over 50 lines and a
screen width of over 130 system font characters when using PipeDream.
Mode 12 is about half that width and depth, a quarter of the area!
Double click on the file [Add] and you will find that you load to the
screen not only [Add] but a dependent document which I have called
[c_Add] containing three custom functions. I would have liked to make
[c_Add] wider but I have deliberately limited its width to 72
characters so that it will fit a mode 12 screen. To keep within 72
characters I have had to use short names such as "p_01" for the
variables. This is not good programming practice. I would have
preferred to use a long meaningful name such as "first_parameter".
Because PipeDreamá4 saves the position of a PipeDream document on the
screen and the position of the cursor within the document, what you
should find is that [Add] is visible and alive (a yellow top bar) with
the cursor in slot [Add]B7. If not then position the pointer on the
number in [Add]B7 (it should be the number 2 unless you've modified the
file) and click the mouse select (left) button. You should see the
same number in the formula line (at the top of the document just to the
right of the cross and tick). Tap some other number, say 9, and then
tap <Return>. If all goes well then, as well as [Add]B7 changing to 9,
all three numbers in the range [Add]B10 to [Add]B12 increase.
For the moment we are going to concentrate on the custom function
'called' from [Add]B10. It is not a spectacular custom function. The
'result' returned to the slot [Add]B10 is (B7á+á1), one more than the
number in the slot [Add]B7. Change the value in [Add]B7 a few times
and convince yourself that the value in [Add]B10 is always 1 more than
the value in [Add]B7.
Now let's have a look at the content of slot [Add]B10. Place the
pointer over [Add]B10 and click select. The formula line does not show
the simple, non custom function way of adding 1 which would be
(B7á+á1); instead it shows the formula used to 'call' the custom
function, namely [c_Add]add_anything(B7).
The 'calling' formula is in three parts:
The first part - [c_Add] - is the name of the dependent document which
contains the custom function.
The second part - add_anything - is the name of the custom function
within [c_Add] which you can find in row 22 of the document [c_Add].
The third part - (B7) - is the slotref of the single piece of data
passed to [c_Add] for processing.
Returning the result
'Calling' the custom function - [c_Add]add_anything(B7) - from slot
[Add]B10 returns the result of the processing to the slot from which it
was called, [Add]B10.
If you place the cursor in [Add]B14 (which shows the number 1) you will
find that the formula line (just to the right of the cross and tick)
shows that the slot contains another 'call' to the same custom function
-á[c_Add]add_anything(0)á- but, instead of the parameter being a
slotref, it is the value 0. You can change the parameter (0) to (9) in
the formula line; when you tap <Return> you will find that the custom
function returns the 'result', 10 to the slot, [Add]B14, from which it
was called. The number returned is always one greater than the number
passed as a parameter to the custom function.
When testing a custom function sometimes it is revealing to 'call' the
function from a 'spare' slot using not a slotref as the parameter but a
value you want to test. We shall return to examples of this aid to
'debugging' in a later tutorial.
The custom function
What we haven't looked at yet is the custom function itself to see how
it adds one to the parameter and returns the 'result'. To do this we
must bring the custom function - [c_Add]add_anything - into view.
Make sure that the cursor is 'in' slot [Add]B7 and then (particularly
if you are using a 'small' screen mode such as mode 12) bring the
document [c_Add] to the front but leave [Add] as the document which is
'alive' (a yellow top bar). If the part of [c_Add] which is visible is
not rows 22 to 39 and columns A to C then use the vertical sliders or
scroll bars to achieve this.
Check that it is [Add] and not [c_Add] or this [ReadMe] which is alive
and that PipeDream's 'input focus' (where the next character typed will
appear) is in slot [Add]B7. After checking, you can confirm this most
easily by tapping a new number such as 7 followed by <Return>. If you
have done everything correctly then you will see that the values in
slots [c_Add]C28 and [c_Add]C31 change to 7 and 8 respectively.
Just as it was possible to add one to the contents of [Add]B7 much more
simply by entering (B7á+á1) into [Add]B10 instead of entering the
custom function, so would it have been possible to have simplified the
custom function itself to just two lines as we did in Custom01.
However, so that I can illustrate a few features of the '4ProL'
programming language, I have 'stretched out' the custom function to
span lines 22 to 39 of [c_Add] and columns A to C.
Let's look at the commands in detail and see how they process data.
Row 22 - ...function("add_anything","p_01:number")
In this custom function the '4ProL' command -á...functioná- has two
arguments. The first argument is the name of the custom function,
-á"add_anything"á- note that the name is included in inverted commas.
The second argument is the one and only parameter passed to the
function. You can pass many parameters each separated by a comma from
the next one. The name of every parameter must be enclosed in a pair
of inverted commas. If you want to pass a large number of values to a
custom function then it is 'better' (more understandable) to pass a
range or array. The name of the one parameter passed to
-á[c_Add]add_anythingá- is -áp_01á¡ and its 'type' has been declared
(after the colon) as a number. Because of this declaration, if you try
to pass anything other than a number to this function then an error
will be generated.
You do not have to declare the type of variable if you want to pass a
number sometimes and, say, a string on another occasion. Try typing
Fred (with or without inverted commas into [Add]B7 and you will find
that the error message -áString not expectedá- is returned to slot
[Add]B10. You will find the error message foreshortened in the body of
the [Add] document. If you want to read the full error message then
click the pointer in [Add]B10, then on the formula button (the italic f
just to the right of the PipeDreamá4 logo) and finally run the pointer
through the first menu option -áSlot 'B10' - Slot value - and you will
see the full error message displayed. This technique is particularly
useful when long error messages are generated.
Row 25 - ...set_value(B25,1)
Here is another convention which I recommend to you. I am using column
B as a 'workspace' for my custom function sheets. One major use for
this workspace is to 'store' the values of 'local' variables.
In this custom function I use slot [c_Add]B25 as storage for a 'local'
variable. The 'local' variable is the number which will be added to
the value taken by the parameter "p_01".
The '4ProL' command - set_value(B25,1) - writes the value 1 to the
space allocated to the 'local' variable [c_Add]B25.
Change the command to - set_value(B25,3) - and the custom function will
now add 3 to the number passed to it as a parameter. Remember that the
custom function is not executed until you 'call' it from [Add]B7 (see
above how to 'call' it).
Now here is something else you can do with this line which allows me to
introduce the concept of a 'global' variable.
Change the command to -áset_value(B25,[Add]B8) - and call the custom
function by changing [Add]B7. The value which is added to the
parameter is now the value of the 'global' variable in [Add]B8. Change
the value in [Add]B8 and notice that the value 'returned' to [Add]B10
has not changed. Are you surprised? 'Call' the custom again by
changing [Add]B7 and watch what happens.
Put [c_Add]A25 back to - set_value(B25,1) - or, if you have problems,
delete the document and reload it.
Row 28 - ...@p_01
This command assigns the current value of the parameter "p_01" to the
slot [c_Add]A28. I have included this so that you will see exactly how
to include parameters in custom functions. Notice that the inverted
commas have 'disappeared' and that the name of the parameter is
preceded by an @@ sign. The @@ sign converts a numeric parameter to a
number. See what happens to the parameter if you remove the @@ - the
three full stops in front of the p_01 disappear.
Row 31 - ...@p_01+B25
This '4ProL' command assigns the value of (@p_01+B25) to slot
[c_Add]A31. Experiment by changing the plus sign to a minus sign or,
indeed, any mathematical function of two variables.
Rows 34 to 36 - set_value(C28,A28) etc
These three rows are totally unnecessary but, if you do have a problem
understanding what is going on within a custom function (for example
if you have a 'bug'), then lines like this are invaluable. A
convention which I use for this purpose and which I recommend to you is
to assign values to the slot in column C corresponding to the values in
columns A or B.
Row 38 - ...result(A31)
The command - ...result - terminates the sequence of commands and
returns a value to the slot from which it was called, [Add]B10.
The custom function - [c_Add]use_slots
Use the scroll bars to make lines [c_Add]A58 to [c_Add]A82 visible on
the screen. This function is called from [Add]B11 and the 'result'
which is returned is the sum of the numbers in the two slots [Add]B7
and [Add]B8. Note that the two values in these slots are passed as two
parameters to the custom function.
It is bad practice to alter values of a parameter within a custom
function; one of the most important features of a parameter is that,
anywhere within the custom function you must be sure that it always
has the same value.
I know that the sum of two parameters can be done very simply with one
line such as -á...result(@@p_01+@@p_02) - but I have written the short
program in a way which illustrates the way of declaring 'local'
variables and altering their values. In this custom function I add one
to the first parameter and subtract one from the second. Of course the
parameters could be processed in much more complex ways before being
combined and the 'result' returned to the slot in [Add] from which the
custom function was called.
The two slots [c_Add]B65 & [c_Add]B66 are used as 'local' variables.
The values of the two parameters are assigned to these two 'local'
variables by the commands in slots [c_Add]A65 & [c_Add]A66.
As I indicated above, the reason why I have assigned the values of the
parameters to two 'local' variables is so that the values can be
changed. The commands in slots [c_Add]A69 &[c_Add]A70 do change the
values of the 'local' variables.
The values of the two 'local' variables are added in slot [c_Add]A73.
The 'result' is returned by the command in slot [c_Add]A82.
The custom function - [c_Add]use_names
This custom function is called from slot [Add]B12 and uses slots
[c_Add]A120 to [c_Add]A144. I have included this function as an
introduction to the use of a 'name' for a 'local' variable within a
custom function. Generally it is preferable to use a 'name' rather
than a slot (as in [c_Add]use_slots) when a 'local' variable is needed.
I recommend that you always use 'names' for 'local' variables as I am
doing here rather than use slots as in the previous custom function.
In a custom function a 'local variable name' must be declared only
once. It is good programming practice to declare all the local
variables you are going to use at the beginning of the custom function
as I have done here.
A 'name' is declared with the command -áset_name(name,slotref) as it is
in [c_Add]A123 & [c_Add]A124. When a 'name' is declared in a custom
function it is good practice to assign a slot in your workspace (I am
using column B for my workspace) rather than assign a dummy value to
the 'name'. In this case the slots B123 & B124 have been assigned to
the 'names' "n_01" and "n_02" respectively. After declaring the 'name'
of the 'local' variable you may assign a new value to that 'name' as
many times as you wish using the command -áset_value(name,value). When
you change the value of a name the value in the slot assigned to that
name in the workspace will also change.
The commands in slots A127 & A128 assign the values of the two
parameters, "p_01" & "p_02" to the two names "n_01" & "n_02". Notice
that when this command is executed new values of the 'names' are
relayed to and stored in the two slots B123 & B124. The command in
A138, -áset_value(C123C124,A123A124), is included to show that the
values in A123 & A124 are not changed by the commands in A127, A128,
A131 & A132! However, these last four commands do change the values of
the two 'local variable names' and the values in the slots B123 & B124.
Contrast the use of 'names' in this custom function with the use of
parameters in "use_slots". Values such as "p_01" have to be written as
@@p_01 to become a value whereas the 'name' "n_01" is a value when
written as n_01. The command set_name("name",slotref) requires
inverted commas around the 'name' because, within the set_name command,
"n_01" is a text string. The addition, n_01+n_02, in slot A135 does
not require inverted commas around the 'names' nor do the 'names' need
to be preceded by @@; n_01 is the value taken by the 'name' "n_01".
Summary
A custom function is a sequence of commands which start with a
-áfunctioná- command and end with a -áresultá- command. Once there is
a custom function within a document then the whole document is a custom
function document. Custom function documents behave differently from
'ordinary' documents - but they do not have a different file type!
Parameters can be passed to custom functions. They must retain their
identity and value throughout the custom function.
Names should be used for local variables rather than slots. Use the
-áset_nameá- command once only to assign a slot in the workspace to the
local variable name. Thereafter, to change the value of the local
variable, the -áset_valueá- command must be used and not the
-áset_nameá¡ command.
The next tutorial
In the next tutorial of this series I will introduce the concept of
making a decision, "Conditional execution". In the meantime, if you
wish to see how local variables are declared with the command
-áset_name("name",slotref)á- and then how the value of the named local
variable is changed with set_value("name",value) I suggest that you
have a look at the rather more advanced custom function you will find
in a directory Primes on the May 1992 PipeLine 4 disc.