From J Wiki
Jump to navigation Jump to search

A train in the context of J, is a sequence of words that combine without executing a verb -- the generalization of hooks and forks.

Modifier trains are sequences of words that combine, without reference to operand(s) u [and v], to produce adverbs and conjunctions.

The following table lists all such combinations (evaluations, verb trains and modifier trains):

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
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 N0
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 its operand inherits the long left scope of modifiers. This extended scope is a consequence of the "leftmost stack words" in rules 6 and 7 of J's Parsing Table.


Each word in a modifier train can be thought of as having none (Verb/Noun), 1 (Adv.), or 2 (Conj.) slots where the operand(s) may potentially be piped in.

Most modifier trains in the sequence table can be categorized, eliminating the need for much memorization/lookup:

  1. a conjunction paired with a verb/noun binds the verb/noun as an operand, creating an adverb
  2. C-middle-tine trains pipe the operand(s) into both outer tines (where possible) and conjoin the resulting verbs
  3. V-middle-tine trains pipe their operand(s) into both outer tines (where possible) and create a fork from the resulting verbs
  4. trains ending in AA (including AA itself) pipe their operand(s) into the left tine, and successively apply the adverbs on the resulting verb

The remaining cases each have ad-hoc interpretations:

  1. AAV --> (u A0) (v A1) V
  2. AV --> (u A) V
  3. CC --> (u C0 v) (u C1 v)
  4. CA --> (u C v) A
  5. AC --> (u A) C u

Longer trains

A verb train (fork or hook) with 4 or more tines is grouped and evaluated in 3’s from the right.

NB. implied parentheses:
NB. v6 v5 v4 v3 v2 v1 v0  ---->  v6 v5 (v4 v3 (v2 v1 v0))

Modifier trains with 4 or more tines are explicitly grouped and evaluated in 3’s from the left:

(([. @ ]) ^: ].) ^: a:

Note: This behavior assumes that contained verb/noun phrases are parenthesized—see below


The following diagrams demonstrate how operands u (and v in the case of conjunctions) are bound by longer modifier trains to produce a resulting modifier.

doCollectUntil=: [.@]^:(-.@:)^:a:@:[.
Equivalent to {{u@]^:(-.@:v)^:a:@:u}}.

The parts of speech in the train are:

