```
from notebook_preamble import J, V, define
```

# Square Spiral Example Joy Code¶

Here is the example of Joy code from the `README`

file:

```
[[[abs]ii <=][[<>][pop !-]||]&&][[!-][[++]][[--]]ifte dip][[pop !-][--][++]ifte]ifte
```

It might seem unreadable but with a little familiarity it becomes just as legible as any other notation. Some layout helps:

```
[ [[abs] ii <=]
[
[<>] [pop !-] ||
] &&
]
[[ !-] [[++]] [[--]] ifte dip]
[[pop !-] [--] [++] ifte ]
ifte
```

This function accepts two integers on the stack and increments or decrements one of them such that the new pair of numbers is the next coordinate pair in a square spiral (like the kind used to construct an Ulam Spiral).

## Original Form¶

It’s adapted from the original code on StackOverflow:

If all you’re trying to do is generate the first N points in the spiral (without the original problem’s constraint of masking to an N x M region), the code becomes very simple:

```
void spiral(const int N)
{
int x = 0;
int y = 0;
for(int i = 0; i < N; ++i)
{
cout << x << '\t' << y << '\n';
if(abs(x) <= abs(y) && (x != y || x >= 0))
x += ((y >= 0) ? 1 : -1);
else
y += ((x >= 0) ? -1 : 1);
}
}
```

## Translation to Joy¶

I’m going to make a function that take two ints (`x`

and `y`

) and
generates the next pair, we’ll turn it into a generator later using the
`x`

combinator.

### First Boolean Predicate¶

We need a function that computes `abs(x) <= abs(y)`

, we can use `ii`

to apply `abs`

to both values and then compare them with `<=`

:

```
[abs] ii <=
```

I’ve defined two short-circuiting Boolean combinators `&&`

and `||`

that each accept two quoted predicate programs, run the first, and
conditionally run the second only if required (to compute the final
Boolean value). They run their predicate arguments `nullary`

.

```
define('&& [nullary] cons [nullary [0]] dip branch')
define('|| [nullary] cons [nullary] dip [1] branch')
```

Given those, we can define `x != y || x >= 0`

as:

```
[<>] [pop 0 >=] ||
```

And `(abs(x) <= abs(y) && (x != y || x >= 0))`

as:

```
[[abs] ii <=] [[<>] [pop 0 >=] ||] &&
```

It’s a little rough, but, as I say, with a little familiarity it becomes legible.

### The Increment / Decrement Branches¶

Turning to the branches of the main `if`

statement:

```
x += ((y >= 0) ? 1 : -1);
```

Rewrite as a hybrid (pseudo-code) `ifte`

expression:

```
[y >= 0] [x += 1] [X -= 1] ifte
```

Change each C phrase to Joy code:

```
[0 >=] [[++] dip] [[--] dip] ifte
```

Factor out the dip from each branch:

```
[0 >=] [[++]] [[--]] ifte dip
```

Similar logic applies to the other branch:

```
y += ((x >= 0) ? -1 : 1);
[x >= 0] [y -= 1] [y += 1] ifte
[pop 0 >=] [--] [++] ifte
```

### “Not Negative”¶

```
define('!- 0 >=')
```

## Putting the Pieces Together¶

We can assemble the three functions we just defined in quotes and give
them them to the `ifte`

combinator. With some arrangement to show off
the symmetry of the two branches, we have:

```
[[[abs] ii <=] [[<>] [pop !-] ||] &&]
[[ !-] [[++]] [[--]] ifte dip]
[[pop !-] [--] [++] ifte ]
ifte
```

As I was writing this up I realized that, since the `&&`

combinator
doesn’t consume the stack (below its quoted args), I can unquote the
predicate, swap the branches, and use the `branch`

combinator instead
of `ifte`

:

```
[[abs] ii <=] [[<>] [pop !-] ||] &&
[[pop !-] [--] [++] ifte ]
[[ !-] [[++]] [[--]] ifte dip]
branch
```

