# Chapter 12: Explicit Verbs

This chapter continues from Chapter 04 the theme of the explicit definition of verbs.

## 12.1 The Colon Conjunction

Recall from Chapter 04 the example of an explicit monad: the Fahrenheit-to-Celsius converter:

       ftoc =: 3 : 0
    z =. y. - 32
    z * 5 % 9
    )

The general scheme for an explicitly-defined function is to provide two arguments for the colon-conjunction, in the form

          type : body

The type is a number: type-3 functions are monadic verbs or ambivalent verbs, while type-4 functions are strictly dyadic verbs (that is, with no monadic case). The complete set of types is as follows:

0 | noun
1 | explicit adverb
2 | explicit conjunction
3 | explicit verb (monad or ambivalent)
4 | explicit verb (dyad)
13 | generated tacit verb

Rather than numbers, some people may prefer to use conventional pre-assigned names. The pre-assigned names and corresponding values are:

`noun` | `adverb` | `conjunction` | `verb` | `monad` | `dyad`

    0

    1

    2

    3

    3

    4

and additionally:

`def` | `define`

    +-+
    |:|
    +-+

    +-+-+
    |:|0|
    +-+-+

Thus the `ftoc` example could be also written as:

       ftoc  =: verb define
    z =. y. - 32
    z * 5 % 9
    )

In this chapter, we will be concerned only with types 3 and 4. For details of types 1 and 2 see Chapter 13 and for type 13 see Chapter 10.

### 12.1.1 Body Styles

The body of an explicit definition consists of one or more lines of text. There are several ways to provide the body. The example above, `ftoc`, shows what is often most convenient: lines introduced by a right argument of zero for the colon operator. A variation is where the body has only one line. Here the body is written as a string:

       ftoc2 =: 3 : '(y. - 32) * 5 % 9'

Another variation allows a multi-line function to be written compactly by embedding line-feeds. `LF` is predefined to be the line-feed character. Notice that the whole body must be parenthesized.

       ftoc3 =: 3 : ('z =: y. - 32', LF, 'z * 5 % 9')
       ftoc3
    +-+-+------------+
    |3|:|z =: y. - 32|
    | | |z * 5 % 9   |
    +-+-+------------+

Another variation uses a boxed list of lines (again with the body parenthesized):

       ftoc4 =: 3 : ('z =. y. - 32' ; 'z * 5 % 9')
       ftoc4
    +-+-+------------+
    |3|:|z =. y. - 32|
    | | |z * 5 % 9   |
    +-+-+------------+

A character array is also possible. Notice that these are not variations of syntax, but rather alternative expressions for constructing a data-structure acceptable as the right-argument of the colon operator.

An ambivalent function is presented by separating the monadic case from the dyadic with a line consisting of a solo colon. For example:

       log =: 3 : 0
    ^. y.    NB. monad
    :
    x. ^. y. NB. dyad
    )

`log` | `log 2.7182818` | `10 log 100`

    +-+-+------------------+
    |3|:|^. y.    NB. monad|
    | | |:                 |
    | | |x. ^. y. NB. dyad |
    +-+-+------------------+

    1

    2

## 12.2 Assignments

In this section we consider assignments, which are of significance in defining explicit functions.

### 12.2.1 Local and Global Variables

Consider the example

       foo =: 3 : 0
    L =.  y.
    G =:  y.
    L
    )

Here, the assignment of the form

`L =. expression`

causes the value of `expression` to be assigned to a local variable named `L`. Saying that `L` is local means that `L` exists only while the function `foo` is executing, and furthermore this `L` is distinct from any other variable named `L`. By contrast, the assignment of the form

`G =: expression`

causes the value of `expression` to be assigned to a global variable named `G`. Saying that `G` is global means that the unique variable `G` exists independently, in its own right.

To illustrate, we define two GLOBAL variables called `L` and `G`, then execute `foo` to show that the `L` mentioned in `foo` is not the same as global `L`, while the `G` mentioned in foo is the same as global G:

       L =: 'old L'
       G =: 'old G'

`foo` | `foo 'new'` | `L` | `G`

    +-+-+--------+
    |3|:|L =.  y.|
    | | |G =:  y.|
    | | |L       |
    +-+-+--------+

    new

    old L

    new

