Fifty Shades of J/Chapter 2
- @ (atop), @: (at), & (bond/compose), &. (under), &: (appose), -: (match), ^. (log), -. (less), [ (left), ] (right), %. (matrix inverse/divide), ~ (passive conjunction), b. (basic characteristics), hook, fork, conjunctions, bridge hook, rank, rank inheritance, mean, geometric mean, harmonic mean, moments, normalization, transformations, valence.
Composition lies at the heart of the J language, and is based on the use of conjunctions, understanding which involves appreciation of the concept of rank. ‘Compose’ in a general sense means “make a composite verb from two others”, but ‘composition’ also extends to the broader range of forming composite objects using explicit conjunctions, and also implicit ones as in the case of hook and fork.
Joining nouns and verbs
The simplest use of conjunctions is to join a noun to a verb in either order to form a new verb, something which is a familiar part of the fabric of natural language. For example, ‘daydream’ is a verb whose meaning cannot be fully conveyed by using ‘day’ or ‘dream’ separately, and the same applies to compound verbs such as ‘headhunt’, ‘facelift’, ‘datestamp’, etc.
(-&2) 6 7 4 5 (2&-) 6 7 _4 _5
where the composite verbs in parentheses could be thought of as ‘take-two-from’ and ‘take-from-two’.
Compositions of two verbs are possible as in ‘sleepwalk’, ‘tumbledry’, ‘stirfry’, and again in each case the composition has an extra layer of meaning which exceeds the sum of its two constituents. For example the familiar technique of multiplying numbers by adding their logarithms, and then using anti-logarithms to obtain the final result. The monadic verb ^ means “raise e to the power”, and its inverse ^. means “get the natural logarithm”. Powers and logarithms to other bases are obtained by applying these verbs in their dyadic forms with the base as left argument. To compose (&) logs with addition gives the logarithm of a product, for example
2 +&^. 3 1.79176
gives the sum of the natural logarithms of 2 and 3 to give the logarithm of 6, and the multiplication process can be completed by using under (&.) :
2 +&.^. 3 6
Both ‘verb-noun’ and ‘noun-verb’ cases are examples of bonding. In function terms 'under' gives (g⁻¹f g) rather than just (f g). Thus (<:&*:) n means n2-1 whereas (<:&.*:) n means √(n2-1). If the verbs are switched, (*:&<:) n means (n-1)2 while (*:&.<:) n means (n-1)2+1 .
The atop conjunction
Sometimes in programming it is useful to start a sequence of counting integers at 1 rather than 0 - this is a basic application of @
int=.>:@i. NB. integers from 1 to y int 4 1 2 3 4 int 2 3 1 2 3 4 5 6
If the constituent verbs are reversed, incrementing comes first and the effect is to change the argument of i. and hence the shape of the result:
(i.@>:) 4 0 1 2 3 4
Also, since i. has monadic rank 1, while the composition i.@>: has monadic rank 0, then for this to work with a list argument, the composition should use at (@:) as discussed below, i.e.
(i.@:>:) 2 3 0 1 2 3 4 5 6 7 8 9 10 11
Atop and hook
The primitive verb | returns the absolute value or values of the items in a numeric list. Thus >./@| returns the maximum absolute value in the list.
maxabs=.>./@:| maxabs 2 7 _11 9 11
Now use this composed verb as the right argument of a hook, which is itself a form of composition without an explicit symbol. %maxabs divides all the list items by the maximum absolute value, so that
scales a list so that the largest absolute value is 1.
normalise 2 7 _11 9 0.181818 0.636364 _1 0.818182
Atop and at
The essence of atop and at is sequencing, in the sense in which lines are sequenced in conventional programming languages. Indeed the presence of many @s and @:s in a J expression is often an indication that the purpose would be more clearly achieved by rewriting the line in a simpler explicit multi-line style. Sequencing can take place in possible ways. Returning to the analogy of ‘stirfry’, two interpretations of this composition are possible; either every morsel is fried and immediately stirred, that is the verbs ‘stir’ and ‘fry’ are fused, or alternatively the frying is applied to everything, and the result is passed to the stirring process. Such distinctions necessarily involve the concept of verb rank.
Some verbs always enforce processing at the level of atomic elements (scalars), even if their arguments are of higher rank, in which case the result is obtained by an appropriate extension from the simple scalar case. The commonest verbs of this kind are the dyadic arithmetic and logic verbs:
+ - * % ^ >. <. +. and *.
Such verbs are called rank-zero verbs. Verb rank may differ in monadic and dyadic cases, example monadic ~: (Nub Sieve) is not a rank-zero verb since it has a different dyadic meaning (Not Equal). In general a verb possesses three verb ranks, one associated with the monadic case, and the other two with the left and right arguments of the dyadic case. Verb rank often underlines an aspect of a verb which is already part of its semantic description. For example the monadic verb $ (shape of) always returns a shape list, that is a rank 1 object, and so the dyadic form (reshape) is constrained to have a shape list as its left argument. The left verb rank is thus 1. A similar condition applies for the dyadic verb |. (shift). %. (matrix inverse) has a verb rank of 2. The three ranks of a verb are obtained as
% b.0 0 0 0 %. b.0 2 _ 2
The left rank of %. is infinite because matrix division places no rank restriction on its numerator. Apart from verbs such as plus=.+ which are mere transliterations of primitive verbs, most defined verbs have infinite rank because it would require a dynamic algorithm to work out true verb rank on each application, and infinite verb rank is always a ‘safe’ assumption. The principal distinction in the present discussion is between rank-zero verbs and non-rank-zero verbs because this leads to an important variant form of composition.
In the phrase
1 2 3(+/@-)2 _1 0 1
the leftmost of the two composed verbs plus insert is constrained to operate at the same rank level as that of minus. Informally +/ fuses into -, which has verb rank zero, and since the +/ of a scalar is simply the scalar itself. The manner in which u binds closely with or ‘tracks’ v in u@v is called rank inheritance.
However with at (@:), the verb u does not inherit the rank of v. With +/@:-, the linkage between u and v is thus less tight, allowing the +/ to operate at a level which is dictated by the rank of the result of v rather than by its own verb rank, so that 1 2 3(+/@:-)2 results in -1 + 0 + 1= 0. More generally rank inheritance applies for @, but not for @:.
Rank inheritance distinctions are important in cases such as the hook +/@-mean where mean=.+/%# which is a fork. Compositions are resolved as soon as a verb is found to the right of the conjunction on a left-to-right scan, and so the above phrase is equivalent to (+/@-)mean, that is add the mean to each item separately. For the reasons just given, +/ operates at rank zero, and so +/ does nothing. On the other hand the phrase +/@(-mean) has (–mean), a hook, as its rightmost verb which is of infinite rank, so that +/ is free to operate at its natural rank of 1, returning a scalar sum which, in the case of the sum of mean deviations, has the value 0 for all numeric lists. For the composed verb +/@:(-mean), the parentheses make no difference to the result, because @: inhibits rank inheritance. The following sequence sums this up :
(+/@-mean)i.5 _2 _1 0 1 2 (+/@(-mean))i.5 0 (+/@:-mean)i.5 0 (+/@:(-mean))i.5 0
Left and right verbs
Two superficially trivial, but nevertheless important verbs are [ (Left) and ] (Right). The fork is another form of composition without explicit symbols. [,] transforms a pair of arguments into a two-item list, and the fork ],[ transforms them into the same list in reverse order. These verbs often have to be used in conjunction with @ (Atop) when, for example, one of the transformations in a dyadic fork uses only one of the two arguments. For example, suppose that the xth moment about the mean of a numeric list y is required, that is the average of the values of mean-adjusted y raised to the power x :
mdev=.-mean moment=.mean@:((mdev@])^[) 2 moment t=.4 5 2 1 2.5 3 moment t 0
In such cases the passive conjunction which switches arguments gives a neater solution :
moment=.mean@:^~mdev 2 moment t=.4 5 2 1 2.5
In the verb -.&i. incorporating -. (Less) is used to remove the items of i.x from i.y, wherein x and y denote the left and right arguments of the verb.
12(-.&i.)3 NB. integers from 3 to 11 3 4 5 6 7 8 9 10 11
In making this into a defined verb :
to=.-.&i.~,] 3 to 12 3 4 5 6 7 8 9 10 11 12
the passive conjunction (~) again switches arguments and ] makes the right argument inclusive. Applications of ~ often involve what I choose to call the ‘bridge hook’ of which an example is $~$. The expression 0($$)a returns a 0-list whatever the value of a whereas 0($~$)a switches the 0 to be right argument and thus returns an array of 0s in the shape of a, a much more useful idiom!
The appose conjunction
The Appose conjunction (&:) and the Under conjunction (&.:) provide for & and &. the same release from rank inheritance as @: does for @ . Compare
mean&% 1 2 3 4 NB. mean inherits rank 0 1 0.5 0.333333 0.25 mean&.% 1 2 3 4 NB. division followed by inverse, inherited rank = 0 1 2 3 4 mean&:%1 2 3 4 NB. no rank inheritance 0.520833
Using &: the harmonic mean (that is the reciprocal of the mean of reciprocals) and geometric mean are given by
% mean&:% 1 2 3 4 NB. or more concisely mean&.:% 1.92 ^mean&:^. 1 2 3 4 NB. or more concisely mean&.:^ 2.21336
Here is another example of presence/absence of rank inheritance
]a=.2$<i.2 3 NB. a is a 2-list ┌─────┬─────┐ │0 1 2│1 2 3│ │3 4 5│4 5 6│ └─────┴─────┘ ,&>a 0 1 2 3 4 5 0 1 2 3 4 5 ,&:>a 0 1 2 3 4 5 0 1 2 3 4 5
When dyadic verbs are concerned, define
]b=.2$<10+i.2 3 NB. b is another 2-list ┌────────┬────────┐ │10 11 12│10 11 12│ │13 14 15│13 14 15│ └────────┴────────┘
a,&> b is a,every b, that is open and join item by item and then assemble the result. However (a,&:>b) means open both items and then join, that is (a,&:>b)-:(>a),(>b)
(a,&>b);(a,&:>b) ┌────────┬────────┐ │ 0 1 2│ 0 1 2│ │ 3 4 5│ 3 4 5│ │10 11 12│ │ │13 14 15│ 0 1 2│ │ │ 3 4 5│ │ 0 1 2│ │ │ 3 4 5│10 11 12│ │10 11 12│13 14 15│ │13 14 15│ │ │ │10 11 12│ │ │13 14 15│ └────────┴────────┘
The conjunction Bond (&) joins a noun and a verb (or a verb and a noun) as in -&2
(-&2)4 5 6 2 3 4
In the above example the bonded verb is monadic. However bonded verbs can also be dyadic in which case the following rule applies :
x m&n y <––> m&v^:x y
see Essay #10: Bonding is Power – how Interesting for details.
Five explicit verb-verb compositions have been discussed so far. In each case the leftmost verb u can be thought of as the prime verb, and v as a transformation. The primary decision is whether the required composition is, in mathematical terms, of the form u(v y), in which case use At (@:) or Atop (@), or if it is of the form (v x)u(v y) use Compose (&) or Appose (&:), with the additional possibility of Under (&. or &.:) to incorporate an inverse transformation. Be careful to distinguish between valences, that is monadicity or dyadicity, since the valences of the component verbs are a separate issue from that of their compounds.
At and Appose are the most basic composition verbs and follow the rules:
|Compound Monadic||Compound Dyadic|
|At||(u@:v)y means u(v y)||x(u@:v)y means u(x v y)|
|Appose||(u&:v)y means u(v y)||x(u&:v)y means (v x)u(v y)|
Atop and Compose obey the rules as At and Appose but invoke rank inheritance. This is discussed in more detail in Essay #6: Punctuation and Rank.
|Compound Monadic||Compound Dyadic|
|Atop||(u@v) y is (u@:v)"(mv) y||x (u@:v) y is x (u@:v)"(lv,rv) y|
|Compose||(u&v) y means (u&:v)"(mv) y||x (u&v) y means x (u@:v)"(mv,mv) y|
where mv is the monadic rank of verb v, lv,rv is a list of the left and right ranks of verb v.
under requires that v is monadic
|Compound Monadic||Compound Dyadic|
|Under||(u&.v) y is v^:_1 (u v y)||x (u&.v) y is v^:_1 ((v x) u (v y))|
@ and & enforce rank inheritance, @: and &: do not. For monadic composed verbs the pairs of conjunctions (@,&) and (@:,&:) are interchangeable. The monadic composed verbs u@v and u&v are thus equivalent, and their effect is also the same as that of issuing u and v directly on a command line, for example
(!i.2 2) ; ((!@i.)2 2) ; ((!&i.)2 2) ┌───┬───┬───┐ │1 1│1 1│1 1│ │2 6│2 6│2 6│ └───┴───┴───┘
In terms of transformations :
|u@v||transformation v uses x and y, then u is applied to the result with rank inherited from v|
|u@:v||transformation v uses x and y, then monadic u is applied to the result without rank inheritance|
|u&v||u is applied at the same rank level as v following a transformation v of all arguments.|
|u&.v||monadic u is applied after a transformation v of all arguments, and then the inverse transformation of v is applied.|
|u&:v||u is applied without rank inheritance following a transformation v involving all arguments.|
A hook (u v) is also a composition of two verbs, for which the two possible results are
x u (v y) NB. hook used dyadically y u (v y) NB. hook used monadically
so that v is always applied monadically.
Because an absent left argument is given the default value y, the composed verb arising from a hook is always inherently dyadic.
A fork (u w v) is a composition of three verbs, for which the two possible results are:
(x u y) w (x v y) NB. fork used dyadically (u y) w (v y) Nb. fork used monadically
For monadic arguments the composed verbs resulting from Atop and Compose are identical. The dyadic cases can be thought of as
|u@v||u is applied to a transformation v which uses both arguments|
|u&v||u is applied after a transformation v has been made to both arguments separately|
|(u v)||u is applied following a transformation v to the right argument only|
Varying or omitting conjunctions can give rise to substantial differences between superficially similar phrases. This is demonstrated by the following table of algebraic equivalents obtained by applying the above rules:
|%^ (hook) means||y/exp(y) = y exp(-y)||x/exp(y) = x exp(-y)|
|%@^ and %@:^ mean||1/exp(y) = exp(-y)||1/xy = x-y|
|%&^ and %&:^ mean||1/exp = exp(-y)||exp(x)/exp(y) = exp(x-y)|
|%&.^ means||ln(1/exp(y)) = ln(exp(-y)) = -y||ln(exp(x)/epx(y)) = ln(epx(x-y)) = x-y|
Atop, At and Compose, Under, Appose along with the Dot conjunction (i.e. ‘space dot’, inner product – see Essay #9: Power Steering extra for examples) are the most common conjunctions in J, whose rules, along with those of hook, fork and cap can be summarized (r.i. = rank inheritance, sp = space which must precede dot) :
|u&v||u(v y)||(v x)u(v y)||(v monadic) with r.i.|
|u&:v||u(v y)||(v x)u(v y)||(v monadic) without r.i.|
|u&.v||v⁻¹u(v y)||v⁻¹(v x)u(v y)||(v monadic) with r.i.|
|u&.:v||v⁻¹u(v y)||v⁻¹(v x)u(v y)||(v monadic) without r.i.|
|u@v||u(v y)||u(x v y)||(u monadic) with r.i.|
|u@:v||u(v y)||u(x v y)||(u monadic) without r.i.|
|hook (u v)||y u(v y)||x u(v y)||(v monadic)|
|fork (u w v)||(u y)w(v y)||(x u y)w(x v y)||(w dyadic)|
|u .v (note the space before the dot)||u y||u(x v y)||(u monadic) without r.i.|
|[: u v||u(v y)||u(x v y)||(u monadic) without r.i.|
When cap is used to make a hook into a pseudo-fork, [: g f is equivalent to g@:f rather than g@f.
int =.>:@i. NB. integers from 1 to y maxabs =.>./ @: | NB. maximum absolute value normalise =.%maxabs NB. max abs value in list = 1 mean =.+/%#. NB. mean of a list mdev =.-mean NB. mean deviation moment =.mean@:^~mdev NB. xth moment of a list to =:-.&i.~,] NB. integers from x to y