Vocabulary/fork

From J Wiki
Jump to navigation Jump to search

>> <<   Back to: Vocabulary Thru to: Dictionary

[x] (f g h) y Fork Invisible Conjunction

Rank Infinity -- operates on [x and] y as a whole -- WHY IS THIS IMPORTANT?

(f g h) makes a single new verb out of the three verbs: f g h. This verb can then be applied to arguments. The form (f g h) y) creates a new verb and immediately executes it:

  • Monad: f gets applied to noun: y
  • Monad: h gets applied to noun: y
  • Dyad: g combines the two results
   y=: 3 3 3 4 3  NB. noun: a time-series
   f=: +/         NB. verb: sum its arg: y
   h=: #          NB. verb: count its arg: y
   g=: %          NB. verb: divide the two results
   (f g h) y      NB. the mean value of series: y
3.2
   mean=: f g h   NB. assign the fork (f g h) to a name
   mean y         NB. does it work? Yes...
3.2

Details

Three adjacent verbs, or a noun followed by two verbs, when not followed by a noun (as in [x] (f g h) y), create a fork that separately executes f and h on the argument(s) of the fork, and then executes g dyadically on those results:

If f is a noun, its "execution" simply produces its value, as discussed below.

We are talking here about after modifiers have been applied, so that there are only verbs and nouns. (%&2 + 2&*) is a fork made from the three verbs %&2, +, and 2&* .

