Amend - kevinlawler/kona GitHub Wiki

Amend updates values. Amends may operate functionally, returning an updated value without truly changing the underlying argument, or they may actually update state, as is the case when amending variables. The verbs . and @ are used for Amend. These verbs are unusual in that while they will accept either one or two arguments, they will also accept either three or four arguments. The triadic and tetradic forms of these verbs support many methods for altering the values of variables.

Colon notation (a:1) also allows assignment, and bracket notation (a[0]:1) allows assignment to subelements. You may even interpose a verb, as in a[0]+:2 or a[0 1]+:2. These methods involving : all reduce to corresponding uses of . or @.

Amend's Relation to Colon Assignment

All ":" assignments are special instances of Amend. The correlations between colon assignment and Dot Amend are as follows:

a:1        is  .[`a;();:;1]
a+:1       is  .[`a;();+;1]
a-:        is  .[`a;();-:]    /The first "-:" is "negate assign", the second "-:" is "negate" (monadic)
a[]:1      is  .[`a;_n;:;1]
a[0]:1     is  .[`a;0;:;1] or .[`a;,0;:;1]
a[0;1]+:2  is  .[`a;0 1;+;2]

Note, that .[a;1;:;10] doesn't change a, but .[`a;1;:;30] does:

  a:1 2 3
1 2 3
  .[a;1;:;10]
1 10 3
  a
1 2 3
  .[`a;1;:;30]
`a
  a
1 30 3

Tetradic Amend (At)

  @[5 6 7;0 1;:;7 7]
7 7 7

Tetradic Amend updates and then returns its first argument based on what is given in the remaining arguments. If the first argument is a symbol it is resolved to its corresponding entry on the K Tree before any changes occur, and then any changes occur in place. For more on how symbols are resolved to entries on the K Tree see the K Tree section in Dictionaries.

The second argument consists of integers or symbols corresponding to entries in the first argument. Integers correspond to indices in lists and symbols correspond to entries in dictionaries. The second argument may also be nil, in which case Tetradic Amend At operates on each value.

  @[5 6 7;_n;:;8]
8 8 8

  d:.((`a;1);(`b;2))
  @[d;`b;:;3]  /the returned dictionary has 3 at `b, but d is unmodified on the K Tree
  @[`d;`b;:;3] /d is modified 

In the case of Tetradic Amend, the third argument must be a dyadic verb (or other function with valence 2). When this is argument is the colon operator ":" assignment is performed. When the argument is some other dyadic operator modification occurs in place.

  @[10 20;0;+;50]
60 20

Indices may be repeated.

  @[10 20;4#0;+;50]
210 20

  @[0 1 2;(_n;_n);+;2]
4 5 6

Tetradic Amend generalizes in the following way. If the expression is represented as @[x;i;f;y], then i represents a list of arbitrary shape. Arguments i and y must look similar in shape, specifically, they must be conformable. Amend will update x at each value of i using the value of y corresponding to the current position in i. So

  @[20 30 40;(0;1 2;(0 1;0 0));-;(10;20 30;(40 50;60 70))]
-160 -40 10

The Tetradic verbs work fine with the general cases of the each, over, and scan adverbs.

  @\[0 0;1;:;1+!4]
(0 0
 0 1
 0 2
 0 3
 0 4)

Triadic Amend (At)

Triadic Amend At is much like Tetradic Amend At except that the third argument is monadic, and so there is no need for a fourth argument.

  @[1 -1 1;_n;-:]   /monadic negate
-1 1 -1 

When the third argument is colon, @ is not Amend but Error Trap.

Tetradic Amend (Dot)

  .[(0 1;2 3);1 1;:;4]
(0 1
 2 4)

Tetradic Amend Dot is a more powerful version of Tetradic Amend At. An At Amend @[a;b;c;d] can be simulated by the Dot Amend .[a;,b;c;d] with the second argument enlisted. Dot Amend can also be referred to as Amend at Depth, or Cross-Sectional Amend. Tetradic Amend Dot is responsible for the parallels with colon/bracket assignment. Dot Amend behaves analogously to At Amend when the first argument is a symbol.

  .[20 30 40;,(0;1 2;(0 1;0 0));-;(10;20 30;(40 50;60 70))] /same as above w/ enlisted 2nd arg
-160 -40 10   /the same answer

When Dot Amend receives the empty list for the index argument, the effect is to modify the entire first argument.

  .["fox";0;:;"b"]
"box"
  .["fox";();:;"b"]
"b"

For an expression .[x;i;f;y], the effect of Dot Amend is to generate a set of target elements-at-depth in x using the cross-product of elements in i.

  x:2 4 4#0 
  .[x;(0 1 1;0 1 2 3;0 1 2 2 2 2);+;1]
((1 1 4 0
  1 1 4 0
  1 1 4 0
  1 1 4 0)
 (2 2 8 0
  2 2 8 0
  2 2 8 0
  2 2 8 0))

This functionality makes more sense if we think of it as being responsible for x[a;b;c]+:1. We may also indicate the values of y. In this case, y will not have shape similar to i, instead the counts of elements of i will ultimately dictate how y is shaped. This is best illustrated with an example.

  .[x;(0 1 1;0 1;0 1 2 2);+;((1 1 1 1;2 2 2 2);(3 3 3 3;4 4 4 4);(5 5 5 5; 6 6 6 6))]
((1 1 2 0
  2 2 4 0
  0 0 0 0
  0 0 0 0)
 (8 8 16 0
  10 10 20 0
  0 0 0 0
  0 0 0 0))

Lists of symbols work analogously for nested dictionaries. You can also mix integers and symbols to index into mixed lists and dictionaries.

Triadic Amend (Dot)

Analogous to Triadic Amend At. A third argument of ":" signifies Error Trap.

Dot vs. At

  m:(1 2;3 4)
(1 2
 3 4)
  m . 1 0  /note that Dot drills down into lower levels
3
  m @ 1 0  /while At scans the top level
(3 4
 1 2)