Vocabulary/dollarco

From J Wiki
Jump to navigation Jump to search

>> <<   Back to: Vocabulary Thru to: Dictionary


[x] $: y Self-Reference

Rank Infinity -- operates on [x and] y as a whole -- WHY IS THIS IMPORTANT?


Stands for the verb currently being executed.

  • Inside a single-phrase verb definition: $: stands for the verb being defined.
  • Inside a J sentence: $: stands only for the outermost verb phrase containing $: within the given sentence.
  • Inside the body of an explicit definition: $: applies only to the sentence in which it occurs.

Examples

   forever =: $:
   forever ''
|stack error: forever
|       forever''
   
   forever2 =: 3 : '$: y'
   forever2 ''
|stack error: forever2
|       $:y

In both cases, $: stands for the verb defined by the verb phrase: ($:) – i.e. itself.
The result is an infinite recursion causing a stack error when space in the function stack is exhausted.


Notes

  • This feature allows an anonymous verb to call itself.
  • This feature enables any sort of verb to call itself recursively, but you must take care how $: is used.



Common Uses

1. To alter the behavior of the monad of an ambivalent verb.

Larger Of (Max) (x >. y) is ambivalent, but its monad may not behave as we want

   >. 1 5 4  NB. does not give us the largest integer
1 5 4
   
   max =: $:/ : >.
   max 1 5 4
5
   1 max 5   NB. but the dyad of max still behaves like dyadic >.
5


2. To convert a dyad into an ambivalent verb.

A tacit verb, like cut below, is always ambivalent. But in this case cut only works correctly as a dyad

   ' ' cut 'alpha bravo charlie'
┌─────┬─────┬───────┐
│alpha│bravo│charlie│
└─────┴─────┴───────┘
   cut 'alpha bravo charlie'
┌──────────────────┬──────────────────┐
│alpha bravo charli│alpha bravo charli│
└──────────────────┴──────────────────┘

We want a monadic form of cut that behaves the same as: ' ' cut y.

Rewrite cut on the pattern: cut2=: (monad) : (dyad)

  • where dyad is the old version of cut
  • and monad is (' '&$:)
   cut =: (' '&$:) : ([: -.&a: <;._2@,~)
   cut 'alpha bravo charlie'
┌─────┬─────┬───────┐
│alpha│bravo│charlie│
└─────┴─────┴───────┘
   'a' cut 'alpha bravo charlie'    NB. cut y at the letter 'a'
┌───┬───┬─────┬────┐
│lph│ br│vo ch│rlie│
└───┴───┴─────┴────┘


3. To convert an explicit dyad into an ambivalent verb.

Adapt the construct used in example 2, namely the pattern: plus=: (monad):(dyad)

  • where monad is (0&$:)
  • and dyad is (4 : 0) …which expects the body to follow immediately after the assignment sentence
   plus =: (0&$:) : (4 : 0)
x + y
)
   plus 4
4

Note how the act of defining a verb eliminates redundant code, such as (some) parentheses. But it can also conceal the structure or make it harder to read

   plus
0&$: :(4 : 'x + y')


4. Another way to convert an explicit dyad into an ambivalent verb.

Use this simple utility in place of 4 : 0 in the assignment sentence

   ddefine =: 1 : 'm&$: : (4 : 0)'

   plus =: 0 ddefine
x + y
)

It makes an ambivalent verb out of a dyad-only definition by providing a default value for the x argument.

We get the same end-result as 3. above

   plus
0&$: :(4 : 'x + y')


5. To create a tacit recursive verb.

Define the verb: factorial as

  • y=0 returns 1
  • y=1 returns 1
  • y>1 returns y*factorial y-1
   factorial =: 1: ` (* $:@<:) @. *
   factorial 6
720

See here for an explanation of this verb.


More Information

1. In order to define the monad of a verb in terms of its dyad, the following construct is common in published code

   plus =: 3 : 0
0 plus y
:
x + y
)

For example, see the factory verb: load

But such an explicit verb is not safe to adapt, because the name of the verb has been hard-wired into its body.

An unwary coder might end up with:

   minus =: 3 : 0
0 plus y
:
x - y
)

It would be good to use $: to make the body independent of the verb name. But if you simply replace plus with $: the monad fails

   plus =: 3 : 0
0 $: y
:
x + y
)
   3 plus 4
7
   plus 4
|stack error: plus
|   0    $:y


2. Why does the failure in 1. happen?

As explained in the introduction, $: doesn't stand here for the whole of the explicit verb plus but only the surrounding verb phrase inside the code defining the monad of plus

...
0 $: y
...

In this case the verb phrase is just the primitive verb: $:

The result is an infinite recursion.


3. The remedy for the failure in 1. is to adapt the construct used in Common Uses 2, namely the pattern: plus=: (monad):(dyad)

  • where monad is (0&$:)
  • and dyad is (4 : 0)

The verb phrase (4 : 0) (even when surrounded by parentheses) looks for a series of lines terminated by ) immediately after the assignment sentence to provide the body of the dyad definition.

Details

1. Be wary of using u f. when u refers to a tacit recursive verb.

Since $: stands for the name of the verb containing it, and f. replaces names with their values, an instance of $: inside the definition of a replaced name will no longer have the same meaning.


CategoryVoc CategoryVocRecursion