[. @  ]  ^: (-. @:) ^: a: @: [. 
C1 C2 V3 C4 (V5 C6) C7 N8 C9 C10 

The leftmost 3-train—(C1 C2 V3)—derives a conjunction, just as e.g. (+/ % #) derives a verb. For the purposes of tracing through the evaluation of a modifier train, we could say that (C1 C2 V3) is itself a conjunction.

Thus the train consisting of the first 5 entities from the left—C1 C2 V3 C4 (V5 C6)—becomes C C4 (V5 C6), where C represents the conjunction (C1 C2 V3). The isolated train (V5 C6) is an adverb, so C C4 (V5 C6) resolves to C C4 A, which is a CCA train. This in turn is a conjunction… and so on.

Evaluation is continued stepwise in 3’s from the left until the end is reached:

C1 C2 V3   C4 (V5 C6)  C7 N8   C9 C10 
-------> C C4    A     
         ----------> C C7 N8   
                     ------> C C9 C10  
                               -------> C

   C2 ----> C4 ----> C7 ----> C9 ----> resulting conj.
   /\        \        \        \        
 C1  V3    (V5 C6)    N8       C10       
 /\          |                 /\
u  v         v                u  v

   @: ----> ^: ----> ^: ----> @: ----> resulting conj.
  / \        \        \        \       
 [.  ]     (-.@:)     a:       [.      
 /\          |                 /\
u  v         v                u  v

The way that longer modifier trains process operand(s) u [and v] is analogous to how longer forks process argument(s) [x and] y. Compare the above diagram with the similar diagram for evaluation of a long fork.


          (C4 V6 V7) ----> A9 ----> resulting adv.
 (A1 V2 V3)  N5                 


 (V1 V2 C3) ----> A4 ----> A5 ----> C6 ----> resulting conj.
        /\                           \
       u  v                          V7


((C1 V2 V3)   C4) ----> resulting conj.
  /\          /\ 
 u  v        u  v

A (A A V C N V C C)

         (    C3 ----> V5 ----> V6 ----> C7    ) ----> resulting adv. 
         (    /\                          \    )
A1 ----> (  C2  N4                        C8   )
|        (  /\                            /\   )
u        ( u′ v′                         u′ v′ )

here u′ and v′ resolve to (u A1) and u respectively: (CCNVVCC) resolves to a conjunction, so the entire train resolves to AC --> (u A) C u


Just as with explicitly defined modifiers, a tacit modifier (i.e. modifier train) is sensibly used only within a definition, as opposed to "inline", since the purpose of modifiers is to abstract over the operand(s) u [and v].

  • Tie (`) and Evoke Gerund as Train (`:6) can be used to insert derived verbs anywhere within a verb train:
   t0=: (+/) ` ` `: 6
   % t0 #
+/ % #
  • The AC train pipes a (potentially modified) copy of u to the right side of the conjunction phrase, similar to how the (v0 v1) y and v0~ y create a copy of y on the left side of the expression.
    • This allows u, or modified versions of u, to be inserted in multiple places within a verb train, as in /.([.`+`(\@])`:6) (equivalent to {{u/. + u\@]}}). This can also be done by instead binding to the conjunctive phrase a dummy operand (we’ll use a:) and ignoring it, as in /.`+`([.\]:@])`:6 a:.
    • ]: (conj. phrase) duplicates operand u without modification, akin to u~ y or (u ]) y.
  • ]. (conj. phrase) [. swaps operands u and v, akin to x u~ y.
  • Ident (]:) isn't restricted to use in adverbs; it can be used within conjunctions as well. This is useful when you want one operand as-is, and the other modified by an adverb. For example, ]: / |. equates to [. (]./) |. or {{u v/ |.}}.
  • Lev ([.) and Dex (].) aren’t restricted to use in conjunctions; they can be used within the conjunction phrase of the adverb-forming train AC, in which [. represents (u A) and ]. reprepresents u.
  • Tacit modifiers can be juxtaposed and nested to write arbitrarily complex modifiers.

Examples of translating explicit modifier definitions to tacit

filter=: {{u # ]}}

filter=: ]: # ]

eachLeft=: {{u"_&.(>`a:)}}

eachLeft=: ]:"_&.(>`a:)
NB. or     ("_)&.(>`a:)

bivalent=: {{u@:v : (u v)}}

bivalent=: @: : ([. ].)    
NB. [x] u v y

modify=: {{ u@{`(I.@[)`]} }}

modify=: ]:@{`(I.@[)`]}
NB. or   (@{)`(I.@[)`]}

substr=: {{,:@[ u ]}}

substr=: ,:/@[`]:`]`:6

while=: {{u^:v^:_}}

while=: ^:^:_

until=: {{u^:(-.@:v)^:_}}

until=: [.^:(-.@:].)^:_
NB. or  ]:^:(-.@:)^:_

Noun operands

u and v in the sequence table can be either verbs or nouns—in other words, u and/or v can be replaced by m and/or n respectively:

uN=: {{u n}}

   uN=: [.].
   - uN 1

mPlusN=: {{m+n}}

   mPlusN=: [.+].
   1 mPlusN 2   

uNegateN=: {{u-n}}

   uNegateN=: [.@:- ].    
   ^ (uNegate=: [.@:-].) 2   

reciprocalOfM=: {{% m}}

   reciprocalOfM=: %([.].)  
   3 reciprocalOfM

u3=: {{u 3}}

   u3=: ([.].)3      
   - u3

uv3=: {{u v 3}}

   uv3=: @:([.].3) 
   - uv3 %

two_u_three =: {{2 u 3}}

   two_u_three=: 2&[.([.].)3 a:    NB. NCC(CC)N N
   NB.        ]:(2&[.([.].)3)      NB. A(NCC(CC)N) 
   + two_u_three

Experimenting with tacit modifiers

Although it doesn’t make sense to write a modifier definition inline within a J program, passing the operands inline can be helpful for playing around and experimenting with tacit modifiers, and for verifying that a given adverb or conjunction does what you intend:

   +(   ]:/\@(@])/   )=
   +(   ]:@/\   )=
   +(   ]:@(/\)   )=
   -(   uv3=: @:([.].3)   )%
   +(   ([./)`;`([.\]:@])`:6 a:   )
