# Reduce reduce with reduced

Check out part 1

Let’s play some more code golf!

```
function some(pred, xs) {
for (let i = 0; i < xs.length; i++) {
if (pred(xs[i], i)) {
return true
}
}
return false
}
function every(pred, xs) {
for (let i = 0; i < xs.length; i++) {
if (!pred(xs[i], i)) {
return false
}
}
return true
}
function reduce(fn, xs, init) {
let result = init
for (let i = 0; i < xs.length; i++) {
result = fn(result, xs[i], i)
}
return result
}
```

`some`

returns `true`

when a predicate returns `true`

**at least one time** , while iterating over a list. `every`

returns `true`

when a predicate **always** returns `true`

.
`some`

and `every`

can be implemented with `reduce`

:

```
function some(pred, xs) {
return reduce((acc, item, i) => acc || pred(item, i), xs, false)
}
function every(pred, xs) {
return reduce((acc, item, i) => acc && pred(item, i), xs, true)
}
function reduce(fn, xs, init) {
let result = init
for (let i = 0; i < xs.length; i++) {
result = fn(result, xs[i], i)
}
return result
}
```

While this is shorter and for the trained eye easier to read. It has no early return. When a predicate in `some`

returns `true`

the list will still be traversed completely. In order to improve this, we need to extent the functionality of reduce:

```
function reduce(fn, xs, init) {
let result = init
for (let i = 0; i < xs.length; i++) {
result = fn(result, xs[i], i)
if (isReduced(result)) return getReduced(result)
}
return result
}
```

Functions that are passed into `reduce`

now have the ability to early return the `reduce`

function. Those functions communicate their desire for an early return, by *decorating* their return-value in a specific way.

```
function some(pred, xs) {
return reduce(
(_, item, i) => (pred(item, i) ? reduced(true) : false),
xs,
false
)
}
function every(pred, xs) {
return reduce(
(_, item, i) => (pred(item, i) ? true : reduced(false)),
xs,
true
)
}
```

`reduced`

wraps the value in some way, so that it can be detected by `isReduced`

. When `some`

discovers a truthy value, it returns this wrapped value. Signaling to the outside reduce function that it should return early.
`reduced`

, `isReduced`

and `getReduced`

could be implemented like this:

```
const reduced = x => ({
"@@transducer/value": x,
"@@transducer/reduced": true,
})
const isReduced = x => x?.["@@transducer/reduced"]
const getReduced = x => x?.["@@transducer/value"]
```

Why I chose to prefix the props with `@@transducer`

is a topic for another time.
Here is the full code:

```
function some(pred, xs) {
return reduce(
(_, item, i) => (pred(item, i) ? reduced(true) : false),
xs,
false
)
}
function every(pred, xs) {
return reduce(
(_, item, i) => (pred(item, i) ? true : reduced(false)),
xs,
true
)
}
function reduce(fn, xs, init) {
let result = init
for (let i = 0; i < xs.length; i++) {
result = fn(result, xs[i], i)
if (isReduced(result)) return getReduced(result)
}
return result
}
const reduced = x => ({
"@@transducer/value": x,
"@@transducer/reduced": true,
})
const isReduced = x => x?.["@@transducer/reduced"]
const getReduced = x => x?.["@@transducer/value"]
```

Well we did not win that much in terms of LoC, but this early return strategy can be used in other list operations:

```
function find(pred, xs) {
for (let i = 0; i < xs.length; i++) {
if (pred(xs[i], i)) {
return xs[i]
}
}
return undefined
}
function indexOf(target, xs) {
for (let i = 0; i < xs.length; i++) {
if (xs[i] === target) {
return i
}
}
return -1
}
function includes(target, xs) {
for (let i = 0; i < xs.length; i++) {
if (xs[i] === target) {
return true
}
}
return false
}
function findIndex(pred, xs) {
for (let i = 0; i < xs.length; i++) {
if (pred(xs[i], i)) {
return i
}
}
return -1
}
```

Use reduce:

```
function find(pred, xs) {
return reduce(
(_, item, i) => (pred(item, i) ? reduced(item) : undefined),
xs,
undefined
)
}
function indexOf(target, xs) {
return reduce((_, item, i) => (target === item ? reduced(i) : -1), xs, -1)
}
function includes(target, xs) {
return reduce(
(_, item) => (target === item ? reduced(true) : false),
xs,
false
)
}
function findIndex(pred, xs) {
return reduce((_, item, i) => (pred(item, i) ? reduced(i) : -1), xs, -1)
}
```

A lot of list operations can be expressed with `reduce`

. Those operations have one thing in common: a collection of items gets traversed, each item is examined to produce a result.
That is the concept of `reduce`

. However, the current implementation of this concept is unnecessary specific. Notice that even though `reduce`

seems to be extremely generic, it can still only be used with one kind of ‘collection’: the list. The shown version does not even work with iterators. Or with anything else that we might want to use map and filter on (Maybe-Constructs or Observables, etc.). For each other type of ‘collection’ we would need to reimplement all of those operations again.

Can we abstract `reduce`

even further?

Yes we can, by using so-called `transducers`

. Coming soon…