### 12.2.2 Local Functions

A local variable may be a noun, as we have seen, or it may be a locally defined function. A local function may be tacit or explicit, as in the following example

       foo =: 3 : 0
    Square  =. *:
    Cube    =. 3 : 'y. * y. * y.'
    Square y. + Cube y.
    )

       foo 2
    100

However, what we can't have is a local function defined by an inner script. Recall that a script is terminated by a solo right parenthesis, so we cannot have one script inside another. Instead, we could use an alternative form for the body of an inner function, such as `scale` in the following example:

       FTOC =: 3 : 0
       line1   =. 'k =. 5 % 9'
       line2   =. 'k * y.'
    scale =. 3 : (line1 ; line2)
    scale y. - 32
    )

       FTOC 212
    100

One final point on the topic of inner functions. A local variable is either strictly local or strictly global. Consider the following:

       K =: 'hello '

       zip =: 3 : 0
    K =. 'goodbye '
    zap =. 3 : 'K , y.'
    zap y.
    )

       zip 'George'
    hello George

We see that there is a global `K` and a local `K`. The inner function `zap` uses the global `K` because the `K` which is local to `zip` is not local to `zap`.

### 12.2.3 Multiple and Indirect Assignments

J provides a convenient means of unpacking a list by assigning different names to different items.

`'day mo yr' =: 16 10 95` | `day` | `mo` | `yr`

    16 10 95

    16

    10

    95

Instead of a simple name to the left of the assignment, we have a string with names separated by spaces.

A variation uses a boxed set of names:

`('day';'mo';'yr') =: 17 11 96` | `day` | `mo` | `yr`

    17 11 96

    17

    11

    96

The parentheses around the left hand of the assignment force evaluation as a set of names, to give what is called "indirect assignment". To illustrate:

       N =: 'DAY';'MO';'YR'

`(N) =: 18 12 97` | `DAY` | `MO` | `YR`

    18 12 97

    18

    12

    97

As a convenience, a multiple assignment will automatically remove one layer of boxing from the right-hand side:

`(N) =: 19;'Jan';98` | `DAY` | `MO` | `YR`

    +--+---+--+
    |19|Jan|98|
    +--+---+--+

    19

    Jan

    98

### 12.2.4 Unpacking the Arguments

Every J function takes exactly one or exactly two arguments - not zero and not more than two. This may appear to be a limitation but in fact is not. A collection of values can be packaged up into a list, or boxed list, to form in effect multiple arguments to the J function. However, the J function must unpack the values again. A convenient way to do this is with the multiple assignment. For example, the familiar formula to find the roots of a quadratic `(a*x^2) +(b*x)+c`, given the vector of coefficients `a,b,c` might be:

       rq =: 3 : 0
    'a b c' =: y.
    ((-b) (+,-) %: (b^2)-4*a*c) % (2*a)
    )

`rq 1 1 _6` | `rq 1 ; 1 ; _6`

    2 _3

    2 _3

## 12.3 Flow of Control

In an explicit definition, the sequence of execution of the lines is often the first line, then the second, and so on through to the last. The result of the whole function is the result computed by the last line to be executed. This sequence may be varied by the presence of CONTROL WORDS, such as `if.` or `while.` .

### 12.3.1 if.

Here is an example of a function in which a choice is made about which lines to execute. The function classifies the temperature of porridge.

       CTP =: 3 : 0
    if.   y. > 80
    do.   'too hot'
    else. 'OK'
    end.
    )

       CTP 70
    OK

This example shows the pattern:

`if. T do. B1 else. B2 end.`

meaning: if the expression `T` evaluates to "true", then execute the expression `B1`, and otherwise execute the expression `B2`.

More generally, `T`, `B1` and `B2` may be what are called BLOCKS. A block is a sequence of zero, one, or more expressions, the sequence being surrounded by control words. Thus in the example above, the block `(y.> 80)` is delimited by the control words `if.` and `do.`. Here is another example, to form the sum of a list, where the T-block and the B2-block each consist of a sequence.

       sum =: 3 : 0
    if.   length  =. # y.
          length  = 0
    do.   0
    else. first =. {. y.
          rest  =. }. y.
          first + sum rest
    end.
    )

       sum 1 2 3
    6

