Vocabulary/ModifierTrains

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.

Overview

The following table lists modifier 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

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:

  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 modifier trains

For comparison, a verb train 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))

A modifier train with 4 or more tines is 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 way that longer modifier trains process operand(s) u [and v] is analogous to how longer verb trains process argument(s) [x and] y. 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 

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  
-------> C C4    A     
         ----------> C C7 N8   
                     ------> C C9  
                             —---> C

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

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



(((A V V) C N) V V) A

           C4 V6 V7 ----> A8 ----> 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 ((C C N) V 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: (CCN)VVCC derives a conjunction, so at the outermost level 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 usually used in an assignment, as opposed to "inline", since the primary purpose of modifiers is to abstract over the operand(s) u [and v]. Inline use can occasionally aid clarity for common idioms, e.g. u (^:^:_) 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\@]}}).
    • ]: (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
_1

mPlusN=: {{m+n}}

   mPlusN=: [.+].
   1 mPlusN 2   
3

uNegateN=: {{u-n}}

   uNegateN=: [.@:- ].          NB. CCVC
   ^ uNegate 2   
0.135335

reciprocalOfM=: {{% m}}

   reciprocalOfM=: %([.].)]:    NB. V(CC)A
   NB.          or %([.].)
   3 reciprocalOfM
0.333333

u3=: {{u 3}}

   u3=: ]:([.].)3               NB. A(CC)N
   NB. or ([.].)3
   - u3
_3

uv3=: {{u v 3}}

   uv3=: @:([.].)3              NB. C(CC)N
   - uv3 %
_0.333333

two_u_three =: {{2 u 3}}

   two_u_three=: 2&]:([.].)3    NB. NCA(CC)N
   NB. or (2&)([.].)3
   + two_u_three
5

Experimenting with tacit modifiers

Although modifiers are usually written as assignments, passing the operands inline can nevertheless be helpful for experimenting with tacit modifiers, and 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/verb trains of longer length

Within modifier trains, sequences of more than two successive non-parenthesized verbs/nouns should not occur.

Information.png If this rule is not followed, the modifier train will be grouped according to behavior that has been deprecated due to its inordinate complexity.

  • Provided that this rule is adhered to, longer modifier trains group in 3's from the left.
NB. Grouping in 3's from left:
   & & / & + +      NB. even number of words
((& & /) & +)+
   & & / & & + +
((& & /) & &) + +   NB. odd number of words

For example, if one wants:

  • (CCA)CA --> parentheses not needed: CCACA
  • (CVV)CA --> parentheses not needed: CVVCA
  • (CVV)VV or CV(VVV) or C(VVV)V--> parentheses needed; CVVVV has more than two successive V's
  • (NVN)C   --> parentheses needed; NVNC has more than two successive V/N's

Notes and Examples

VVC/NVC

   5 7 +/ (* ; .) * i.2 2
┌─────┬─────┐
 0  514 26
14 21     
└─────┴─────┘

Here, the conjunction on the right is initially placed into a fork (which needs some sort of good name). Initially the entire fork acts as a conjunction, and the arguments to that conjunction (here +/ and the * on the right) are supplied to the inner conjunction, forming the verb fork * ; +/ .*.

NOTE: NVC should appear in a future J release, but does not work in j9.6.0-beta13

VNC

   +(j. 3 &) 10
10j3

The V N in VNC is evaluated to produce a noun, which becomes an instance of the NC train.

The entire expression to the left of the conjunction is evaluated and then combined with the conjunction to form an adverb - in this example 0j3&.

VNC is the only example of a derived modifier hook which evaluates a verb during its construction.

