# cart¶

Short for Cartesian, the `cart()` gear combines data from its inputs, at least one of which is of the `Queue` type. It combines each element of the data received at its second input with whole data value received at its first input.

`cart`(*din)

Most often the `cart()` gear is used to combine a `Queue` and some other non-Queue data, so that the non-Queue data is replicated for each element of the `Queue`.

Imagine if we have a `Queue` of `x` coordinates `[10, 11, 12]`, and we would like to attach to each of them an `y` coordinate to form a point. The `y` coordinate is generated by a source which does not know how long our `Queue` -s are so it only outputs a single value `0`, which is than replicated by the `cart()` gear for each element of the `Queue` carrying the `x` coordinate. The result of the `cart()` operation is a `Queue` of points `[(10, 0), (11, 0), (12, 0)]`. Observe how the value `0`, received at `din1` input of the `cart()` gear is acknowledged only after it has been combined with all the elements of the `Queue` (in the third cycle).

```x = drv(t=Queue[Uint[5]], seq=[[10, 11, 12]])
y = drv(t=Uint[5], seq=[0])

cart(x, y) | check(ref=[[(10, 0), (11, 0), (12, 0)]])
```

Next example has identical data types as the previous one, only its driving sequence is longer.

```op1 = drv(t=Queue[Uint[5]], seq=[[10, 11, 12], [20, 21, 22]])
op2 = drv(t=Uint[1], seq=[0, 1])

cart(op1, op2) | check(ref=[[(10, 0), (11, 0), (12, 0)], [(20, 1), (21, 1), (22, 1)]])
```

Finally, this example shows how two `Queue` -s are combined using the `cart` gear.

```op1 = drv(t=Queue[Uint[5]], seq=[[10, 11], [20, 21], [30, 31]])
op2 = drv(t=Queue[Uint[5]], seq=[[10, 11, 12]])

cart(op1, op2) | check(ref=[[[(10, 10), (11, 10)], [(20, 11), (21, 11)], [(30, 12), (31, 12)]]])
```
`cart_sync`(*din)

Performs the same operation as the `cart()` gear regarding the data replication, however it does not combine the data at the output, but outputs each of the data via separate interface.

```op1 = drv(t=Queue[Uint[5]], seq=[[10, 11, 12], [20, 21, 22]])
op2 = drv(t=Uint[1], seq=[0, 1])

out1, out2 = cart_sync(op1, op2)
out1 | check(ref=[[10, 11, 12], [20, 21, 22]])
out2 | check(ref=[0, 0, 0, 1, 1, 1])
```
`cart_sync_with`(sync_in, din) → din

Performs the same operation as the `cart()` gear regarding the data replication, however it does not combine the data at the output, but outputs only the interface whose data has been replicated. Useful if we don’t need the data combination, just the replication.

```sync = drv(t=Queue[Uint[5]], seq=[[10, 11, 12], [20, 21, 22]])

drv(t=Uint[1], seq=[0, 1]) \
| cart_sync_with(sync) \
| check(ref=[0, 0, 0, 1, 1, 1])
```