Here we see that the value of the T-block (true or false) is the value of the last expression in the sequence, `(length = 0)`

The expressions in a block may themselves be (inner) blocks, as shown by another function to classify the temperature of porridge:

       ClaTePo =: 3 : 0

    if. y. > 80  do.      'too hot'
    else.
          if. y. < 60 do. 'too cold'
          else.           'just right'
          end.
    end.
    )

       ClaTePo 70
    just right

This example also shows that control-words serve to terminate J expressions just as end-of-line terminates J expressions. Hence control-words allow some freedom in laying out a definition for the most pleasing appearance.

A neater variation of the last example is:

       CLATEPO =: 3 : 0
    if.     y. > 80 do. 'too hot'
    elseif. y. < 60 do. 'too cold'
    elseif. 1       do. 'just right'
    end.
    )

       CLATEPO 70
    just right

The second scheme for `if.` is:

       if.     T1 do. B1
       elseif. T2 do. B2
        ...
       elseif. Tn do. Bn
       end.

Notice that according to this scheme, if all of the tests `T1` ... `Tn` fail, then none of the blocks `B1` .. `Bn` will be executed. Consequently we may wish to make `Tn` a catch-all test, with the constant value 1, as in the example of `CLATEPO` above.

### 12.3.2 while. and whilst.

In the general pattern

    while. T do. B end.

the block `B` is executed repeatedly so long as block `T` evaluates to true. Here is an example, a version of the factorial function:

       fact =: 3 : 0
    r =. 1
    while. y. > 1
    do.    r  =. r * y.
           y. =. y. - 1
    end.
    r
    )

       fact 5
    120

The variation `whilst. T do. B end.` means

    B
    while. T do. B end.

that is, block `B` is executed once, and then repeatedly so long as block `T` is true.

### 12.3.3 for

The pattern

`for_a. A do. B. end.`

means: for each item `a` in array `A`, execute block `B`. Here `a` may be any name; the variable `a` takes on the value of each item of `A` in turn. For example, to sum a list:

       Sum =: 3 : 0
    r =. 0
    for_term. y. do.  r =. r+term end.
    r
    )

       Sum 1 2 3
    6

In addition to the variable `a` for the value of an item, the variable `a_index` is available to give the index of the item. For example, this function numbers the items:

       f3 =: 3 : 0
    r =. 0 2 $ 0
    for_item. y. do.  r =. r , (item_index; item) end.
    r
    )

       f3 'ab';'cdef';'gh'
    +-+----+
    |0|ab  |
    +-+----+
    |1|cdef|
    +-+----+
    |2|gh  |
    +-+----+

Another variation is the pattern `for. A. do. B end.` which is similar except that the variables `a` and `a_index` are not available.

### 12.3.4 try.

Here we look at a way of handling errors. The scheme is that:

`try. B1 catch. B2 end.`

means: execute block `B1`. If for any reason `B1` fails, then `B1` is abandoned and `B2` executed instead. If `B1` succeeds, then `B2` is not executed. The following example is a function which tests that the argument supplied is valid.

       foo =: 3 : 0
    try. *: y.  catch. 'argument must be numeric' end.
    )

`foo 2` | `foo 'hello'`

    4

    argument must be numeric

### 12.3.5 goto and label

Given any name, such as `qwerty`, then two control-words may be constructed: `label_qwerty.` and `goto_qwerty.` . (Notice that both end with a dot).

The meaning of `label_qwerty.` is that it provides a name for a block which begins at the point where `label_qwerty.` occurs. This block ends at the end of the whole explicit definition. The purpose of naming a block in this way is that `goto_qwerty.` means that the named block is to be executed next. Here is an example: yet another factorial function.

       facto =: 3 : 0
    r =. 1
    label_again.
       if. y. < 2 do. goto_done. end.
       r  =. r * y.
       y. =. y. - 1
       goto_again.
    label_done.
    r
    )

       facto 5
    120

### 12.3.6 break, continue and return

to be supplied

This is the end of Chapter 12.

NEXT
Table of Contents

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

last updated 16 Aug 2002