AVV

   +(/ % #) 3 5 7
5

Here, the once we supply an argument for the adverb we get a verb fork.

CVV

   5 7 +/ ( . ; %.) * i.2 2
┌─────┬────┐
14 26_4 5
└─────┴────┘

In this example, the fork acts as a conjunction which will form a verb fork.

CVC

   +/ (&: ,  &.:) *: 2 3 7
62 7.87401

Here we initially have two conjunctions which after receiving their verb arguments form the verb fork +/&:*: , +/&.:*: (sum of squares and the square root of the sum of squares

AAV

AAV forms a conjunction with each adverb accepting a different verb argument. If you instead wished a single verb argument to be composed with the adverbs, use (AA)V.

   #((/.~)]:~.)(,:;,.) 3 5 7 5 3
┌─────┬───┐
2 2 12 3
3 5 72 5
     1 7
└─────┴───┘

Here, (/.~) is an adverb which takes # as an argument forming the verb #/.~ and ]: is the identity adverb which takes the fork (,:;,.) as an argument. This gives us (#/.~ (,: ; ,.) ~.) (tallies of unique values along with those unique values, shown in rows and in columns).

AAA

   -(~/\.)i.5
_2 _2 _1 1 4

An AAA train gives us simple composition rather than a fork. Thus, these are equivalent:

   -(~/\.)i.5
_2 _2 _1 1 4
   -~/\.i.5
_2 _2 _1 1 4
   (-~/0 1 2 3 4),(-~/1 2 3 4),(-~/2 3 4),(-~/3 4),(-~/4)
_2 _2 _1 1 4
   (0-~1-~2-~3-~4),(1-~2-~3-~4),(2-~3-~4),(3-~4),4
_2 _2 _1 1 4
   (0-~1-~2-~4-3),(1-~2-~4-3),(2-~4-3),(4-3),4
_2 _2 _1 1 4
   ((((4-3)-2)-1)-0),(((4-3)-2)-1),((4-3)-2),(4-3),4
_2 _2 _1 1 4

CAA

CAA behaves similarly to AAA except the conjunction requires a second argument. (In other words, it does not follow the pattern of AAV where different adverbs take different external arguments.)

+/(&./\.)*: i.5
5.47723 5.47723 5.38516 5 4
   +/(&./\.)*: i.5
5.47723 5.47723 5.38516 5 4
   +/&.*:/\. 0 1 2 3 4 
5.47723 5.47723 5.38516 5 4
   (+/&.*:/0 1 2 3 4),(+/&.*:/1 2 3 4),(+/&.*:/2 3 4),(+/&.*:/3 4),(+/&.*:/4)
5.47723 5.47723 5.38516 5 4
...

NCA

 *(0 1 1x1 1p1& /) i.3
0       0       0
0       1       2
0 2.71828 5.43656
0 3.14159 6.28319

Here, *(0 1 1x1 1p1& /) gives us 0 1 2.71828 3.14159&(*/) (except with greater accuracy).

NCC

   +(2 & &.)^. 2 4 6 8
4 8 12 16

The example presented here for a NCC conjunction train serves as an overly elaborate mechanism to multiply by 2.

Equivalent results here include:

   +(2 & &.)^. 2 4 6 8
   2&(+&.^.) 2 4 6 8
   ^(^.2)+(^.2 4 6 8)

VCA

   5 13 p:(+&.inv) 7 11
13 29

Unlike in some other examples where resolving the adverb results in a verb fork, here the inner tine is a conjunction, which is applied immediately to generate the resulting verb (no secondary fork is created).

Equivalent expressions:

   5 13 +&.(p:inv) 7 11
   p: 5 13 +&(p:inv) 7 11
   p: 2 5 + 3 4
   p:5 9

VCC

   ^(<.&&.)j. i.6
0j_1 1j_1 1 0j1 _1 _1j_1

Here, our derived verb is <.&(^&.j.)

ACN

   +(/L:0) 1 2 3 ;<<4 5 6
┌─┬────┐
6│┌──┐│
 ││15││
 │└──┘│
└─┴────┘
   *(/L:0) 1 2 3 ;<<4 5 6
┌─┬─────┐
6│┌───┐│
 ││120││
 │└───┘│
└─┴─────┘

ACV

   5 10 -/(~&.:^.)100 1000
 20  10
200 100

Here the derived verb is -/~&.:^. which is numerically equivalent to %~/ for positive left and right arguments.

ACA

Unlike the AAA train, a ACA train is a conjunction which requires two different verb arguments:

   +(/&/)*
+/&(*/)
   2 3 +(/&/)* 10 100
1006

ACC

ACC is similar to ACA except that the conjunction on the right takes both of the verb arguments.

   +(/ . ].)*
+/ .*
   1 2 3 +(/ . ].)* 1 10 100
321
   -/(~&&.:)*:
-/~&(-/&.:*:)
   3 2-/(~&&.:)*:100 10
97.2627

CCN

   +/(&.: & 12) *:
+/&.:*:&12
   +/(&.: & 12) *: 5 9 16
13 15 20

or

   while=: ^:^:_
   (+ p:) while (<&10)  0
26
   
   whilst=: ^:^:a:
   (+ p:) whilst (<&10)  0
0 2 7 26

CCA

Here, the rightmost adverb takes its verb argument from the right side of the train rather than the left side.

   +/( . &. ~)*
+/ .*&.(*~)
   3 +/( . &. ~)* 3 4
15

CCC

A fork composed of three conjunctions works much like a fork composed of three verbs:

   +(```)-
┌─┬─┬─┬─┐
+-+-
└─┴─┴─┴─┘
   (+`-)`(+`-)
┌─┬─┬─┬─┐
+-+-
└─┴─┴─┴─┘


NC/CN

A single noun when supplied to a conjunction forms an adverb which requires the other conjunction argument:

   -(3&)
3&-
   -(&3)
-&3

A NC phrase is not an example of a train, but is included here for completeness.

VC/CV

A single verb when supplied to a conjunction forms an adverb which requires the other conjunction argument:

   -(3&)
   3(-&)
-&3
   3(&-)
3&-

A CN phrase is not an example of a train, but is included here for completeness.

AV

An AV train first takes a verb argument and then (typically) forms a hook (as adverbs usually produce verb results):

   +(/ *:) i.4
0 1 4  9
1 2 5 10
2 3 6 11
3 4 7 12

AA

A pair of adverbs as a train acts as an adverb, and the result of the left adverb is then combined with the right adverb. In other words, these are equivalent:

   +(/\)
+/\
   (+/)\   
+/\

AC

The (AC) train is a hook with adverb syntax - the single argument to the hook becomes the argument of the adverb and the right argument of the conjunction (the left argument of the conjunction is the result from the adverb):

   j.(~ &)
j.~&j.
   1 2 3 j.(~ &) 10 100 1000
_1j10 _2j100 _3j1000

CA

The (CA) train produces a conjunction - the arguments to the train become the arguments to the inner conjunction and the result from that conjunction becomes the argument to the adverb.

   10(&/.)#.
10&#./.
   1 2 3 2 1 (10(&/.)#.) 1 2 3 4 5 
15 24 3

CC

The (CC) train supplies both arguments to both conjunctions and as the results from conjunctions are typically verbs, the result is typically a verb hook.

   -(& &.)j.
-&j. -&.j.
   -(& &.)j. 2 _3 4j5
0j4 0j_6 _10j8