diff --git a/spec.bs b/spec.bs
index 69c5ad9..b25552d 100644
--- a/spec.bs
+++ b/spec.bs
@@ -345,7 +345,7 @@ dictionary SubscribeOptions {
};
callback Predicate = boolean (any value, unsigned long long index);
-callback Reducer = any (any accumulator, any currentValue);
+callback Reducer = any (any accumulator, any currentValue, unsigned long long index);
callback Mapper = any (any value, unsigned long long index);
// Differs from Mapper only in return type, since this callback is exclusively
// used to visit each element in a sequence, not transform it.
@@ -1604,7 +1604,67 @@ For now, see [https://github.com/wicg/observable#operators](https://github.com/w
The reduce(|reducer|, |initialValue|, |options|)
method steps are:
- 1. TODO: Spec this and use |reducer|, |initialValue|, and |options|.
+ 1. Let |p| [=a new promise=].
+
+ 1. Let |controller| be a [=new=] {{AbortController}}.
+
+ 1. Let |internal options| be a new {{SubscribeOptions}} whose {{SubscribeOptions/signal}} is the
+ result of [=creating a dependent abort signal=] from the list
+ «|controller|'s [=AbortController/signal=], |options|'s
+ {{SubscribeOptions/signal}} if non-null», using {{AbortSignal}}, and the [=current realm=].
+
+ 1. If |internal options|'s {{SubscribeOptions/signal}} is [=AbortSignal/aborted=], then:
+
+ 1. [=Reject=] |p| with |internal options|'s {{SubscribeOptions/signal}}'s
+ [=AbortSignal/abort reason=].
+
+ 1. Return |p|.
+
+ 1. [=AbortSignal/add|Add the following abort algorithm=] to |internal options|'s
+ {{SubscribeOptions/signal}}:
+
+ 1. [=Reject=] |p| with |internal options|'s {{SubscribeOptions/signal}}'s [=AbortSignal/abort
+ reason=].
+
+ 1. Let |idx| be an {{unsigned long long}}, initially 0.
+
+ 1. Let |accumulator| be |initialValue| if it is given, and uninitialized otherwise.
+
+ 1. Let |observer| be a new [=internal observer=], initialized as follows:
+
+ : [=internal observer/next steps=]
+ ::
+ 1. If |accumulator| is uninitialized (meaning no |initialValue| was passed in), then set
+ |accumulator| to the passed in |value|, set |idx| to |idx| + 1, and abort these steps.
+
+ Note: This means that |reducer| will not be called with the first |value| that [=this=]
+ produces set as the {{Reducer/currentValue}}. Rather, when the *second* value is
+ eventually emitted, we will call |reducer| with *it* as the {{Reducer/currentValue}},
+ and the first value (that we're saving here) as the {{Reducer/accumulator}}.
+
+ 1. [=Invoke=] |reducer| with |accumulator| as {{Reducer/accumulator}}, the passed in
+ |value| as {{Reducer/currentValue}}, and |idx| as {{Reducer/index}}. Let |result| be
+ the returned value.
+
+ If an exception |E| was thrown, then
+ [=reject=] |p| with |E|, and [=AbortController/signal abort=] |controller| with |E|.
+
+ 1. Set |idx| to |idx| + 1.
+
+ 1. Set |accumulator| to |result|.
+
+ : [=internal observer/error steps=]
+ :: [=Reject=] |p| with the passed in error.
+
+ : [=internal observer/complete steps=]
+ :: 1. If |accumulator| is not "unset
", then [=resolve=] |p| with |accumulator|.
+
+ Otherwise, [=reject=] |p| with a {{TypeError}}.
+
+ 1. Subscribe to [=this=] given |observer|
+ and |internal options|.
+
+ 1. Return |p|.