diff --git a/apps/labs/posts/hypothesis-array-api.md b/apps/labs/posts/hypothesis-array-api.md
new file mode 100644
index 000000000..8b44c90ea
--- /dev/null
+++ b/apps/labs/posts/hypothesis-array-api.md
@@ -0,0 +1,713 @@
+---
+title: "Using Hypothesis to test array-consuming libraries"
+author: matthew-barber
+published: October 6, 2021
+description: 'This blog post is for anyone developing array-consuming methods (think SciPy and scikit-learn) and is new to property-based testing. I demonstrate a typical workflow of testing with Hypothesis whilst writing an array-consuming function that works for all libraries adopting the Array API, catching bugs before your users do.'
+category: [Array API]
+featuredImage:
+ src: /posts/hypothesis-array-api/hypothesis-array-api-social.png
+ alt: 'Hypothesis logo accompanied by the text Property-based testing for the Array API'
+hero:
+ imageSrc: /posts/hypothesis-array-api/hypothesis-array-api-social.png
+ imageAlt: 'Hypothesis logo accompanied by the text 'Property-based testing for the Array API'
+---
+
+Over the summer, I\'ve been interning at Quansight Labs to develop
+testing tools for the developers and users of the upcoming [Array API
+standard](https://data-apis.org/array-api/latest/). Specifically, I
+contributed \"strategies\" to the testing library
+[Hypothesis](https://github.com/HypothesisWorks/hypothesis/), which I\'m
+excited to announce are now available in
+[`hypothesis.extra.array_api`](https://hypothesis.readthedocs.io/en/latest/numpy.html#array-api).
+Check out the primary [pull
+request](https://github.com/HypothesisWorks/hypothesis/pull/3065) I made
+for more background.
+
+This blog post is for anyone developing array-consuming methods (think
+SciPy and scikit-learn) and is new to property-based testing. I
+demonstrate a typical workflow of testing with Hypothesis whilst writing
+an array-consuming function that works for *all* [libraries adopting the
+Array
+API](https://data-apis.org/array-api/latest/purpose_and_scope.html#stakeholders),
+catching bugs before your users do.
+
+## Before we begin
+
+Hypothesis shipped with its Array API strategies in [version
+6.21](https://hypothesis.readthedocs.io/en/latest/changes.html#v6-21-0).
+We also need to use NumPy \>= 1.22 so that we can test with its
+[recently merged](https://github.com/numpy/numpy/pull/18585) Array API
+implementation---this hasn\'t been released just yet, so I would
+recommend installing a [nightly
+build](https://anaconda.org/scipy-wheels-nightly/numpy).
+
+I will be using the excellent
+[ipytest](https://github.com/chmp/ipytest/) extension to nicely run
+tests in Jupyter as if we were using
+[pytest](https://github.com/pytest-dev/pytest/) proper. For pretty
+printing I use the superb [Rich](https://github.com/willmcgugan/rich)
+library, where I simply override Python\'s builtin `print` with
+[`rich.print`](https://rich.readthedocs.io/en/stable/reference/init.html#rich.print).
+I also suppress all warnings for convenience\'s sake.
+
+``` python
+%%capture
+!pip install hypothesis>=6.21
+!pip install -i https://pypi.anaconda.org/scipy-wheels-nightly/simple numpy
+```
+
+``` python
+%%capture
+!pip install ipytest
+import ipytest; ipytest.autoconfig(display_columns=80)
+```
+
+``` python
+%%capture
+!pip install rich
+from rich import print
+```
+
+``` python
+import warnings; warnings.filterwarnings("ignore")
+```
+
+## What the Array API enables
+
+The [API](https://data-apis.org/array-api/latest/) standardises
+functionality of array libraries, which has [numerous
+benefits](https://data-apis.org/array-api/latest/use_cases.html) for
+both developers and users. I recommend reading the [Data APIs
+announcement
+post](https://data-apis.org/blog/announcing_the_consortium/) to get a
+better idea of how the API is being shaped, but for our purposes it
+works an awful lot like NumPy.
+
+The most exciting prospect for me is being able to easily write an
+array-consuming method that works with all the adopting libraries.
+Let\'s try writing this method to calculate the cumulative sums of an
+array:
+
+``` python
+def cumulative_sums(x):
+ """Return the cumulative sums of the elements of the input."""
+ xp = x.__array_namespace__()
+
+ result = xp.empty(x.size, dtype=x.dtype)
+ result[0] = x[0]
+ for i in range(1, x.size):
+ result[i] = result[i - 1] + x[i]
+
+ return result
+```
+
+The all-important
+[`__array_namespace__()`](https://data-apis.org/array-api/latest/API_specification/array_object.html#method-array-namespace)
+method allows array-consuming methods to get the array\'s respective
+Array API module. Conventionally we assign it to the variable `xp`.
+
+From there you just need to rely on the guarantees of the Array API to
+support NumPy, TensorFlow, PyTorch, CuPy, etc. all in one simple method!
+
+## Good ol\' unit tests
+
+I hope you\'d want write some tests at some point 😉
+
+We can import NumPy\'s Array API implementation and test with that for
+now, although in the future it\'d be a good idea to try other
+implementations (see [related Hypothesis
+issue](https://github.com/HypothesisWorks/hypothesis/issues/3085)). We
+don\'t `import numpy as np`, but instead import NumPy\'s new module
+`numpy.array_api`, which exists to comply with the Array API standard
+where `numpy` proper can not (namely so NumPy can keep backwards
+compatibility).
+
+``` python
+from numpy import array_api as nxp
+
+def test_cumulative_sums():
+ x = nxp.asarray([0, 1, 2, 3, 4])
+ assert nxp.all(cumulative_sums(x) == nxp.asarray([0, 1, 3, 6, 10]))
+
+ipytest.run()
+```
+
+ . [100%]
+ 1 passed in 0.02s
+
+I would probably write a
+[parametrized](https://docs.pytest.org/en/stable/parametrize.html) test
+here and write cases to cover all the interesting scenarios I can think
+of. Whatever we do, we will definitely miss some edge cases. What if we
+could catch bugs we would never think of ourselves?
+
+## Testing our assumptions with Hypothesis
+
+```{=html}
+
+```
+Hypothesis is a property-based testing library. To lift from their
+excellent
+[docs](https://hypothesis.readthedocs.io/en/latest/index.html), think of
+a normal unit test as being something like the following:
+
+1. Set up some data.
+2. Perform some operations on the data.
+3. Assert something about the result.
+
+Hypothesis lets you write tests which instead look like this:
+
+1. For all data matching some specification.
+2. Perform some operations on the data.
+3. Assert something about the result.
+
+You almost certainly will find new bugs with Hypothesis thanks to how it
+cleverly fuzzes your specifications, but the package really shines in
+how it [\"reduces\" failing test
+cases](https://drops.dagstuhl.de/opus/volltexte/2020/13170/) to present
+only the minimal reproducers that trigger said bugs. This demo will
+showcase both its power and user-friendliness.
+
+Let\'s try testing a simple assumption that we can make about our
+`cumulative_sums()` method:
+
+> For an array with positive elements, its cumulative sums should only
+> increment or remain the same per step.
+
+```{=html}
+
+```
+```{=html}
+
+```
+We can write a simple enough Hypothesis-powered test method for this:
+
+``` python
+from hypothesis import given
+from hypothesis.extra.array_api import make_strategies_namespace
+
+xps = make_strategies_namespace(nxp)
+
+@given(xps.arrays(dtype="uint8", shape=10))
+def test_positive_arrays_have_incrementing_sums(x):
+ a = cumulative_sums(x)
+ assert nxp.all(a[1:] >= a[:-1])
+```
+
+As the Array API tools provided by Hypothesis are agnostic to the
+adopting array/tensor libraries, we first need to bind an implementation
+via
+[`make_strategies_namespace()`](https://hypothesis.readthedocs.io/en/latest/numpy.html#hypothesis.extra.array_api.make_strategies_namespace).
+Passing `numpy.array_api` will give us a
+[`SimpleNamespace`](https://docs.python.org/3/library/types.html#types.SimpleNamespace)
+to use these tools for NumPy\'s Array API implementation.
+
+The
+[`@given()`](https://hypothesis.readthedocs.io/en/latest/details.html#hypothesis.given)
+decorator tells Hypothesis what values it should generate for our test
+method. In this case
+[`xps.arrays()`](https://hypothesis.readthedocs.io/en/latest/numpy.html#xps.arrays)
+is a \"search strategy\" that specifies Array API-compliant arrays from
+`numpy.array_api` should be generated.
+
+In this case, `shape=10` specifies the arrays generated are
+1-dimensional and of size 10, and `dtype="uint8"` specifies they should
+contain unsigned integers (which is handy for our test method as uints
+are always positive). Let\'s quickly see a small sample of the arrays
+Hypothesis can generate:
+
+``` python
+for _ in range(10):
+ x = xps.arrays(dtype="uint8", shape=10, unique=True).example()
+ print(repr(x))
+print("...")
+```
+
+```{=html}
+
Array([239, 211, 226, 129, 31, 13, 80, 235, 254, 163], dtype=uint8)
+
+```
+
+```{=html}
+Array([164, 175, 254, 111, 63, 241, 64, 201, 173, 117], dtype=uint8)
+
+```
+
+```{=html}
+Array([106, 149, 210, 230, 58, 37, 66, 153, 203, 181], dtype=uint8)
+
+```
+
+```{=html}
+Array([ 93, 0, 254, 253, 252, 251, 250, 249, 248, 247], dtype=uint8)
+
+```
+
+```{=html}
+Array([ 16, 0, 254, 253, 252, 251, 250, 249, 248, 247], dtype=uint8)
+
+```
+
+```{=html}
+Array([172, 0, 254, 253, 252, 251, 250, 249, 248, 247], dtype=uint8)
+
+```
+
+```{=html}
+Array([129, 0, 254, 253, 252, 251, 250, 249, 248, 247], dtype=uint8)
+
+```
+
+```{=html}
+Array([111, 0, 254, 253, 252, 251, 250, 249, 248, 247], dtype=uint8)
+
+```
+
+```{=html}
+Array([ 67, 0, 254, 253, 252, 251, 250, 249, 248, 247], dtype=uint8)
+
+```
+
+```{=html}
+Array([ 0, 255, 254, 253, 252, 251, 250, 249, 248, 247], dtype=uint8)
+
+```
+
+```{=html}
+...
+
+```
+
+How Hypothesis \"draws\" from its strategies can look rather
+unremarkable at first. A small sample of draws might look fairly uniform
+but trust that strategies will end up covering all kinds of edge cases.
+Importantly it will cover these cases efficiently so that
+Hypothesis-powered tests are *relatively* quick to run on your machine.
+
+All our test method does is get the cumulative sums array `a` that is
+returned from `cumulative_sums(x)`, and then check that every element
+`a[i]` is greater than or equal to `a[i-1]`.
+
+Time to run it!
+
+``` python
+ipytest.run("-k positive_arrays_have_incrementing_sums", "--hypothesis-seed=3")
+```
+
+ F [100%]
+ =================================== FAILURES ===================================
+ _________________ test_positive_arrays_have_incrementing_sums __________________
+
+ @given(xps.arrays(dtype="uint8", shape=10))
+ > def test_positive_arrays_have_incrementing_sums(x):
+
+ :7:
+ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
+
+ x = Array([26, 26, 26, 26, 26, 26, 26, 26, 26, 26], dtype=uint8)
+
+ @given(xps.arrays(dtype="uint8", shape=10))
+ def test_positive_arrays_have_incrementing_sums(x):
+ a = cumulative_sums(x)
+ > assert nxp.all(a[1:] >= a[:-1])
+ E assert Array(False, dtype=bool)
+ E + where Array(False, dtype=bool) = (Array([ 52, 78, 104, 130, 156, 182, 208, 234, 4], dtype=uint8) >= Array([ 26, 52, 78, 104, 130, 156, 182, 208, 234], dtype=uint8))
+ E + where = nxp.all
+
+ :9: AssertionError
+ ---------------------------------- Hypothesis ----------------------------------
+ Falsifying example: test_positive_arrays_have_incrementing_sums(
+ x=Array([26, 26, 26, 26, 26, 26, 26, 26, 26, 26], dtype=uint8),
+ )
+ =========================== short test summary info ============================
+ FAILED ::test_positive_arrays_have_incrementing_sums - assert A...
+ 1 failed, 1 deselected in 0.17s
+
+Hypothesis has tested our assumption and told us we\'re wrong. It
+provides us with the following falsifying example:
+
+``` python
+>>> x = xp.full(10, 26, dtype=xp.uint8)
+>>> x
+Array([ 26, 26, 26, 26, 26, 26, 26, 26, 26, 26], dtype=uint8)
+>>> cumulative_sums(x)
+Array([ 26, 52, 78, 104, 130, 156, 182, 208, 234, 4], dtype=uint8)
+```
+
+You can see that an overflow error has occurred for the final cumulative
+sum, as 234 + 26 (260) cannot be represented in 8-bit unsigned integers.
+
+Let\'s try promoting the dtype of the cumulative sums array so that it
+can represent larger numbers, and then we can run the test again.
+
+``` python
+def max_dtype(xp, dtype):
+ if dtype in [getattr(xp, name) for name in ("int8", "int16", "int32", "int64")]:
+ return xp.int64
+ elif dtype in [getattr(xp, name) for name in ("uint8", "uint16", "uint32", "uint64")]:
+ return xp.uint64
+ else:
+ return xp.float64
+
+def cumulative_sums(x):
+ xp = x.__array_namespace__()
+
+ result = xp.empty(x.size, dtype=max_dtype(xp, x.dtype))
+ result[0] = x[0]
+ for i in range(1, x.size):
+ result[i] = result[i - 1] + x[i]
+
+ return result
+
+ipytest.run("-k positive_arrays_have_incrementing_sums")
+```
+
+ . [100%]
+ 1 passed, 1 deselected in 0.18s
+
+You can see another assumption about our code is:
+
+> We can find the cumulative sums of arrays of any scalar dtype.
+
+We should cover this assumption in our test method
+`test_positive_arrays_have_incrementing_sums` by passing child search
+strategies into our
+[`xps.arrays()`](https://hypothesis.readthedocs.io/en/latest/numpy.html#xps.arrays)
+parent strategy. Specifying `dtype` as
+[`xps.scalar_dtypes()`](https://hypothesis.readthedocs.io/en/latest/numpy.html#xps.scalar_dtypes)
+will tell Hypothesis to generate arrays of all scalar dtypes. To specify
+that these array values should be positive, we can just pass keyword
+arguments to the underlying value generating strategy
+[`xps.from_dtype()`](https://hypothesis.readthedocs.io/en/latest/numpy.html#xps.from_dtype)
+via `elements={"min_value": 0}`.
+
+And while we\'re at it, let\'s make sure to cover another assumption:
+
+> We can find the cumulative sums of arrays with multiple dimensions.
+
+Specifying `shape` as
+[`xps.array_shapes()`](https://hypothesis.readthedocs.io/en/latest/numpy.html#xps.array_shapes)
+will tell Hypothesis to generate arrays of various dimensionality and
+sizes. We can
+[filter](https://hypothesis.readthedocs.io/en/latest/data.html#filtering)
+this strategy with `lambda s: prod(s) > 1` so that always `x.size > 1`,
+allowing our test code to still work.
+
+``` python
+from math import prod
+from hypothesis import settings
+
+@given(
+ xps.arrays(
+ dtype=xps.scalar_dtypes(),
+ shape=xps.array_shapes().filter(lambda s: prod(s) > 1),
+ elements={"min_value": 0},
+ )
+)
+def test_positive_arrays_have_incrementing_sums(x):
+ a = cumulative_sums(x)
+ assert nxp.all(a[1:] >= a[:-1])
+
+ipytest.run("-k positive_arrays_have_incrementing_sums", "--hypothesis-seed=3")
+```
+
+ F [100%]
+ =================================== FAILURES ===================================
+ _________________ test_positive_arrays_have_incrementing_sums __________________
+
+ @given(
+ > xps.arrays(
+ dtype=xps.scalar_dtypes(),
+ shape=xps.array_shapes().filter(lambda s: prod(s) > 1),
+ elements={"min_value": 0},
+ )
+ )
+ E hypothesis.errors.MultipleFailures: Hypothesis found 2 distinct failures.
+
+ :5: MultipleFailures
+ ---------------------------------- Hypothesis ----------------------------------
+ Falsifying example: test_positive_arrays_have_incrementing_sums(
+ x=Array([[False, False]], dtype=bool),
+ )
+ TypeError: only size-1 arrays can be converted to Python scalars
+
+ The above exception was the direct cause of the following exception:
+
+ Traceback (most recent call last):
+ , line 12, in test_positive_arrays_have_incrementing_sums
+ a = cumulative_sums(x)
+ , line 13, in cumulative_sums
+ result[0] = x[0]
+ File "/numpy/array_api/_array_object.py", line 657, in __setitem__
+ self._array.__setitem__(key, asarray(value)._array)
+ ValueError: setting an array element with a sequence.
+
+ Falsifying example: test_positive_arrays_have_incrementing_sums(
+ x=Array([False, False], dtype=bool),
+ )
+ Traceback (most recent call last):
+ , line 12, in test_positive_arrays_have_incrementing_sums
+ a = cumulative_sums(x)
+ , line 15, in cumulative_sums
+ result[i] = result[i - 1] + x[i]
+ File "/numpy/array_api/_array_object.py", line 362, in __add__
+ other = self._check_allowed_dtypes(other, "numeric", "__add__")
+ File "/numpy/array_api/_array_object.py", line 125, in _check_allowed_dtypes
+ raise TypeError(f"Only {dtype_category} dtypes are allowed in {op}")
+ TypeError: Only numeric dtypes are allowed in __add__
+ =========================== short test summary info ============================
+ FAILED ::test_positive_arrays_have_incrementing_sums - hypothes...
+ 1 failed, 1 deselected in 0.38s
+
+Again Hypothesis has proved our assumptions wrong, and this time it\'s
+found two problems.
+
+Firstly, our `cumulative_sums()` method doesn\'t adjust for boolean
+arrays, so we get an error when we add two `bool` values together.
+
+``` python
+>>> x = xp.zeros(2, dtype=xp.bool)
+>>> x
+Array([False, False], dtype=bool)
+>>> cumulative_sums(x)
+Traceback:
+ , line 15, in cumulative_sums
+ result[i] = result[i - 1] + x[i]
+ ...
+TypeError: Only numeric dtypes are allowed in __add__
+```
+
+Secondly, our `cumulative_sums()` method is assuming arrays are
+1-dimensional, so we get an error when we wrongly assume `x[0]` will
+always return a single scalar (technically a 0-dimensional array).
+
+``` python
+>>> x = xp.zeros((1, 2), dtype=xp.bool)
+>>> x
+Array([[False, False]], dtype=bool)
+>>> cumulative_sums(x)
+Traceback:
+ , line 13, in cumulative_sums
+ result[0] = x[0]
+ ...
+TypeError: only size-1 arrays can be converted to Python scalars
+```
+
+I\'m going to flatten input arrays and convert the boolean arrays to
+integer arrays of ones and zeros. Of-course we\'ll run the test again to
+make sure our updated `cumulative_sums()` method now works.
+
+``` python
+def cumulative_sums(x):
+ xp = x.__array_namespace__()
+
+ x = xp.reshape(x, x.size)
+
+ if x.dtype == xp.bool:
+ mask = x
+ dtype = xp.uint64
+ x = xp.zeros(x.shape, dtype=xp.uint64)
+ x[mask] = 1
+
+ result = xp.empty(x.size, dtype=max_dtype(xp, x.dtype))
+ result[0] = x[0]
+ for i in range(1, x.size):
+ result[i] = result[i - 1] + x[i]
+
+ return result
+
+ipytest.run("-k positive_arrays_have_incrementing_sums", "--hypothesis-seed=3")
+```
+
+ F [100%]
+ =================================== FAILURES ===================================
+ _________________ test_positive_arrays_have_incrementing_sums __________________
+
+ @given(
+ > xps.arrays(
+ dtype=xps.scalar_dtypes(),
+ shape=xps.array_shapes().filter(lambda s: prod(s) > 1),
+ elements={"min_value": 0},
+ )
+ )
+
+ :5:
+ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
+
+ x = Array([4611686018427387904, 4611686018427387904], dtype=int64)
+
+ @given(
+ xps.arrays(
+ dtype=xps.scalar_dtypes(),
+ shape=xps.array_shapes().filter(lambda s: prod(s) > 1),
+ elements={"min_value": 0},
+ )
+ )
+ def test_positive_arrays_have_incrementing_sums(x):
+ a = cumulative_sums(x)
+ > assert nxp.all(a[1:] >= a[:-1])
+ E assert Array(False, dtype=bool)
+ E + where Array(False, dtype=bool) = (Array([-9223372036854775808], dtype=int64) >= Array([4611686018427387904], dtype=int64))
+ E + where = nxp.all
+
+ :13: AssertionError
+ ---------------------------------- Hypothesis ----------------------------------
+ Falsifying example: test_positive_arrays_have_incrementing_sums(
+ x=Array([4611686018427387904, 4611686018427387904], dtype=int64),
+ )
+ =========================== short test summary info ============================
+ FAILED ::test_positive_arrays_have_incrementing_sums - assert A...
+ 1 failed, 1 deselected in 1.24s
+
+We resolved our two previous issues\... but Hypothesis has found yet
+another failing scenario 🙃
+
+``` python
+>>> x = xp.full(2, 4611686018427387904, dtype=xp.int64)
+>>> x
+Array([ 4611686018427387904, 4611686018427387904], dtype=int64)
+>>> cumulative_sums(x)
+Array([ 4611686018427387904, -9223372036854775808], dtype=int64)
+```
+
+An overflow has occurred again, which we can\'t do much about it this
+time. There\'s no larger signed integer dtype than `int64` (in the Array
+API), so we\'ll just have `cumulative_sums()` detect overflows itself.
+
+``` python
+def cumulative_sums(x):
+ xp = x.__array_namespace__()
+
+ x = xp.reshape(x, x.size)
+
+ if x.dtype == xp.bool:
+ mask = x
+ dtype = xp.uint64
+ x = xp.zeros(x.shape, dtype=xp.uint64)
+ x[mask] = 1
+
+ result = xp.empty(x.size, dtype=max_dtype(xp, x.dtype))
+ result[0] = x[0]
+ for i in range(1, x.size):
+ result[i] = result[i - 1] + x[i]
+ if result[i] < result[i - 1]:
+ raise OverflowError("Cumulative sum cannot be represented")
+
+ return result
+```
+
+If Hypothesis generates arrays which raise `OverflowError`, we can just
+catch it and use
+[`assume(False)`](https://hypothesis.readthedocs.io/en/latest/details.html#making-assumptions)
+to ignore testing these arrays on runtime. This \"filter-on-runtime\"
+behaviour can be very handy at times, although [their docs note
+`assume()` can be
+problematic](https://hypothesis.readthedocs.io/en/latest/details.html#how-good-is-assume).
+
+We can also explicitly cover overflows in a separate test.
+
+``` python
+from hypothesis import assume
+import pytest
+
+@given(
+ xps.arrays(
+ dtype=xps.scalar_dtypes(),
+ shape=xps.array_shapes().filter(lambda s: prod(s) > 1),
+ elements={"min_value": 0},
+ )
+)
+def test_positive_arrays_have_incrementing_sums(x):
+ try:
+ a = cumulative_sums(x)
+ assert nxp.all(a[1:] >= a[:-1])
+ except OverflowError:
+ assume(False)
+
+def test_error_on_overflow():
+ x = nxp.asarray([nxp.iinfo(nxp.uint64).max, 1], dtype=nxp.uint64)
+ with pytest.raises(OverflowError):
+ cumulative_sums(x)
+
+ipytest.run()
+```
+
+ ... [100%]
+ 3 passed in 0.27s
+
+Our little test suite finally passes 😅
+
+If you\'re feeling adventurous, you might want to get [this very
+notebook](https://github.com/Quansight-Labs/quansight-labs-site/tree/main/posts/2021/10/hypothesis-array-api.ipynb)
+running and see if you can write some test cases yourself---bonus points
+if they fail! For starters, how about testing that cumulative sums
+*decrease* with arrays containing negative elements?
+
+When you\'re developing an Array API array-consuming method, and an
+equivalent method already exists for one of the adopting libraries, I
+highly recommend using Hypothesis to compare its results to your own.
+For example, we could use the battle-tested
+[`np.cumsum()`](https://numpy.org/doc/stable/reference/generated/numpy.cumsum.html)
+to see how our `cumulative_sums()` method compares:
+
+``` python
+import numpy as np
+
+@given(xps.arrays(dtype=xps.scalar_dtypes(), shape=xps.array_shapes()))
+def test_reference_implementation(x):
+ our_out = cumulative_sums(x)
+ # We convert numpy.array_api arrays into NumPy's top-level "ndarray"
+ # structure, so we can compare our results with np.cumsum().
+ # We do this via np.asarray(obj), which will see if obj supports
+ # NumPy's interface protocol to subsequently get the underlying
+ # ndarray from obj - fortunately arrays generated from
+ # numpy.array_api do support this!
+ # See https://numpy.org/devdocs/user/basics.interoperability.html
+ our_out = np.asarray(our_out)
+ their_out = np.cumsum(np.asarray(x))
+ assert np.all(our_out == their_out)
+```
+
+```{=html}
+
+```
+Such \"differential testing\" is a great exercise to really think about
+what your code does, even if ultimately you conclude that you are happy
+with different results.
+
+Zac Hatfield-Dodds, who maintains Hypothesis, writes more about
+differential testing in their short paper [\"Falsify your Software:
+validating scientific code with property-based
+testing\"](http://conference.scipy.org/proceedings/scipy2020/zac_hatfield-dodds.html).
+Generally it\'s a great read if you want more ideas on how Hypothesis
+can make your array-consuming libraries robust!
+
+## Watch this space
+
+This year should see a first
+[version](https://data-apis.org/array-api/latest/future_API_evolution.html#versioning)
+of the Array API standard, and subsequently NumPy shipping
+`numpy.array_api` out to the world---this means array-consuming
+libraries will be able to reliably develop for the Array API quite soon.
+I hope I\'ve demonstrated why you should try Hypothesis when the time
+comes 🙂
+
+Good news is that I\'m extending my stay at Quansight. My job is to help
+unify Python\'s fragmented scientific ecosystem, so I\'m more than happy
+to respond to any inquiries about using Hypothesis for the Array API via
+[email](mailto:quitesimplymatt@gmail.com) or
+[Twitter](https://twitter.com/whostolehonno).
+
+For now I\'m contributing to the Hypothesis-powered [Array API
+compliance suite](https://github.com/data-apis/array-api-tests), which
+is already being used by the NumPy team to ensure `numpy.array_api`
+actually complies with every tiny detail of the
+[specification](https://data-apis.org/array-api/latest/). This process
+has the added side-effect of finding limitations in
+[`hypothesis.extra.array_api`](https://hypothesis.readthedocs.io/en/latest/numpy.html#array-api),
+so you can expect Hypothesis to only improve from here on out!
+
diff --git a/apps/labs/public/posts/hypothesis-array-api/hypothesis-array-api-social.png b/apps/labs/public/posts/hypothesis-array-api/hypothesis-array-api-social.png
new file mode 100644
index 000000000..92be45e98
Binary files /dev/null and b/apps/labs/public/posts/hypothesis-array-api/hypothesis-array-api-social.png differ
| | | | | | | | | | | | | |