Frantically tried to crack this and write it up so I could squeeze this into the month just because of the alliteration and failed.

I’m not sure now how I ended up playing with Joy, but I think it was because I had Forth on my learning list and Joy was mentioned there.

It is a wee bit confusing.

You provide the arguments for a function and then the function and execute it by finishing with a period (like Erlang). So to add two numbers:

``````2 3 +.
``````

Ok, so that isn’t confusing, but if you want to add the result of that sum to the result of another sum, say (2 + 3) + (4 + 5) you end up with the following:

``````2 3 + 4 5 + +.
``````

It starts to get confusing. You have to mentally visualise the brackets.

There are no variables and you can’t build up intermediate results (as far as I know) to make things easier to read, you’ve got to do everything in one go. You can however use DEFINE blocks (like Erlang) to build up functions, etc up-front.

I thought I’d start with very simple programme since my poor little brain was (still is) struggling a bit to wrap itself around Joy: Given two lists of gears/sprockets (for my bike) calculate all the ratios and sort them, displaying both the ratio and the gear pairs. So if I input something like so:

``````DEFINE
littlegears == [12 13 15 17 19 21 23 25];
biggears == [34 50].
``````

I can get an output like so:

``````[ [ 4.1667 "50/12"] [ 3.846 "50/13"] ... and so on ]
``````

## Calculating ratios

First step was calculating all the ratios. My first attempt was as follows:

``````littlegears [biggears 1 at 1.0 * /] map [-1 pow] map
littlegears [biggears 0 at 1.0 * /] map [-1 pow] map
concat.
``````

which is tricky to understand already. The first line calculates all the ratios against the 50 and the second against 34 and both these lists are then joined together with `concat`. Looking at just the first line, the “50” value is obtained by `biggears 1 at` which leaves:

``````littlegears [50 1.0 * /] map [-1 pow] map
``````

This is then multiplied by 1.0 so it’s converted to a float from an integer, which is important when it comes to dividing.

``````littlegears [50.0 /] map [-1 pow] map
``````

The first `map` then takes the `50.0` and the divide and applies this over the `littlegears` list so you end up with:

``````[0.24 0.26 0.3 0.34 0.38 0.42 0.46 0.52] [-1 pow] map
``````

The problem with mapping the `50 /` over the list is that my divisions are inverted. I don’t want to divide the little gears by the big gears I want it the other way round. My cludgy fix for this was to raise all values to the power of minus one, effectively inverting them.

I thought there must be a better way to do this, like Haskell’s `flip` function. And there is:

``````littlegears [50.0 swap /] map.
``````

does the same as:

``````littlegears [50.0 /] map [-1 pow] map
``````

## Merging Two lists as pairs

Ok, so I know how to get all the ratios, but that is not much use on it’s own. The next thing I wanted to figure out was how to merge two lists by grouping as pairs so I could have the ratios next to the gear combinations (`[ [4.1667 "50/12"] ... ]`). I started playing about a list containing two little lists:

``````[[1 2] [3 4]]
``````

And trying to get this result:

``````[[1 3] [2 4]]
``````

In Joy `cons` is the function use to join an element to a list so the following did the trick, but only for a two element list:

``````[[1 2] [3 4]] [first] map
[[1 2] [3 4]] [second] map
[] cons cons.
``````

For a three element list I’d need:

``````[[1 2 3] [4 5 6]] [first] map
[[1 2 3] [4 5 6]] [second] map
[[1 2 3] [4 5 6]] [third] map
[] cons cons cons.
``````

And so on which isn’t very sustainable for longer lists. I’m currently stuck on how to do this bit properly. I can’t find any function in the documentation that takes two lists (aggregates) so I don’t think I’m missing an easy way to do this.

## Getting list of gear pairs

I couldn’t find any function to format an integer as a string. There are string to integer and string to float functions, but not the reverse as far as I can tell. So I thought I would build the results as follows: `[ [ 4.1667 50 12] ... etc ]` sorted on ratio.

``````littlegears [ [30] cons] map.
``````

builds up the gear pairs, although the gears are listed the wrong way:

``````[[12 30] [13 30] [15 30] [17 30] [19 30] [21 30] [23 30] [26 30]]
``````

If I want them the right way round it gets messier:

``````littlegears [ [] cons ] map [ [30] swap concat] map.
``````

## Sorting a nested list

The tutorial has an implementation of quick sort which is meant to be in the standard library - it’s not in what I’ve compiled - and I’ve tried adapting that to work on a nested list:

``````[[7 4] [3 5] [6 9] [1 3]]
``````

As follows:

``````[small]
[]
[uncons [first >] split]
[[swap] dip cons concat]
binrec
``````

So I get:

``````[[1 3] [3 5] [6 9] [7 4]]
``````

But it doesn’t work.

And so that’s where I’m up to so far. No answers on postcards please - I’m sure I’ll figure it out sooner or later.