Guides/Reading Tacit Verbs

From J Wiki
Jump to navigation Jump to search

This page attempts to explain how to read/parse some of the tacit forms of the verb randStrng defined on Guides/Defining Verbs.

Reading randStrngC

The simplest tacit form to parse is probably:

randStrngC=: [ {~ [: ? ] $ [: # [

How do we read this? Well, on consulting the J Dictionary, we can see that the 10 primitives appearing in randStrngC are all verbs except for ~ which is an adverb. Remembering that adverbs modify the verb to their left to create a new verb, then {~ is a verb and what we have here is a train (sequence) of 9 verbs.

   [ {~ [: ? ] $ [: # [
   - -- -- - - - -- - -
   9 8  7  6 5 4 3  2 1

J will attempt to parse this train into forks (trains of 3 verbs). A simple verb train with an odd number of verbs, can be parsed as only forks. The number of forks formed by a train of verbs can be calculated as (1+0.5*(x-3)), where x is the number of verbs in the train).

In other words, a train of three verbs represents one fork -- those three verbs combine to form a new verb. Likewise, a train of five verbs represents two forks. First three of the verbs combine together to form a new verb and then two other verbs combine with the new verb to form another train of three verbs. Every time you add a new verb you get a new fork. With seven verbs the forks would be arranged like this: (a b (c d (e f g)))

A train with an even number of verbs will consist of (1+0.5*(x-4)) forks and 1 hook (a train of 2 verbs) at the end.

Our tacit verb is a train of 9 verbs so we should end up with 4 forks.

Fork 1
The first fork (remember that J parses from right to left) in the above train is:

   [: # [

The Primer says that a fork of the form:

    x (f g h) y  ↔  (x f y) g (x h y)
where f, g and h are verbs. So Fork 1 is equivalent to:
    (x [: y) # (x [ y)

But Cap ([:) "ignores" its x and y arguments and applies the monad # to the result of x [ y. The result of x [ y is just x so the first fork is equivalent to:

   #x

Fork 2
The second fork uses the whole of the first fork as its right tine and takes the next two verbs in the train to form the middle and left tines:

   ] $ [: # [
   - - ------
   L M   R

Evaluated as:

   (x ] y) $ (x([: # [)y)

But we already know x([: # [)y is #x so this is equivalent to:

   (x ] y) $ (#x)

and the result of x ] y is y so the combined result of the 1st and 2nd forks is:

   y $ #x

Fork 3
We're ready for the third fork now which is:

   [: ? ] $ [: # [
   -- - ----------
   L  M     R

Again we already know the result of the right tine (y $ #x) and that [: will apply the monad ? to the right tine so:

   (y [: x) ? (y $ #x)
is equivalent to:
   ? y $ #x

Fork 4
The fourth and last fork is:

   [ {~ [: ? ] $ [: # [
   - -- ---------------
   L M        R


   (x [ y) {~ (? y $ #x)

Applying x [ yx we can rewrite as:

   x {~ (? y $ #x)     NB. brackets are not necessary

The adverb Passive (~) swaps the left and right arguments of the verb it modifies, so we can rewrite the last statement as:

   (? y $ #x) { x      NB. brackets are necessary!

which is the same as the explicit form of the verb (randStrngB) that we translated to tacit!

Reading randStrngE

randStrngE=: [ {~ ] ?@$ #@[

This train is shorter than randStrngC but might be a bit harder to parse until we have identified the verbs in the expression.

The new primitive in randStrngE is Atop (@). Consulting the J Dictionary we can see that @ is a conjunction. A conjunction joining 2 verbs forms a new verb (verb conjunction verb is equivalent to a new verb).

So this time we only have a train of 5 verbs because the sequence of primitives  #@[ is a new verb, not a fork. The same is true for  ?@$ .

   [ {~ ] ?@$ #@[
   - -- - --- ---
   5 4  3  2   1

There are 5 verbs in the train (an odd number) so this should pass as a sequence of 2 forks (1+0.5*(5-3)).

Fork 1
The first fork in the above train is:

   ] ?@$ #@[
   - --- ---
   3  2   1

Again, The Primer states that a fork of the form: x (f g h) y(x f y) g (x h y), so for our case:

   (x ] y) ?@$ (x #@[ y)

but Atop (@) states that x u@v y ↔ u x v y and we know that x ] y is y so Fork 1 can be rewritten as:

   (y) ?@$ (# x [ y)

and x [ y is x so:

   (y) ?@$ (#x)

Applying the Atop equivalency again we get:

   ? y $ #x

i.e. Roll y random numbers between 0 and #x.

Fork 2
The second and last fork uses the whole of the first fork as its right tine and takes the next two verbs in the train to form the middle and left tines:

   [ {~ ] ?@$ #@[
   - -- ---------
   L M      R

This is evaluated as:

   (x [ y) {~ (x(] ?@$ #@[)y)

But we already know  x(] ?@$ #@[)y is  ? y $ #x so this is equivalent to:

   (x [ y) {~ (? y $ #x)

which we have already seen and read as Fork 4 of randStrngC above.

See Also


Contributed by Ric Sherlock