```
define('spiral_next [[[abs] ii <=] [[<>] [pop !-] ||] &&] [[!-] [[++]] [[--]] ifte dip] [[pop !-] [--] [++] ifte] ifte')
```

Let’s try it out:

```
J('0 0 spiral_next')
```

```
1 0
```

```
J('1 0 spiral_next')
```

```
1 -1
```

```
J('1 -1 spiral_next')
```

```
0 -1
```

```
J('0 -1 spiral_next')
```

```
-1 -1
```

## Turning it into a Generator with `x`

¶

It can be used with the x combinator to make a kind of generator for spiral square coordinates.

We can use `codireco`

to make a generator

```
codireco ::= cons dip rest cons
```

It will look like this:

```
[value [F] codireco]
```

Here’s a trace of how it works:

```
[0 [dup ++] codireco] . x
[0 [dup ++] codireco] . 0 [dup ++] codireco
[0 [dup ++] codireco] 0 . [dup ++] codireco
[0 [dup ++] codireco] 0 [dup ++] . codireco
[0 [dup ++] codireco] 0 [dup ++] . cons dip rest cons
[0 [dup ++] codireco] [0 dup ++] . dip rest cons
. 0 dup ++ [0 [dup ++] codireco] rest cons
0 . dup ++ [0 [dup ++] codireco] rest cons
0 0 . ++ [0 [dup ++] codireco] rest cons
0 1 . [0 [dup ++] codireco] rest cons
0 1 [0 [dup ++] codireco] . rest cons
0 1 [[dup ++] codireco] . cons
0 [1 [dup ++] codireco] .
```

But first we have to change the `spiral_next`

function to work on a
quoted pair of integers, and leave a copy of the pair on the stack.
From:

```
y x spiral_next
---------------------
y' x'
```

to:

```
[x y] [spiral_next] infra
-------------------------------
[x' y']
```

```
J('[0 0] [spiral_next] infra')
```

```
[0 1]
```

So our generator is:

```
[[x y] [dup [spiral_next] infra] codireco]
```

Or rather:

```
[[0 0] [dup [spiral_next] infra] codireco]
```

There is a function `make_generator`

that will build the generator for
us out of the value and stepper function:

```
[0 0] [dup [spiral_next] infra] make_generator
----------------------------------------------------
[[0 0] [dup [spiral_next] infra] codireco]
```

Here it is in action:

```
J('[0 0] [dup [spiral_next] infra] make_generator x x x x pop')
```

```
[0 0] [0 1] [-1 1] [-1 0]
```

Four `x`

combinators, four pairs of coordinates.

## Conclusion¶

So that’s an example of Joy code. It’s a straightforward translation of the original. It’s a little long for a single definition, you might break it up like so:

```
_spn_P ::= [[abs] ii <=] [[<>] [pop !-] ||] &&
_spn_T ::= [ !-] [[++]] [[--]] ifte dip
_spn_E ::= [pop !-] [--] [++] ifte
spiral_next ::= _spn_P [_spn_E] [_spn_T] branch
```

This way it’s easy to see that the function is a branch with two quasi-symmetrical paths.

We then used this function to make a simple generator of coordinate
pairs, where the next pair in the series can be generated at any time by
using the `x`

combinator on the generator (which is just a quoted
expression containing a copy of the current pair and the “stepper
function” to generate the next pair from that.)

```
define('_spn_P [[abs] ii <=] [[<>] [pop !-] ||] &&')
define('_spn_T [!-] [[++]] [[--]] ifte dip')
define('_spn_E [pop !-] [--] [++] ifte')
define('spiral_next _spn_P [_spn_E] [_spn_T] branch')
```

```
V('23 18 spiral_next')
```

