
Chapter 3: Defining FunctionsJ comes with a collection of functions builtin; we have seen a few, such as * and +. In this section we take a first look at how to put together these builtin functions, in various ways, for the purpose of defining our own functions. 3.1 RenamingThe simplest way of defining a function is to give a name of our own choice to a builtin function. The definition is an assignment. For example, to define square to mean the same as the builtin *: function: square =: *: square 1 2 3 4 1 4 9 16 The point here is that we might prefer our own name as more memorable. We can use different names for the monadic and dyadic cases of the same builtin function: Ceiling =: >. Max =: >.
3.2 InsertingRecall that (+/ 2 3 4) means 2+3+4, and similarly (*/ 2 3 4) means 2*3*4. We can define a function and give it a name, say sum, with an assignment: sum =: + / sum 2 3 4 9 Here, sum =: +/ shows us that +/ is by itself an expression which denotes a function. This expression +/ can be understood as: "Insert" (/) applied to the function + to produce a listsumming function. That is, / is itself a kind of function. It takes one argument, on its left. Both its argument and its result are functions. 3.3 Terminology: Verbs, Operators and AdverbsWe have seen functions of two kinds. Firstly, there are "ordinary" functions, such as + and *, which compute numbers from numbers. In J these are called "verbs". Secondly, we have functions, such as /, which compute functions from functions. Functions of this kind will here be called "operators", to distinguish them from verbs. (The word "operator" is not used in the official J literature. However, in this book, for the purpose of explanation, it will be convenient to have a single word, "operator", to describe any kind of function which is not a verb. Then we may say that every function in J is either a verb or an operator.) Operators which take one argument are called "adverbs". An adverb always takes its argument on the left. Thus we say that in the expression (+ /) the adverb / is applied to the verb + to produce a listsumming verb. The terminology comes from the grammar of English sentences: verbs act upon things and adverbs modify verbs. 3.4 CommutingHaving seen one adverb, (/), let us look at another. The adverb ~ has the effect of exchanging left and right arguments.
The scheme is that for a dyad f with arguments x and y x f~ y means y f x For another example, recall the residue verb  where 2  7 means, in conventional notation, "7 mod 2". We can define a mod verb: mod =:  ~
Let me draw some pictures. Firstly, here is a diagram of function f applied to an argument y to produce a result (f y). In the diagram the function f is drawn as a rectangle and the arrows are arguments flowing into, or results flowing out of, the function. Each arrow is labelled with an expression.
Here is a similar diagram for a dyadic f applied to arguments x and y to produce (x f y).
Here now is a diagram for the function (f~), which can be pictured as containing inside itself the function f, together with a crossed arrangement of arrows. 3.5 BondingSuppose we wish to define a verb double such that double x means x * 2 . That is, double is to mean "multiply by 2". We define it like this: double =: * & 2 double 3 6 Here we take a dyad, *, and produce from it a monad by fixing one of the two arguments at a chosen value (in this case, 2). The & operator forms a bond between a function and a value for one argument. The bonding operation is also known as "currying". Instead of fixing the right argument we could fix the left. For example, suppose that the rate of sales tax is 10%, then a function to compute the tax, from the purchaseprice is: tax =: 0.10 & * tax 50 5 Here is a diagram illustrating function k&f. 3.6 Terminology: Conjunctions and NounsThe expression (*&2) can be described by saying that the & operator is a function which is applied to two arguments (the verb * and the number 2), and the result is the "doubling" verb. A twoargument operator such as & is called in J a "conjunction", because it conjoins its two arguments. By contrast, recall that adverbs are operators with only one argument. Every function in J, whether builtin or userdefined, belongs to exactly one of the four classes: monadic verbs, dyadic verbs, adverbs or conjunctions. Here we regard an ambivalent symbol such as  as denoting two different verbs: monadic negation or dyadic subtraction. Every expression in J has a value of some type. All values which are not functions are data (in fact, arrays, as we saw in the previous section). In J, data values, that is, arrays, are called "nouns", in accordance with the Englishgrammar analogy. We can call something a noun to emphasize that it's not a verb, or an array to emphasize that it may have several dimensions. 3.7 Composition of FunctionsConsider the English language expression: the sum of the squares of the numbers 1 2 3, that is, (1+4+9), or 14. Since we defined above verbs for sum and square, we are in a position to write the J expression as: sum square 1 2 3 14 A single sumofthesquares function can be written as a composite of sum and square: sumsq =: sum @: square sumsq 1 2 3 14 The symbol @: (at colon) is called a "composition" operator. The scheme is that if f and g are verbs, then for any argument y (f @: g) y means f (g y) Here is a diagram for the scheme:
At this point, the reader may be wondering why we write (f @: g) and not simply (f g) to denote composition. The short answer is that (f g) means something else, which we will come to. For another example of composition, a temperature in degrees Fahrenheit can be converted to Celsius by composing together functions s to subtract 32 and m tomultiply by 5%9. s =:  & 32 m =: * & (5%9) convert =: m @: s
For clarity, these examples showed composition of named functions. We can of course compose expressions denoting functions: conv =: (* & (5%9)) @: ( & 32) conv 212 100 We can apply an expression denoting a function, without giving it a name: (* & (5%9)) @: ( & 32) 212 100 The examples above showed composing a monad with a monad. The next example shows we can compose a monad with a dyad. The general scheme is: x (f @: g) y means f (x g y) For example, the total cost of an order for several items is given by multiplying quantities by corresponding unit prices, and then summing the results. To illustrate: P =: 2 3 NB. prices Q =: 1 100 NB. quantities total =: sum @: *
For more about composition, see Chapter 08. 3.8 Trains of VerbsConsider the expression "no pain, no gain". This is a compressed idiomatic form, quite comprehensible even if not grammatical in construction  it is not a sentence, having no main verb. J has a similar notion: a compressed idiomatic form, based on a scheme for giving meaning to short lists of functions. We look at this next. 3.8.1 HooksRecall the verb tax we defined above to compute the amount of tax on a purchase, at a rate of 10%. The definition is repeated here: tax =: 0.10 & * The amount payable on a purchase is the purchaseprice plus the computed tax. A verb to compute the amount payable can be written: payable =: + tax If the purchase price is, say, $50, we see:
In the definition (payable =: + tax) we have a sequence of two verbs + followed by tax. This sequence is isolated, by being on the righthand side of the assignment. Such an isolated sequence of verbs is called a "train", and a train of 2 verbs is called a "hook". We can also form a hook just by isolating the two verbs inside parentheses: (+ tax) 50 55 The general scheme for a hook is that if f is a dyad and g is a monad, then for any argument y: (f g) y means y f (g y) Here is a diagram for the scheme:
For another example, recall that the "floor" verb <. computes the wholenumber part of its argument. Then to test whether a number is a whole number or not, we can ask whether it is equal to its floor. A verb meaning "equaltoitsfloor" is the hook (= <.) : wholenumber =: = <.
3.8.2 ForksThe arithmetic mean of a list of numbers L is given by the sum of L divided by the number of items in L. (Recall that numberofitems is given by the monadic verb #.)
A verb to compute the mean as the sum divided by the number of items can be written as a sequence of three verbs: sum followed by % followed by # . mean =: sum % # mean L 6 An isolated sequence of three verbs is called a fork. The general scheme is that if f is a monad, g is a dyad and h is a monad then for any argument y, (f g h) y means (f y) g (h y) Here is a diagram of this scheme:
Hooks and forks are sequences of verbs, also called "trains" of verbs. For more about trains, see Chapter 09. 3.9 Putting Things TogetherLet us now try a longer example which puts together several of the ideas we saw above. The idea is to define a verb to produce a simple display of a given list of numbers, showing for each number what it is as a percentage of the total. Let me begin by showing you a complete program for this example, so you can see clearly where we are going. I don't expect you to study this in detail now, because explanation will be given below. Just note that we are looking at a a program of 8 lines, defining a verb called display and its supporting functions. NB. display verb: tabulate as percentages percent =: (100 & *) @: (% +/) round =: <. @: (+&0.5) comp =: round @: percent br =: ,. ; (,. @: comp) tr =: ('Data';'Percentages') & , reshape =: 2 2 & $ display =: reshape @: tr @: br To show that this verb displays the data as given and as computed percentages: display 15 30 15 +++ DataPercentages +++ 15 25  30 50  15 25  +++ The verb percent computes the percentages, dividing each number by the total, with the hook (% +/) and then multiplying by 100. To save you looking backwards and forwards, the definition of percent is repeated here: percent =: (100 & *) @: (% +/) To illustrate with simple data: data =: 3 5
Let us round the percentages to the nearest whole number, by adding 0.5 to each and then taking the floor (the integer part) with the verb <. The verb round is: round =: <. @: (+&0.5) Then the verb to compute the displayed values from the data is: comp =: round @: percent
Now we want to show the data and computed values in columns. To make a 1column table out of a list, we can use the builtin verb ,. (comma dot, called "Ravel Items").
To make the bottom row of the display, we define verb br as a fork which links together the data and the computed values, both as columns: br =: ,. ; (,. @: comp)
To make the top row of the display (the column headings), here is one possible way. The bottom row will be a list of two boxes. On the front of this list we stick two more boxes for the top row, giving a list of 4 boxes. To do this we define a verb tr: tr =: ('Data';'Percentages') & ,
All that remains is to reshape this list of 4 boxes into a 2 by 2 table, using the reshape verb defined as: reshape =: 2 2 & $ reshape tr br data +++ DataPercentages +++ 3 38  5 63  +++ and so we put everything together: display =: reshape @: tr @: br display data +++ DataPercentages +++ 3 38  5 63  +++ This display verb has two aspects: the function comp which computes the values (the rounded percentages), and the remainder which is concerned to present the results. By changing the definition of comp, we can display a tabulation of the values of other functions. Suppose we define comp to be the builtin squareroot verb (%:) . comp =: %: We would also want to change the columnheadings in the top row, specified by the tr verb: tr =: ('Numbers';'Square Roots') & , display 1 4 9 16 +++ NumbersSquare Roots +++  1 1   4 2   9 3  16 4  +++ In review, we have seen a small J program with some characteristic features of J: bonding, composition and a fork. As with all J programs, this is only one of the many possible ways to write it. This is the end of Chapter 3. 
Copyright © Roger Stokes 2001. This material may be freely reproduced, provided that this copyright notice is also reproduced.
last updated 05Jun01