x (f g h) y ⇔ (x f y) g (x h y)       result
(f g h) y ⇔ (f y) g (h y)                |
                                         g
                                        / \
                                       /   \
                                      /     \
                                     f       h
                                   [/]\    [/]\
                                  [x]  y  [x]  y
   (+/ % #) 1 2 3 4 5   NB. A fork
3
   (+/ 1 2 3 4 5) % (# 1 2 3 4 5)   NB. equivalent computation
3

There is a huge difference between

   %: +/ *: 3 4  NB. Pythagorean theorem: square, then total, then square root
5

and

   (%: +/ *:) 3 4  NB. ???
10.7321 17.7321
     11      18

The first is simply right-to-left execution of *: 3 4 followed by +/ 9 16 followed by %: 25 . The second creates a fork out of the verbs (%: +/ *:) and then executes that according to the definition above, producing who-knows-what.


A Beginner's Error

J beginners often code a fork by mistake.

The beginner might spot an attractive sequence of three verbs in sample code, e.g.  %: +/ *: (viz. the Pythagorean calculation above) and copy this sequence to make a named verb

   length=: %: +/ *:   NB. the length of vector y

But the result may be unexpected:

   length 3 4
10.7321 17.7321
     11      18

The assignment to the name length created a fork because the three verbs were not followed by a noun.

One way to think of this is that when substituting for a name, like length here, you'd put parentheses around the substituted phrase to avoid strange effects – which is typical math practice.

For example, let y=x+2

Substituting for y in z=y^2^+2y+5 yields z=(x+2)^2^+2(x+2)+5

However, in the sentence

   length 3 4

substituting for the name length in this manner yields

   (%: +/ *:) 3 4

You have accidentally created a fork. To do what you intend, insert: @: between the three verbs

   length=: %: @: (+/) @: *:

Here is an equivalent construct using two forks instead of @:

   length=: [: %: [: +/ *:
   length=: [: %: ([: +/ *:)   NB. redundant parens to hilite the 2 forks

ASIDE:
The substitution model described above is not at all how J actually executes sentences. But it gives the right answers.


Common uses

1. Compute the mean value of time-series y by dividing the sum over y

   +/y

by the tally of y

   #y
   mean=: +/ % #
   mean 3 3 3 4 3
3.2

More Information

1. If the fork itself is executed dyadically, i. e. there is a left argument (x (f g h) y), verbs f and h are executed dyadically as x f y and x h y. If there is no x argument to the fork ((f g h) y), f and h are executed as f y and h y.

2. When a fork appears in a tacit definition, where it is creating a verb (and therefore not being executed on a noun), it doesn't have to be enclosed in parentheses:

   mean =: +/ % #
   mean 1 2 3
2

3. In a normal sentence that is executing on noun arguments to produce a noun result, a fork must be enclosed in parentheses, as discussed above.

4. The sequence noun-verb-verb, not followed by a noun, produces a NVV fork which is like a regular fork except that the noun simply produces its value regardless of the arguments to the fork.

 result of [x] (N g h) y
    |
    g
   / \
  N   h
    [/]\
   [x]  y

   5 (3 + *) 6
33

5. A sequence of more than 3 verbs in a row (not followed by a noun) is processed from right to left and becomes a sequence of forks. If the sequence has an even number of verbs, the last one on the left is part of a final hook.

Odd-numbered positions (numbering from the right starting at 1), except the rightmost, may be filled by nouns, as in NVV forks.


Odd number of verbs: numbering the verbs from the right, odd-numbered verbs are all executed on the original arguments of the overall fork (monadically if the overall fork has no x argument, dyadically if it does), and even-numbered verbs are all executed dyadically on results of adjacent odd-numbered verbs.

result<----v12<----v10<----v8<-----v6<-----v4<-----v2
           /       /       /       /       /       / \
          /       /       /       /       /       /   \
         /       /       /       /       /       /     \
       v13     v11      v9      v7      v5      v3      v1
      [/]\    [/]\    [/]\    [/]\    [/]\    [/]\    [/]\
     [x]  y  [x]  y  [x]  y  [x]  y  [x]  y  [x]  y  [x]  y

   2 (3 * [ + >. - <.) 5
15

result<---- * <---- + <---  -
           /       /       / \
          /       /       /   \
         /       /       /     \
        3       [       >.      <.
               / \     / \     / \
              2   5   2   5   2   5

Even number of verbs: numbering the verbs from the right, odd-numbered verbs are all executed monadically on the original y; even-numbered verbs except the leftmost are executed dyadically on the results of odd-numbered verbs; the leftmost verb (which is part of a hook) is executed dyadically, with a left argument of x or y.

result<---v14<---v12<-v10<-v8<-v6<-v4<-v2
          /      /    /   /   /   /   / \
      x or y    v13  v11 v9  v7  v5  v3  v1
                |    |   |   |   |   |   |
                y    y   y   y   y   y   y

   2 1 3 (+   4 <. >./ - <./) 3 1 4 1 5 9
6 5 7

result<--- + <-- <. <- -
          /     /     / \
       2 1 3   4    >./ <./
                     |   |
                     |   3 1 4 1 5 9
                     3 1 4 1 5 9

6. Any odd-numbered verb (counting from the right) except the rightmost may be replaced by [: (Cap) to produce a capped fork. The [: is not a verb. Its presence in ([: g h) indicates that its tine of the fork is nonexistent: it is not executed, and moreover g is executed as a monad.

      result              result
        |                   |
normal  g           capped  g
fork   / \          fork     \
      /   \                   \
     /     \             /     \
    f       h          [:       h
  [/]\    [/]\        [/]\    [/]\
 [x]  y  [x]  y      [x]  y  [x]  y

   (3 * {. + [: i. [: >: {: - {.) 4 8  NB. integers between 4 and 8, tripled
12 15 18 21 24

result <------ * <- + <- i. <- >: <- -
              /    /                / \
             /    /    /     /     /   \
            3    {.   [:    [:    {:    {.
                 |    |     |     |     |
                4 8  4 8   4 8   4 8   4 8

7. In the fork (f g h), h is executed before f (as is appropriate given J's general right-to-left execution model), but this behavior is not guaranteed, so don't rely on it.


Related Primitives

Hook (u v), Atop (u@v), At (u@:v), Compose (u&v), Appose (u&:v), Under (u&.v), Under (u&.:v)


u (p q [r]) [v] Modifier train Invisible Modifier

Use the valid sequences consisting of words p and q [and r] in the table below [and combinations thereof] to define a modifier (adverb or conjunction) tacitly, that is, without reference to operand(s) u [and v].

It is never necessary to use a phrase of this form; explicit modifier definitions perform the same function. But "invisible" modifiers offer a sophisticated language of function composition.


Details

The table below lists the valid sequences that can be used directly (that is, without parentheses) within a modifier train, along with the interpretation for each.

In most cases, the sequence yields a derived entity that subsequently acts on operands u (and v, in the case of conjunctions).

If no part of speech is shown for the derived entity, the sequence executes immediately and does not wait for operands.

Sequence Train Part of speech Interpretation Quick Search
N0 V1 N2 no executed to produce a noun NVN
V0 V1 V2
N0 V1 V2
verb verb creates a fork VVV
NVV
V0 V1 C2 verb† conj V0 V1 (u C2 v) VVC
V0 N1 C2 no† adv (... V0 N1) C2 VNC
A0 V1 V2 modifier adv (u A0) V1 V2 AVV
C0 V1 V2 modifier conj (u C0 v) V1 V2 CVV
C0 V1 C2 modifier conj (u C0 v) V1 (u C2 v) CVC
A0 A1 V2 modifier conj (u A0) (v A1) V2 AAV
A0 A1 A2 modifier adv ((u A0) A1) A2 AAA
C0 A1 A2 modifier conj ((u C0 v) A1) A2 CAA
N0 C1 N2
N0 C1 V2
V0 C1 V2
V0 C1 N2
no executed to produce any part of speech
N0 C1 A2 modifier† adv N0 C1 (u A2) NCA
N0 C1 C2 modifier† conj N0 C1 (u C2 v) NCC
V0 C1 A2 modifier† adv V0 C1 (u A2) VCA
V0 C1 C2 modifier† conj V0 C1 (u C2 v) VCC
A0 C1 N2 modifier* adv (u A0) C1 N2 ACN
A0 C1 V2 modifier* adv (u A0) C1 V2 ACV
A0 C1 A2 modifier conj (u A0) C1 (v A2) ACA
A0 C1 C2 modifier conj (u A0) C1 (u C2 v) ACC
C0 C1 N2 modifier* conj (u C0 v) C1 N2 CCN
C0 C1 V2 modifier conj (u C0 v) C1 V2 CCV
C0 C1 A2 modifier conj (u C0 v) C1 (v A2) CCA
C0 C1 C2 modifier conj (u C0 v) C1 (u C2 v) CCC
N0 A1
V0 A1
no executed to produce any part of speech
N0 C1 adv N0 C1 u NC
V0 N1 no executed to produce a noun VN
V0 V1 verb verb creates a hook VV
V0 C1 adv V0 C1 u VC
A0 V1 modifier adv (u A0) V1 AV
A0 A1 modifier adv (u A0) A1 AA
A0 C1 modifier adv (u A0) C1 u (adverbial hook) AC
C0 N1 * adv u C0 N1 CN
C0 V1 * adv u C0 V1 CV
C0 A1 modifier conj (u C0 v) A1 CA
C0 C1 modifier conj (u C0 v) (u C1 v) CC

* indicates the combination of a conjunction with a single argument on its right, forming an adverb.
† indicates the combination of a conjunction with an argument on its left. This also forms an adverb, but the formation of the operand inherits the long left scope of modifiers. This extended scope is a consequence of the limited "leftmost stack words" in rules 6 and 7 of J's Parsing Table.


Common uses

   While=: ^:^:_

   >:While(<&7) 0  NB. increment while less than 7
7

More Information

See: More discussion and examples of Modifier Trains.