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.
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 0 !: 111 which we can call, say, do.
do =: 0 !: 111 do script
We should now see the lines on the screen just as though they had been typed in from the keyboard:
t =: T - 32 t * 5 % 9 100
We can run the script again with a different value for T
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 )
Let us look at this definition more closely
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. To demonstrate:
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 to Celsius. 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 of (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.
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 above, 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. Other representations are available: see Chapter 27.
4.6 Script Files
We have seen scripts (lines of J) used for definitions of single variables: text variables or functions. 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 files, loading or reloading the definitions from script files, and initiating computations 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.
Table of Contents
This chapter last updated 25 Mar 2006 .
The examples in this chapter
were executed using J version 601 beta.
Copyright © Roger Stokes 2006. This material may be freely reproduced, provided that this copyright notice is also reproduced.