Vocabulary/ModifierTrains
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 V2verb verb creates a fork VVV
NVVV0 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 N0no 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 A1no 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.
Classification
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:
- a conjunction paired with a verb/noun binds the verb/noun as an operand, creating an adverb
- C-middle-tine trains pipe the operand(s) into both outer tines (where possible) and conjoin the resulting verbs
- V-middle-tine trains pipe their operand(s) into both outer tines (where possible) and create a fork from the resulting verbs
- 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:
- AAV --> (u A0) (v A1) V
- AV --> (u A) V
- CC --> (u C0 v) (u C1 v)
- CA --> (u C v) A
- 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: (([. @ ]) ^: ].) ^: a:
Note: This behavior assumes that contained verb/noun phrases are parenthesized—see below
Examples
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.
A V V C N V V A
(C4 V6 V7) ----> A9 ----> resulting adv. /\ (A1 V2 V3) N5 | u
V V C A A C V
(V1 V2 C3) ----> A4 ----> A5 ----> C6 ----> resulting conj. /\ \ u v V7
C V V C
((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
Usage
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
andv0~ 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 tou~ y
or(u ]) y
.
- This allows u, or modified versions of u, to be inserted in multiple places within a verb train, as in
]. (conj. phrase) [.
swaps operands u and v, akin tox 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 _1
mPlusN=: {{m+n}}
mPlusN=: [.+]. 1 mPlusN 2 3
uNegateN=: {{u-n}}
uNegateN=: [.@:- ]. ^ (uNegate=: [.@:-].) 2 0.135335
reciprocalOfM=: {{% m}}
reciprocalOfM=: %([.].) 3 reciprocalOfM 0.333333
u3=: {{u 3}}
u3=: ([.].)3 - u3 _3
uv3=: {{u v 3}}
uv3=: @:([.].3) - uv3 % _0.333333
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 5
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) )% _0.333333 +( ([./)`;`([.\]:@])`:6 a: ) +/ ; +\@] e.( %^:(0&]:`(12"_))`]}]:"]: ::'z' )2 %^:(0&e.`(12"_))`]} "2 ::'z' e.( (%^:(0&[.`(12"_))`]})"]. ::'z' )2 %^:(0&e.`(12"_))`]} "2 ::'z'
Completeness
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.
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.
- Modifier trains CC[V/N], AC[V/N] always greedily group the first (i.e. leftmost) 3 terms to produce a derived entity.
- 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.
- 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.
(@ - @)%