+/ ; +\@]
   e.(   %^:(0&]:`(12"_))`]}]:"]: ::'z'   )2
%^:(0&e.`(12"_))`]} "2 ::'z'
   e.(   (%^:(0&[.`(12"_))`]})"]. ::'z'   )2
%^:(0&e.`(12"_))`]} "2 ::'z'


Modifier trains can implement any modifier except those in which a noun phrase involving arguments x and/or y is passed internally as an operand to a modifier, as in {{u"(v y) y}} or {{(u"x) y}}.

This limitation follows from the fact that tacit verbs cannot implement e.g. the equivalent of {{(<"x) y}}. The tacit stand-in for the noun x is the verb [, and e.g. u"verb has a different meaning from u"noun.

Parsing rules for mixed modifier/traditional trains of longer length

Traditional verb/noun trains/forks can be combined, unparenthesized, within a modifier train. Long(er than 3) modifier trains will sometimes interrupt and sometimes allow the formation of verb phrases.

Information.png Within modifier trains, it is strongly recommended that verb/noun phrases simply be parenthesized. The grouping behavior otherwise is more complex than is documented below.

Below are the rules for how non-parenthesized mixed trains are parsed.

  1. Modifier trains CC[V/N], AC[V/N] always greedily group the first (i.e. leftmost) 3 terms to produce a derived entity.
  2. All other modifier trains with a V/N on one side prioritize formation of a verb train (VV or VVV or NVV) over greedy left-grouping.
    1. Within modifier trains, (non-parenthesized) verb train sub-sequences always form forks, never hooks. That is, they group themselves in 3's from the right (as in standalone verb trains), and never group an even number of V/N's into a train, only an odd number.
@ @ + % #  NB. Modifier start of train @@ must capture 3rd completing term.  (CC) will never auto-group itself because it is only 2 terms long.

(@ @ +) % #

+/ % # @ @  NB. VVV to left will autogroup. VCC result.

(+/ % #) @ @

  1 + = +-@: NB. Odd number of v/n to left a conjunction forms an adverb with verb fork as bound parameter

(1 + = + -)@:

@@+@-  NB. uCn verb phrase +@- did not form because of 3rd item greed rule.

(@ @ +) @ -

but the train forming modifier trains (AV AAV AVV CVV VVC) "tend to" defer to VVV formation:

]: ]: -/%#

]: ]: (-/ % #)

]: -~ -/ % #  NB. verb phrases allowed to freely form on AV or AVV "start" (left) of modifier train.  

]: (-~) (-/ % #)

]: ]: -@^  %// NB. Equivalent here to (]: %// -@^). 
               NB. (]: ]: -@^ %//) is (A A V V) --> ((AAV)V) --> ((]: ]: -@^) %//) --> ((AAV)V) resolves to C V --> V binds as right operand to C --> ((u A0) (V1 A1) V0))

(]: ]: (-@^))(%//)

@@]: + -  NB. CCA exists and has priority over to its right AVV

(@ @ ]:) + -

@@% + - NB. CCV has left priority over VVV (creates (CA)VV -> CVV)

(@ @ %) + -

 @  + -~ % $ # NB. CVV not being prioritized.  Instead VVV is prioritized. CVV is "leftover" binding

(@ + (-~))(% $ #)

@   - % $ #  NB. Again VVV prioritized and leftover forms modifier train.

@ - (% $ #)

@: - + = +-# NB. VV(VVV) prioritized

@: - (+ = + - #)

@ @ ]: + - % $ #

(@ @ ]:)(+ - % $ #)

(@ @ ]:) + - % $ 

(@ @ ]:) + (- % $)

+ -/ % # @ NB. VVC with even number of verbs to left of Conj.

+ (-/ % #) @

+ -/ % # # @  NB. odd number of verbs to left forms an adverb fork@

(+ -/ % # #)@

+@- @ @ NB. verb phrases can be formed at start/left of modifier train. ie. if leftmost term is verb/noun

+@- @ @

  +/ @ @ 

+/ @ @

@-@% NB. but if it doesn't start with verb/noun, verb phrases defer to greedy modifier rule.

(@ - @)%