Help / Learning / Ch 4: Scripts and Explicit Functions
Chapter 4: Scripts and Explicit Functions
What is called a "script" is a sequence of lines of J where the whole sequence can be replayed on demand to perform a computation. The themes of this chapter are scripts, functions defined by scripts, and scripts in files.
Here is an assignment to the variable txt:
txt =: 0 : 0 What is called a "script" is a sequence of lines of J. )
The expression 0 : 0 means "as follows", that is, 0 : 0 is a verb which takes as its argument, and delivers as its result, whatever lines are typed following it, down to the line beginning with the solo right- parenthesis.
The value of txt is these two lines, in a single character string. The string contains line-feed (LF) characters, which cause txt to be displayed as several lines. txt has a certain length, it is rank 1, that is, just a list, and it contains 2 line-feed characters.
txt What is called a "script" is a sequence of lines of J.
Let us say that txt is a "text" variable, that is, a character string with zero or more line-feed characters.
4.2 Scripts for Procedures
Here we look at computations described as step-by-step procedures to be followed. For a very simple example, the Fahrenheit-to-Celsius conversion can be described in two steps. Given some temperature T say in degrees Fahrenheit:
T =: 212
then the first step is subtracting 32. Call the result t, say
t =: T - 32
The second step is multiplying t by 5%9 to give the temperature in degrees Celsius.
t * 5 % 9 100
Suppose we intend to perform this computation several times with different
values of T.
We could record this two-line procedure as a script which can be replayed on demand. The script consists of the lines of J stored in a text variable, thus:
script =: 0 : 0 t =: T - 32 t * 5 % 9 )
Scripts like this can be executed with the built-in J verb given by the expression 0 !: 1 which we can call, say, do.
do =: 0 !: 1
Here the expression 0 !: 1 can be understood as the verb produced by giving a left argument of 0 and a right argument of 1 to the conjunction !: (exclamation colon, called the "Foreign Conjunction" ). !: offers a set of utility functions or system services which are organised into groups of verbs. For more details, see the Dictionary
In this example the left argument of 0 specifies the script-executing group, and the right argument of 1 picks out a particular member of that group, namely a verb to execute the script to the end regardless of errors, and displaying the execution on screen.
If we now enter do script we should now see the lines on the screen just as though they had been typed in from the keyboard:
do script t =: T - 32 t * 5 % 9 100
We can run the script again with a different value for T
T =: 32 do script t =: T - 32 t * 5 % 9 0
4.3 Explicitly-Defined Functions
Functions can be defined by scripts. Here is an example, the Fahrenheit-to-Celsius conversion as a verb.
Celsius =: 3 : 0 t =: y - 32 t * 5 % 9 )
The main features of this definition are:
The function is introduced with the expression 3 : 0 which means: "a verb as follows". (By contrast, recall that 0 : 0 means "a character string as follows").
The colon in 3 : 0 is a conjunction. Its left argument (3) means "verb". Its right argument (0) means "lines following". For more details, see Chapter 12. A function introduced in this way is called "explicitly-defined", or just "explicit".
The expression Celsius 32 212 applies the verb Celsius to the argument 32 212, by carrying out a computation which can be described, or modelled, like this:
y =: 32 212 t =: y - 32 t * 5 % 9 0 100
Notice that, after the first line, the computation proceeds according to the script.
4.3.3 Argument Variable(s)
The value of the argument (32 212) is supplied to the script as a variable named y . This "argument variable" is named y in a monadic function. (In a
dyadic function, as we shall see below,
the left argument is named x and the right is y)
4.3.4 Local Variables
Here is our definition of Celsius repeated:
Celsius =: 3 : 0 t =: y - 32 t * 5 % 9 )
We see it contains an assignment to a variable t. This variable is used only during the execution of Celsius. Unfortunately this assignment to t interferes with the value of any other variable also called t, defined outside Celsius, which we happen to be
using at the time.
t =: 'hello' Celsius 212 100 t 180
We see that the variable t with original value ('hello') has been
changed in executing Celsius.
To avoid this undesirable effect, we declare that t inside Celsius is
to be a strictly private affair,
distinct from any other variable called t.
For this purpose there is a special form of assignment, with the symbol =. (equal dot). Our revised definition becomes:
Celsius =: 3 : 0 t =. y - 32 t * 5 % 9 )
and we say that t in Celsius is a local variable, or that t is local
By contrast, a variable defined outside a function is said to be global. Now we can demonstrate that in Celsius assignment to local variable t
does not affect
any global variable t
t =: 'hello' Celsius 212 100 t hello
The argument-variable y is also a local variable. Hence the evaluation
(Celsius 32 212) is more accurately modelled by the computation:
y =. 32 212 t =. y - 32 t * 5 % 9 0 100
4.3.5 Dyadic Verbs
Celsius is a monadic verb, introduced with 3 : 0 and defined in terms of the single argument y. By contrast, a dyadic verb is introduced with 4 : 0. The left and right arguments are always named x and y respectively Here is an example. The "positive difference" of two numbers is the larger
minus the smaller.
posdiff =: 4 : 0 larger =. x >. y smaller =. x <. y larger - smaller )
A one-line script can be written as a character string, and given as the right argument of the colon conjunction.
PosDiff =: 4 : '(x >. y) - (x <. y)' 4 PosDiff 3 1
4.3.7 Control Structures
In the examples we have seen so far of functions defined by scripts, execution begins with the expression on the first line, proceeds to the next line, and so on to the last.
This straight-through path is not the only path possible. A choice can be made as to which expression to execute next.
For an example, here is a function to compute a volume from given length, width and height. Suppose the function is to check that its argument is given correctly as a list of 3 items (length, width and height). If so, a volume is computed. If not, the result is to be the character-string 'ERROR'.
volume =: 3 : 0 if. 3 = # y do. * / y else. 'ERROR' end. )
Everything from if. to end. together forms what is called a "control structure". Within it if. do. else. and end. are called "control words". See Chapter 12 for more on control structures.
4.4 Tacit and Explicit Compared
We have now seen two different styles of function definition. The explicit style, introduced in this chapter, is so called because it explicitly mentions variables standing for arguments. Thus in volume
the variable y is an explicit mention of an argument.
By contrast, the style we looked at in the previous chapter is called "tacit", because there is no mention of variables standing for arguments. For example, compare explicit and tacit definitions of the positive-difference function:
epd =: 4 : '(x >. y) - (x <. y)' tpd =: >. - <.
Many functions defined in the tacit style can also be defined explicitly, and vice versa. Which style is preferable depends on what seems most natural, in the light of however we conceive the function to be defined. The choice lies between breaking down the problem into, on the one hand, a scripted sequence of
steps or, on the other hand,
a collection of smaller functions.
The tacit style allows a compact definition. For this reason, tacit functions lend themselves well to systematic analysis and transformation. Indeed, the J system can, for a broad class of tacit functions, automatically compute such transformations as inverses and derivatives.
4.5 Functions as Values
A function is a value, and a value can be displayed by entering an expression. An expression can be as simple as a name. Here are some values of tacit and explicit functions:
- & 32 +-+-+--+ |-|&|32| +-+-+--+ epd +-+-+-------------------+ |4|:|(x >. y) - (x <. y)| +-+-+-------------------+ Celsius +-+-+-----------+ |3|:|t =. y - 32| | | |t * 5 % 9 | +-+-+-----------+
The value of each function is here represented as a boxed structure. This is the default, but we can choose from several other possibilities: see Chapter 27. For now I will mention only the "linear representation", which shows a function as a sequence of characters which could be typed in again to produce the function. We can switch the session to to show functions in the linear representation by entering:
and we see for example:
epd 4 : '(x >. y) - (x <. y)'
In the following chapters, values of functions will often be shown in this linear representation.
4.6 Script Files
We have seen scripts (lines of J) used for definitions of single variables:
By contrast, a file holding lines of J as text can store many definitions.
Such a file is called a script file, and its usefulness is that all its definitions together can be executed by reading the file.
Here is an example. Using a text-editor of your choice, create a file on your computer, containing 2 lines of text like the following.
squareroot =: %:
z =: 1 , (2+2) , (4+5)
A J script file has a filename ending with .ijs by convention, so suppose the file is created (in Windows) with the full pathname
c:\temp\myscript.ijs for example.
Then in the J session it will be convenient to identify the file by defining a variable F say to hold this filename as a string.
F =: 'c:\temp\myscript.ijs'
Having created this 2-line script file, we can execute it by typing at the keyboard:
0!:1 < F
and we should now see the lines on the screen just as though they had been
typed from the keyboard.
squareroot =: %: z =: 1 ,(2+2), (4+5)
We can now compute with the definitions we have just loaded in from the file:
z 1 4 9 squareroot z 1 2 3
The activities in a J session will be typically a mixture of editing script
loading or reloading the definitions from script files, and initiating
at the keyboard. What carries over from one session to another is only the script files. The state, or memory, of the J system itself disappears at the end of the session, along with all the definitions entered during the session. Hence it is a good idea to ensure, before ending a J session, that any script file is up to date, that is, it contains all the definitions you wish to preserve.
At the beginning of a session the J system will automatically load a designated script file, called the "profile". (See Chapter 26 for more details). The profile can be edited, and is a good place to record any definitions of your own which you find generally useful. We have now come to the end of Chapter 4 and of Part 1. The following chapters will treat, in more depth and detail, the themes we have touched upon in Part 1.
The examples in this chapter
were executed using J version 701.
This chapter last updated 29 Jul 2012
Copyright © Roger Stokes 2012. This material may be freely reproduced, provided that this copyright notice is also reproduced.