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 (f g [h]) [v] Modifier train Invisible Modifier

A sequence of 2 or 3 words which computes a valid part-of-speech.

Use the valid sequences in the table below to combine verbs u f g [and h] [and v] for subsequent execution.

It is never necessary to use a phrase of this form. Visible modifier primitives can perform the same functions. But invisible modifiers offer a sophisticated language of function composition.


Details

In the table below, the train is interpreted as shown.

In most cases, the train 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 train executes immediately and does not wait for operands.

Train Part of speech Interpretation
N0 V1 N2 executed to produce a noun
V0 V1 V2
N0 V1 V2
verb creates a fork
V0 V1 C2 conj V0 V1 (u C2 v)
A0 V1 V2 adv (u A0) V1 V2
C0 V1 V2 conj (u C0 v) V1 V2
C0 V1 C2 conj (u C0 v) V1 (u C2 v)
A0 A1 V2 conj (u A0) (v A1) V2
A0 A1 A2 adv ((u A0) A1) A2
C0 A1 A2 conj ((u C0 v) A1) A2
N0 C1 N2 executed to produce any part of speech
N0 C1 V2 executed to produce any part of speech
N0 C1 A2 adv N0 C1 (u A2)
N0 C1 C2 conj N0 C1 (u C2 v)
V0 C1 N2 executed to produce any part of speech
V0 C1 V2 executed to produce any part of speech
V0 C1 A2 adv V0 C1 (u A2)
V0 C1 C2 conj V0 C1 (u C2 v)
A0 C1 N2 adv (u A0) C1 N2
A0 C1 V2 adv (u A0) C1 V2
A0 C1 A2 conj (u A0) C1 (v A2)
A0 C1 C2 conj (u A0) C1 (u C2 v)
C0 C1 N2 conj (u C0 v) C1 N2
C0 C1 V2 conj (u C0 v) C1 V2
C0 C1 A2 conj (u C0 v) C1 (v A2)
C0 C1 C2 conj (u C0 v) C1 (u C2 v)
N0 A1 executed to produce any part of speech
N0 C1 adv N0 C1 u
V0 A1 executed to produce any part of speech
V0 N1 executed to produce a noun
V0 V1 verb creates a hook
V0 C1 adv V0 C1 u
A0 V1 adv (u A0) V1
A0 A1 adv (u A0) A1
A0 C1 adv (u A0) C1 u (adverbial hook)
C0 N1 adv u C0 N1
C0 V1 adv u C0 V1
C0 A1 conj (u C0 v) A1
C0 C1 conj (u C0 v) (u C1 v)

More Information

See: Discussion and examples of invisible modifiers.