Vocabulary/fork
>> << 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 all valid fundamental sequences that create adverbs or conjunctions.
Each sequence yields a derived entity that subsequently acts on the operand(s) u [and v].
These fundamental sequences can be nested to create more complex trains.
Sequence Part of speech Interpretation Quick Search V0 V1 C2 conj V0 V1 (u C2 v) VVC N0 V1 C2 conj N0 V1 (u C2 v) NVC N0 C1 A2 adv N0 C1 (u A2) NCA N0 C1 C2 conj N0 C1 (u C2 v) NCC V0 C1 A2 adv V0 C1 (u A2) VCA C0 V1 C2 conj (u C0 v) V1 (u C2 v) CVC V0 C1 C2 conj V0 C1 (u C2 v) VCC A0 C1 A2 conj (u A0) C1 (v A2) ACA A0 C1 C2 conj (u A0) C1 (u C2 v) ACC C0 C1 A2 conj (u C0 v) C1 (v A2) CCA C0 C1 C2 conj (u C0 v) C1 (u C2 v) CCC V0 N1 C2 adv (... V0 N1) C2 VNC A0 V1 V2 adv (u A0) V1 V2 AVV C0 V1 V2 conj (u C0 v) V1 V2 CVV A0 A1 V2 conj (u A0) (v A1) V2 AAV A0 A1 A2 adv ((u A0) A1) A2 AAA C0 A1 A2 conj ((u C0 v) A1) A2 CAA A0 C1 N2 adv (u A0) C1 N2 ACN A0 C1 V2 adv (u A0) C1 V2 ACV C0 C1 N2 conj (u C0 v) C1 N2 CCN C0 C1 V2 conj (u C0 v) C1 V2 CCV N0 C1 adv N0 C1 u NC V0 C1 adv V0 C1 u VC A0 V1 adv (u A0) V1 AV A0 A1 adv (u A0) A1 AA A0 C1 adv (u A0) C1 u (adverbial hook) AC C0 N1 adv u C0 N1 CN C0 V1 adv u C0 V1 CV C0 A1 conj (u C0 v) A1 CA C0 C1 conj (u C0 v) (u C1 v) CC
Common uses
While=: ^:^:_ NB. tacit equivalent to {{u^:v^:_}} >:While(<&7) 0 NB. increment while less than 7 7
More Information
See: More discussion and examples of Modifier Trains.