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. ## 4.1 Text 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.
`$ txt` | `# $ txt` | `+/ txt = LF`
    55
    1
    2
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 `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`
       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
    )
`Celsius 32 212` | `1 + Celsius 32 212`
    0 100
    1 101
Let us look at this definition more closely. ### 4.3.1 Heading 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". ### 4.3.2 Meaning 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.` (letter-y dot). This "argument variable" is always named `y.` in a monadic function. (In a dyadic function, as we shall see below, the right argument is always named `y.` and the left is `x.`) ### 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
    )
`3 posdiff 4` | `4 posdiff 3`
    1
    1
### 4.3.6 One-Liners 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.
    )
We see:
`volume 2 3 4` | `volume 2 3`
    24
    ERROR
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.

NEXT
Table of Contents
Index

Copyright © Roger Stokes 2004. This material may be freely reproduced, provided that this copyright notice is also reproduced.

last updated 17 July 2004