```
. 23 18 spiral_next
23 . 18 spiral_next
23 18 . spiral_next
23 18 . _spn_P [_spn_E] [_spn_T] branch
23 18 . [[abs] ii <=] [[<>] [pop !-] ||] && [_spn_E] [_spn_T] branch
23 18 [[abs] ii <=] . [[<>] [pop !-] ||] && [_spn_E] [_spn_T] branch
23 18 [[abs] ii <=] [[<>] [pop !-] ||] . && [_spn_E] [_spn_T] branch
23 18 [[abs] ii <=] [[<>] [pop !-] ||] . [nullary] cons [nullary [0]] dip branch [_spn_E] [_spn_T] branch
23 18 [[abs] ii <=] [[<>] [pop !-] ||] [nullary] . cons [nullary [0]] dip branch [_spn_E] [_spn_T] branch
23 18 [[abs] ii <=] [[[<>] [pop !-] ||] nullary] . [nullary [0]] dip branch [_spn_E] [_spn_T] branch
23 18 [[abs] ii <=] [[[<>] [pop !-] ||] nullary] [nullary [0]] . dip branch [_spn_E] [_spn_T] branch
23 18 [[abs] ii <=] . nullary [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
23 18 [[abs] ii <=] . [stack] dinfrirst [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
23 18 [[abs] ii <=] [stack] . dinfrirst [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
23 18 [[abs] ii <=] [stack] . dip infra first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
23 18 . stack [[abs] ii <=] infra first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
23 18 [18 23] . [[abs] ii <=] infra first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
23 18 [18 23] [[abs] ii <=] . infra first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
23 18 . [abs] ii <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
23 18 [abs] . ii <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
23 18 [abs] . [dip] dupdip i <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
23 18 [abs] [dip] . dupdip i <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
23 18 [abs] . dip [abs] i <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
23 . abs 18 [abs] i <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
23 . 18 [abs] i <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
23 18 . [abs] i <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
23 18 [abs] . i <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
23 18 . abs <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
23 18 . <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
False . [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
False [18 23] . swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
23 18 [False] . first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
23 18 False . [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
23 18 False [0] . [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
23 18 False [0] [[[<>] [pop !-] ||] nullary] . branch [_spn_E] [_spn_T] branch
23 18 . 0 [_spn_E] [_spn_T] branch
23 18 0 . [_spn_E] [_spn_T] branch
23 18 0 [_spn_E] . [_spn_T] branch
23 18 0 [_spn_E] [_spn_T] . branch
23 18 . _spn_E
23 18 . [pop !-] [--] [++] ifte
23 18 [pop !-] . [--] [++] ifte
23 18 [pop !-] [--] . [++] ifte
23 18 [pop !-] [--] [++] . ifte
23 18 [pop !-] [--] [++] . [nullary not] dipd branch
23 18 [pop !-] [--] [++] [nullary not] . dipd branch
23 18 [pop !-] . nullary not [--] [++] branch
23 18 [pop !-] . [stack] dinfrirst not [--] [++] branch
23 18 [pop !-] [stack] . dinfrirst not [--] [++] branch
23 18 [pop !-] [stack] . dip infra first not [--] [++] branch
23 18 . stack [pop !-] infra first not [--] [++] branch
23 18 [18 23] . [pop !-] infra first not [--] [++] branch
23 18 [18 23] [pop !-] . infra first not [--] [++] branch
23 18 . pop !- [18 23] swaack first not [--] [++] branch
23 . !- [18 23] swaack first not [--] [++] branch
23 . 0 >= [18 23] swaack first not [--] [++] branch
23 0 . >= [18 23] swaack first not [--] [++] branch
True . [18 23] swaack first not [--] [++] branch
True [18 23] . swaack first not [--] [++] branch
23 18 [True] . first not [--] [++] branch
23 18 True . not [--] [++] branch
23 18 False . [--] [++] branch
23 18 False [--] . [++] branch
23 18 False [--] [++] . branch
23 18 . --
23 17 .
```