Repository: computationalgeography/lue (language: python)

Issue:
Add overloads for `add` / `+` accepting `future<Element>`



Discussion / hints:

Fix patch:
diff --git a/.codacy.yaml b/.codacy.yaml
new file mode 100644
index 000000000..200b92097
--- /dev/null
+++ b/.codacy.yaml
@@ -0,0 +1,19 @@
+---
+exclude_paths:
+    - "document/**"
+    - "environment/**"
+engines:
+    - markdownlint:
+        # Keep these settings in sync with .mdl_style.rb
+        - MD004: false
+        - MD005: false
+        - MD007:
+            - indent: 4
+        - MD012: false
+        - MD013:
+            - line_length: 110
+        - MD024: false
+        - MD030: false
+        - MD034: false
+        - MD041: false
+        - MD046: false
diff --git a/.editorconfig b/.editorconfig
index 40a75e425..2ee2b22b4 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -7,14 +7,8 @@ charset = utf-8
 indent_style = space
 indent_size = 4
 insert_final_newline = true
-max_line_length = 80
-trim_trailing_whitespace = true
-
-[*.{c,cpp,h,hpp,md,rb,rst,txt,yaml,yml}]
 max_line_length = 110
-
-[*.py]
-max_line_length = 90
+trim_trailing_whitespace = true
 
 [*.yml]
 indent_size = 2
diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml
index 4b7816e31..0affcba04 100644
--- a/.github/workflows/linux.yml
+++ b/.github/workflows/linux.yml
@@ -172,6 +172,7 @@ jobs:
               ctest \
                   --test-dir ${{ env.lue_build_directory }} \
                   --output-on-failure \
+                  --exclude-regex algorithm_image_land_integrate_test \
                   --exclude-regex lue_py_image_land_python_test
 
               # Test of runtime targets
diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml
index de60579f9..11b044e6c 100644
--- a/.github/workflows/macos.yml
+++ b/.github/workflows/macos.yml
@@ -172,6 +172,7 @@ jobs:
               ctest \
                   --test-dir ${{ env.lue_build_directory }} \
                   --output-on-failure \
+                  --exclude-regex algorithm_image_land_integrate_test \
                   --exclude-regex lue_py_image_land_python_test
 
               # Test of runtime targets
diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml
index 66752ccf1..08ea93bbb 100644
--- a/.github/workflows/windows.yml
+++ b/.github/workflows/windows.yml
@@ -189,6 +189,7 @@ jobs:
               ctest \
                   --test-dir ${{ env.lue_build_directory }} \
                   --output-on-failure \
+                  --exclude-regex algorithm_image_land_integrate_test \
                   --exclude-regex lue_py_image_land_python_test
 
               # Tests of runtime targets
diff --git a/.mdl_style.rb b/.mdl_style.rb
index 5dce73c50..6ca9b3ba1 100644
--- a/.mdl_style.rb
+++ b/.mdl_style.rb
@@ -1,3 +1,5 @@
+# Keep these settings in sync with .codacy.yaml
+
 # https://github.com/markdownlint/markdownlint/blob/main/docs/configuration.md
 # https://github.com/markdownlint/markdownlint/blob/main/docs/RULES.md
 all
@@ -11,5 +13,5 @@
 exclude_rule 'MD046'
 
 # The parameters which can be changed are mentioned in the rules page (Parameters: ...)
-rule 'MD013', :line_length => 110
 rule 'MD007', :indent => 4
+rule 'MD013', :line_length => 110
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 616bf4b93..9c1819a52 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,5 +1,5 @@
 cmake_minimum_required(
-    VERSION 3.26)
+    VERSION 3.28)
 project(LUE
     VERSION 0.3.8
     LANGUAGES C CXX
diff --git a/document/doc/CMakeLists.txt b/document/doc/CMakeLists.txt
index 43a0698ce..241f0301e 100644
--- a/document/doc/CMakeLists.txt
+++ b/document/doc/CMakeLists.txt
@@ -32,6 +32,7 @@ foreach(name IN ITEMS
     about/publication.md
     about/related.md
     about/release.md
+    about/short_description.md
     contribute/documentation.md
     contribute/index.md
     contribute/release.md
@@ -63,8 +64,9 @@ foreach(name IN ITEMS
     reference/c/index.md
     reference/cpp/index.md
     reference/index.md
-    reference/java/index.md
-    reference/julia/index.md
+    # reference/fortran/index.md
+    # reference/java/index.md
+    # reference/julia/index.md
     reference/operation/index.md
     reference/operation/uniform.md
     # reference/python/data_model/index.rst
@@ -72,8 +74,8 @@ foreach(name IN ITEMS
     # reference/python/data_model/index.rst
     # reference/python/framework/index.rst
     reference/python/index.md
-    reference/r/index.md
-    reference/rust/index.md
+    # reference/r/index.md
+    # reference/rust/index.md
     references.bib
     reference/utility/index.md
     reference/utility/lue_calculate.md
@@ -81,7 +83,6 @@ foreach(name IN ITEMS
     reference/utility/lue_translate.md
     reference/utility/lue_validate.md
     reference/utility/lue_view.md
-    short_description.md
     _toc.yml
 )
     configure_file(${name} ${name} COPYONLY)
@@ -98,6 +99,9 @@ foreach(name IN ITEMS
     framework/algorithm/doc/policy/range.md
     framework/algorithm/doc/template.md
 
+    framework/api/doc/index.md
+    framework/api/cxx/doc/index.md
+
     framework/doc/test/index.md
 
     framework/doc/howto/index.md
@@ -115,6 +119,7 @@ foreach(name IN ITEMS
     framework/algorithm/doc/grouped_operation/array_operation.md
     framework/algorithm/doc/grouped_operation/random_number_operation.md
 
+    framework/core/doc/index.md
     framework/partitioned_array/doc/index.md
     framework/partitioned_route/doc/index.md
 
diff --git a/document/doc/_toc.yml b/document/doc/_toc.yml
index 832cdee6c..31b07ef24 100644
--- a/document/doc/_toc.yml
+++ b/document/doc/_toc.yml
@@ -35,12 +35,18 @@ parts:
       - file: reference/operation/index.md
         sections:
         - file: reference/operation/uniform.md
-      - file: reference/c/index.md
-      - file: reference/cpp/index.md
-      - file: reference/java/index.md
-      - file: reference/julia/index.md
-      - file: reference/python/index.md
-      - file: reference/r/index.md
+      - file: source/framework/api/doc/index.md
+        sections:
+        - file: reference/c/index.md
+        - file: reference/cpp/index.md
+          sections:
+          - file: source/framework/api/cxx/doc/index.md
+        # - file: reference/fortran/index.md
+        # - file: reference/java/index.md
+        # - file: reference/julia/index.md
+        - file: reference/python/index.md
+        # - file: reference/r/index.md
+        # - file: reference/rust/index.md
       - file: reference/utility/index.md
         sections:
         - file: reference/utility/lue_calculate.md
@@ -70,6 +76,7 @@ parts:
       - file: source/data_model/doc/index.md
       - file: source/framework/doc/index.md
         sections:
+        - file: source/framework/core/doc/index.md
         - file: source/framework/partitioned_array/doc/index.md
         - file: source/framework/partitioned_route/doc/index.md
         - file: source/framework/algorithm/doc/index.md
diff --git a/document/doc/short_description.md b/document/doc/about/short_description.md
similarity index 100%
rename from document/doc/short_description.md
rename to document/doc/about/short_description.md
diff --git a/document/doc/reference/cpp/index.md b/document/doc/reference/cpp/index.md
index 44af2ddfe..55c84f59d 100644
--- a/document/doc/reference/cpp/index.md
+++ b/document/doc/reference/cpp/index.md
@@ -1,3 +1,1 @@
 # C++ reference [WIP]
-
-Work in progress.
diff --git a/document/doc/reference/fortran/index.md b/document/doc/reference/fortran/index.md
new file mode 100644
index 000000000..d558c8beb
--- /dev/null
+++ b/document/doc/reference/fortran/index.md
@@ -0,0 +1,4 @@
+# Fortran reference [TODO]
+
+If Fortran language bindings to LUE interest you, you may want to [help us](#doc-contribute) adding them. Do
+[contact](https://lue.computationalgeography.org/) us if you want to discuss this.
diff --git a/environment/cmake/Lue.cmake b/environment/cmake/Lue.cmake
index bbc328a83..8c9d35be4 100644
--- a/environment/cmake/Lue.cmake
+++ b/environment/cmake/Lue.cmake
@@ -9,6 +9,10 @@ include(GenerateExportHeader)
 
 set(LUE_CXX_STANDARD 20)
 
+if(CMAKE_VERSION VERSION_GREATER "2.28.0")
+    set(CMAKE_CXX_SCAN_FOR_MODULES FALSE)
+endif()
+
 # Handle configuration and 3rd party libraries and tools, and ...
 include(LueConfiguration)
 
diff --git a/environment/cmake/LueConfiguration.cmake b/environment/cmake/LueConfiguration.cmake
index 1f6949c6e..39c5f2b1c 100644
--- a/environment/cmake/LueConfiguration.cmake
+++ b/environment/cmake/LueConfiguration.cmake
@@ -122,17 +122,6 @@ if(LUE_BUILD_DATA_MODEL)
 endif()
 
 
-if(LUE_BUILD_QA)
-    if(LUE_QA_WITH_TESTS)
-        set(ENV{CTEST_OUTPUT_ON_FAILURE} "1")
-    endif()
-endif()
-
-
-if(LUE_BUILD_DOCUMENTATION)
-endif()
-
-
 set(LUE_TEMPLATIZE "${PROJECT_SOURCE_DIR}/environment/script/templatize.py")
 
 # NOTE These can be made configurable later on
diff --git a/environment/cmake/lue_package.cmake b/environment/cmake/lue_package.cmake
index 9fe6ca2cd..fa0540342 100644
--- a/environment/cmake/lue_package.cmake
+++ b/environment/cmake/lue_package.cmake
@@ -7,7 +7,7 @@ set(CPACK_PACKAGE_VERSION_MINOR ${PROJECT_VERSION_MINOR})
 set(CPACK_PACKAGE_VERSION_PATCH ${PROJECT_VERSION_PATCH})
 set(CPACK_PACKAGE_INSTALL_DIRECTORY ${CPACK_PACKAGE_NAME})
 set(CPACK_PACKAGE_DESCRIPTION_FILE
-    ${${PROJECT_NAME}_SOURCE_DIR}/document/doc/short_description.md)
+    ${${PROJECT_NAME}_SOURCE_DIR}/document/doc/about/short_description.md)
 
 set(CPACK_SOURCE_PACKAGE_FILE_NAME ${LUE_LOWER_PROJECT_NAME}-${LUE_VERSION})
 set(CPACK_SOURCE_IGNORE_FILES
diff --git a/source/framework/algorithm/doc/index.md b/source/framework/algorithm/doc/index.md
index 1e46e3cd5..630fa5fcc 100644
--- a/source/framework/algorithm/doc/index.md
+++ b/source/framework/algorithm/doc/index.md
@@ -1,4 +1,4 @@
-# Algorithms
+# `lue_framework_algorithm`
 
 
 These are top-level algorithms that can be called in any order. They take one or more partitioned arrays as
diff --git a/source/framework/algorithm/include/lue/framework/algorithm/add.hpp b/source/framework/algorithm/include/lue/framework/algorithm/add.hpp
index 75f0d8447..39dc9667f 100644
--- a/source/framework/algorithm/include/lue/framework/algorithm/add.hpp
+++ b/source/framework/algorithm/include/lue/framework/algorithm/add.hpp
@@ -33,6 +33,6 @@ namespace lue {
     }  // namespace policy::add
 
 
-    LUE_BINARY_LOCAL_OPERATION_OVERLOADS4(add, detail::Add)
+    LUE_BINARY_LOCAL_OPERATION_OVERLOADS_WITH_POLICIES(add, detail::Add)
 
 }  // namespace lue
diff --git a/source/framework/algorithm/include/lue/framework/algorithm/all.hpp b/source/framework/algorithm/include/lue/framework/algorithm/all.hpp
index ab2cb319f..446713840 100644
--- a/source/framework/algorithm/include/lue/framework/algorithm/all.hpp
+++ b/source/framework/algorithm/include/lue/framework/algorithm/all.hpp
@@ -56,7 +56,7 @@ namespace lue {
 
 
     template<typename Policies, typename Element, Rank rank>
-    hpx::future<Element> all(Policies const& policies, PartitionedArray<Element, rank> const& array)
+    auto all(Policies const& policies, PartitionedArray<Element, rank> const& array) -> Scalar<Element>
     {
         using Functor = detail::All<Element>;
 
@@ -65,10 +65,10 @@ namespace lue {
 
 
     template<typename Policies, typename Element, Rank rank>
-    hpx::future<Element> all(
+    auto all(
         hpx::id_type const locality_id,
         Policies const& policies,
-        ArrayPartition<Element, rank> const& partition)
+        ArrayPartition<Element, rank> const& partition) -> Scalar<Element>
     {
         using Functor = detail::All<Element>;
 
diff --git a/source/framework/algorithm/include/lue/framework/algorithm/any.hpp b/source/framework/algorithm/include/lue/framework/algorithm/any.hpp
index c88a5ad44..c0af84cdc 100644
--- a/source/framework/algorithm/include/lue/framework/algorithm/any.hpp
+++ b/source/framework/algorithm/include/lue/framework/algorithm/any.hpp
@@ -73,7 +73,7 @@ namespace lue {
 
 
     template<typename Element, Rank rank>
-    hpx::future<Element> any(PartitionedArray<Element, rank> const& array)
+    auto any(PartitionedArray<Element, rank> const& array) -> Scalar<Element>
     {
         using Functor = detail::Any<Element>;
         using Policies = policy::any::DefaultPolicies<Element>;
diff --git a/source/framework/algorithm/include/lue/framework/algorithm/binary_local_operation.hpp b/source/framework/algorithm/include/lue/framework/algorithm/binary_local_operation.hpp
index dd1d65cf0..62d30479b 100644
--- a/source/framework/algorithm/include/lue/framework/algorithm/binary_local_operation.hpp
+++ b/source/framework/algorithm/include/lue/framework/algorithm/binary_local_operation.hpp
@@ -8,40 +8,36 @@ namespace lue {
 
     // local_operation(partition, scalar)
     template<typename Policies, typename InputElement1, typename InputElement2, Rank rank, typename Functor>
-    ArrayPartition<OutputElementT<Functor>, rank> binary_local_operation(
-        hpx::id_type const locality_id,
+    auto binary_local_operation(
+        hpx::id_type locality_id,
         Policies const& policies,
         ArrayPartition<InputElement1, rank> const& input_partition,
         hpx::shared_future<InputElement2> const& input_scalar,
-        Functor const& functor);
-
+        Functor const& functor) -> ArrayPartition<OutputElementT<Functor>, rank>;
 
     // local_operation(array, array)
     template<typename Policies, typename InputElement1, typename InputElement2, Rank rank, typename Functor>
-    PartitionedArray<OutputElementT<Functor>, rank> binary_local_operation(
+    auto binary_local_operation(
         Policies const& policies,
         PartitionedArray<InputElement1, rank> const& input_array1,
         PartitionedArray<InputElement2, rank> const& input_array2,
-        Functor const& functor);
-
+        Functor const& functor) -> PartitionedArray<OutputElementT<Functor>, rank>;
 
     // local_operation(array, scalar)
     template<typename Policies, typename InputElement1, typename InputElement2, Rank rank, typename Functor>
-    PartitionedArray<OutputElementT<Functor>, rank> binary_local_operation(
+    auto binary_local_operation(
         Policies const& policies,
         PartitionedArray<InputElement1, rank> const& input_array,
         hpx::shared_future<InputElement2> const& input_scalar,
-        Functor const& functor);
-
+        Functor const& functor) -> PartitionedArray<OutputElementT<Functor>, rank>;
 
     // local_operation(scalar, array)
     template<typename Policies, typename InputElement1, typename InputElement2, Rank rank, typename Functor>
-    PartitionedArray<OutputElementT<Functor>, rank> binary_local_operation(
+    auto binary_local_operation(
         Policies const& policies,
         hpx::shared_future<InputElement1> const& input_scalar,
         PartitionedArray<InputElement2, rank> const& input_array,
-        Functor const& functor);
-
+        Functor const& functor) -> PartitionedArray<OutputElementT<Functor>, rank>;
 
     // local_operation(scalar, scalar)
     template<typename Policies, typename InputElement1, typename InputElement2, typename Functor>
@@ -54,412 +50,8 @@ namespace lue {
 }  // namespace lue
 
 
-#define LUE_BINARY_LOCAL_OPERATION_OVERLOADS(name, Functor)                                                  \
-                                                                                                             \
-    /* f(policies, array, array) */                                                                          \
-    template<typename Policies, typename InputElement, Rank rank>                                            \
-    auto name(                                                                                               \
-        Policies const& policies,                                                                            \
-        PartitionedArray<InputElement, rank> const& array1,                                                  \
-        PartitionedArray<InputElement, rank> const& array2)                                                  \
-    {                                                                                                        \
-        using OutputElement = OutputElementT<Functor<InputElement>>;                                         \
-                                                                                                             \
-        return binary_local_operation(policies, array1, array2, Functor<InputElement, OutputElement>{});     \
-    }                                                                                                        \
-                                                                                                             \
-                                                                                                             \
-    /* f(array, array) */                                                                                    \
-    template<typename InputElement, Rank rank>                                                               \
-    auto name(                                                                                               \
-        PartitionedArray<InputElement, rank> const& array1,                                                  \
-        PartitionedArray<InputElement, rank> const& array2)                                                  \
-    {                                                                                                        \
-        using OutputElement = OutputElementT<Functor<InputElement>>;                                         \
-        using Policies = policy::name::DefaultPolicies<OutputElement, InputElement>;                         \
-                                                                                                             \
-        return name(Policies{}, array1, array2);                                                             \
-    }                                                                                                        \
-                                                                                                             \
-                                                                                                             \
-    /* f(policies, array, scalar) */                                                                         \
-    template<typename Policies, typename OutputElement, typename InputElement, Rank rank>                    \
-    PartitionedArray<OutputElement, rank> name(                                                              \
-        Policies const& policies,                                                                            \
-        PartitionedArray<InputElement, rank> const& array,                                                   \
-        hpx::shared_future<InputElement> const& scalar)                                                      \
-    {                                                                                                        \
-        return binary_local_operation(policies, array, scalar, Functor<InputElement, OutputElement>{});      \
-    }                                                                                                        \
-                                                                                                             \
-                                                                                                             \
-    /* f(policies, array, scalar) */                                                                         \
-    template<typename Policies, typename InputElement, Rank rank>                                            \
-    auto name(                                                                                               \
-        Policies const& policies,                                                                            \
-        PartitionedArray<InputElement, rank> const& array,                                                   \
-        hpx::shared_future<InputElement> const& scalar)                                                      \
-    {                                                                                                        \
-        using OutputElement = OutputElementT<Functor<InputElement>>;                                         \
-                                                                                                             \
-        return name<Policies, OutputElement, InputElement, rank>(policies, array, scalar);                   \
-    }                                                                                                        \
-                                                                                                             \
-                                                                                                             \
-    /* f(policies, array, scalar) */                                                                         \
-    template<typename Policies, typename InputElement, Rank rank>                                            \
-    auto name(                                                                                               \
-        Policies const& policies,                                                                            \
-        PartitionedArray<InputElement, rank> const& array,                                                   \
-        InputElement const scalar)                                                                           \
-    {                                                                                                        \
-        return name(policies, array, hpx::make_ready_future<InputElement>(scalar).share());                  \
-    }                                                                                                        \
-                                                                                                             \
-                                                                                                             \
-    /* f(array, scalar) */                                                                                   \
-    template<typename OutputElement, typename InputElement, Rank rank>                                       \
-    PartitionedArray<OutputElement, rank> name(                                                              \
-        PartitionedArray<InputElement, rank> const& array, hpx::shared_future<InputElement> const& scalar)   \
-    {                                                                                                        \
-        using Policies = policy::name::DefaultPolicies<OutputElement, InputElement>;                         \
-                                                                                                             \
-        return name<Policies, OutputElement, InputElement, rank>(Policies{}, array, scalar);                 \
-    }                                                                                                        \
-                                                                                                             \
-                                                                                                             \
-    /* f(array, scalar) */                                                                                   \
-    template<typename OutputElement, typename InputElement, Rank rank>                                       \
-    PartitionedArray<OutputElement, rank> name(                                                              \
-        PartitionedArray<InputElement, rank> const& array, InputElement const scalar)                        \
-    {                                                                                                        \
-        return name<OutputElement, InputElement, rank>(                                                      \
-            array, hpx::make_ready_future<InputElement>(scalar).share());                                    \
-    }                                                                                                        \
-                                                                                                             \
-                                                                                                             \
-    /* f(array, scalar) */                                                                                   \
-    template<typename InputElement, Rank rank>                                                               \
-    auto name(                                                                                               \
-        PartitionedArray<InputElement, rank> const& array, hpx::shared_future<InputElement> const& scalar)   \
-    {                                                                                                        \
-        using OutputElement = OutputElementT<Functor<InputElement>>;                                         \
-                                                                                                             \
-        return name<OutputElement, InputElement, rank>(array, scalar);                                       \
-    }                                                                                                        \
-                                                                                                             \
-                                                                                                             \
-    /* f(array, scalar) */                                                                                   \
-    template<typename InputElement, Rank rank>                                                               \
-    auto name(PartitionedArray<InputElement, rank> const& array, InputElement const scalar)                  \
-    {                                                                                                        \
-        return name(array, hpx::make_ready_future<InputElement>(scalar).share());                            \
-    }                                                                                                        \
-                                                                                                             \
-                                                                                                             \
-    /* f<OutputElement, InputElement>(policies, scalar_f, array) */                                          \
-    template<typename Policies, typename OutputElement, typename InputElement, Rank rank>                    \
-    PartitionedArray<OutputElement, rank> name(                                                              \
-        Policies const& policies,                                                                            \
-        hpx::shared_future<InputElement> const& scalar,                                                      \
-        PartitionedArray<InputElement, rank> const& array)                                                   \
-    {                                                                                                        \
-        return binary_local_operation(policies, scalar, array, Functor<InputElement, OutputElement>{});      \
-    }                                                                                                        \
-                                                                                                             \
-                                                                                                             \
-    /* f<OutputElement, InputElement>(scalar_f, array) */                                                    \
-    template<typename OutputElement, typename InputElement, Rank rank>                                       \
-    PartitionedArray<OutputElement, rank> name(                                                              \
-        hpx::shared_future<InputElement> const& scalar, PartitionedArray<InputElement, rank> const& array)   \
-    {                                                                                                        \
-        using Policies = policy::name::DefaultPolicies<OutputElement, InputElement>;                         \
-                                                                                                             \
-        return name<Policies, OutputElement, InputElement, rank>(Policies{}, scalar, array);                 \
-    }                                                                                                        \
-                                                                                                             \
-                                                                                                             \
-    /* f<OutputElement, InputElement(policies, scalar, array) */                                             \
-    template<typename Policies, typename OutputElement, typename InputElement, Rank rank>                    \
-    PartitionedArray<OutputElement, rank> name(                                                              \
-        Policies const& policies,                                                                            \
-        InputElement const scalar,                                                                           \
-        PartitionedArray<InputElement, rank> const& array)                                                   \
-    {                                                                                                        \
-        return binary_local_operation(                                                                       \
-            policies,                                                                                        \
-            hpx::make_ready_future<InputElement>(scalar),                                                    \
-            array,                                                                                           \
-            Functor<InputElement, OutputElement>{});                                                         \
-    }                                                                                                        \
-                                                                                                             \
-                                                                                                             \
-    /* f<OutputElement, InputElement>(scalar, array) */                                                      \
-    template<typename OutputElement, typename InputElement, Rank rank>                                       \
-    PartitionedArray<OutputElement, rank> name(                                                              \
-        InputElement const scalar, PartitionedArray<InputElement, rank> const& array)                        \
-    {                                                                                                        \
-        return name<OutputElement, InputElement, rank>(                                                      \
-            hpx::make_ready_future<InputElement>(scalar).share(), array);                                    \
-    }                                                                                                        \
-                                                                                                             \
-                                                                                                             \
-    /* f<InputElement, InputElement>(policies, scalar_f, array) */                                           \
-    template<typename Policies, typename InputElement, Rank rank>                                            \
-    auto name(                                                                                               \
-        Policies const& policies,                                                                            \
-        hpx::shared_future<InputElement> const& scalar,                                                      \
-        PartitionedArray<InputElement, rank> const& array)                                                   \
-    {                                                                                                        \
-        using OutputElement = OutputElementT<Functor<InputElement>>;                                         \
-                                                                                                             \
-        return name<Policies, OutputElement, InputElement, rank>(policies, scalar, array);                   \
-    }                                                                                                        \
-                                                                                                             \
-                                                                                                             \
-    /* f<InputElement, InputElement>(scalar_f, array) */                                                     \
-    template<typename InputElement, Rank rank>                                                               \
-    auto name(                                                                                               \
-        hpx::shared_future<InputElement> const& scalar, PartitionedArray<InputElement, rank> const& array)   \
-    {                                                                                                        \
-        using OutputElement = OutputElementT<Functor<InputElement>>;                                         \
-        using Policies = policy::name::DefaultPolicies<OutputElement, InputElement>;                         \
-                                                                                                             \
-        return name<Policies, OutputElement, InputElement, rank>(Policies{}, scalar, array);                 \
-    }                                                                                                        \
-                                                                                                             \
-                                                                                                             \
-    /* f<InputElement, InputElement>(policies, scalar, array) */                                             \
-    template<typename Policies, typename InputElement, Rank rank>                                            \
-    auto name(                                                                                               \
-        Policies const& policies,                                                                            \
-        InputElement const scalar,                                                                           \
-        PartitionedArray<InputElement, rank> const& array)                                                   \
-    {                                                                                                        \
-        using OutputElement = OutputElementT<Functor<InputElement>>;                                         \
-                                                                                                             \
-        return name<Policies, OutputElement, InputElement, rank>(                                            \
-            policies, hpx::make_ready_future<InputElement>(scalar), array);                                  \
-    }                                                                                                        \
-                                                                                                             \
-                                                                                                             \
-    /* f<InputElement, InputElement>(scalar, array) */                                                       \
-    template<typename InputElement, Rank rank>                                                               \
-    auto name(InputElement const scalar, PartitionedArray<InputElement, rank> const& array)                  \
-    {                                                                                                        \
-        using OutputElement = OutputElementT<Functor<InputElement>>;                                         \
-                                                                                                             \
-        return name<OutputElement, InputElement, rank>(                                                      \
-            hpx::make_ready_future<InputElement>(scalar).share(), array);                                    \
-    }
-
-
-// All overloads *without* a Policies template parameter
-#define LUE_BINARY_LOCAL_OPERATION_OVERLOADS2(name, Functor, Policies)                                       \
-                                                                                                             \
-    /* f(array, array) */                                                                                    \
-    template<typename InputElement, Rank rank>                                                               \
-    auto name(                                                                                               \
-        PartitionedArray<InputElement, rank> const& array1,                                                  \
-        PartitionedArray<InputElement, rank> const& array2)                                                  \
-    {                                                                                                        \
-        using OutputElement = OutputElementT<Functor<InputElement>>;                                         \
-        using Policies_ = Policies<OutputElement, InputElement>;                                             \
-                                                                                                             \
-        return name(Policies_{}, array1, array2);                                                            \
-    }                                                                                                        \
-                                                                                                             \
-                                                                                                             \
-    /* f(array, scalar) */                                                                                   \
-    template<typename OutputElement, typename InputElement, Rank rank>                                       \
-    PartitionedArray<OutputElement, rank> name(                                                              \
-        PartitionedArray<InputElement, rank> const& array, hpx::shared_future<InputElement> const& scalar)   \
-    {                                                                                                        \
-        using Policies_ = Policies<OutputElement, InputElement>;                                             \
-                                                                                                             \
-        return name<Policies_, OutputElement, InputElement, rank>(Policies_{}, array, scalar);               \
-    }                                                                                                        \
-                                                                                                             \
-                                                                                                             \
-    /* f(array, scalar) */                                                                                   \
-    template<typename OutputElement, typename InputElement, Rank rank>                                       \
-    PartitionedArray<OutputElement, rank> name(                                                              \
-        PartitionedArray<InputElement, rank> const& array, InputElement const scalar)                        \
-    {                                                                                                        \
-        return name<OutputElement, InputElement, rank>(                                                      \
-            array, hpx::make_ready_future<InputElement>(scalar).share());                                    \
-    }                                                                                                        \
-                                                                                                             \
-                                                                                                             \
-    /* f(array, scalar) */                                                                                   \
-    template<typename InputElement, Rank rank>                                                               \
-    auto name(                                                                                               \
-        PartitionedArray<InputElement, rank> const& array, hpx::shared_future<InputElement> const& scalar)   \
-    {                                                                                                        \
-        using OutputElement = OutputElementT<Functor<InputElement>>;                                         \
-                                                                                                             \
-        return name<OutputElement, InputElement, rank>(array, scalar);                                       \
-    }                                                                                                        \
-                                                                                                             \
-                                                                                                             \
-    /* f(array, scalar) */                                                                                   \
-    template<typename InputElement, Rank rank>                                                               \
-    auto name(PartitionedArray<InputElement, rank> const& array, InputElement const scalar)                  \
-    {                                                                                                        \
-        return name(array, hpx::make_ready_future<InputElement>(scalar).share());                            \
-    }                                                                                                        \
-                                                                                                             \
-                                                                                                             \
-    /* f<OutputElement, InputElement>(scalar_f, array) */                                                    \
-    template<typename OutputElement, typename InputElement, Rank rank>                                       \
-    PartitionedArray<OutputElement, rank> name(                                                              \
-        hpx::shared_future<InputElement> const& scalar, PartitionedArray<InputElement, rank> const& array)   \
-    {                                                                                                        \
-        using Policies_ = Policies<OutputElement, InputElement>;                                             \
-                                                                                                             \
-        return name<Policies_, OutputElement, InputElement, rank>(Policies_{}, scalar, array);               \
-    }                                                                                                        \
-                                                                                                             \
-                                                                                                             \
-    /* f<OutputElement, InputElement>(scalar, array) */                                                      \
-    template<typename OutputElement, typename InputElement, Rank rank>                                       \
-    PartitionedArray<OutputElement, rank> name(                                                              \
-        InputElement const scalar, PartitionedArray<InputElement, rank> const& array)                        \
-    {                                                                                                        \
-        return name<OutputElement, InputElement, rank>(                                                      \
-            hpx::make_ready_future<InputElement>(scalar).share(), array);                                    \
-    }                                                                                                        \
-                                                                                                             \
-                                                                                                             \
-    /* f<InputElement, InputElement>(scalar_f, array) */                                                     \
-    template<typename InputElement, Rank rank>                                                               \
-    auto name(                                                                                               \
-        hpx::shared_future<InputElement> const& scalar, PartitionedArray<InputElement, rank> const& array)   \
-    {                                                                                                        \
-        using OutputElement = OutputElementT<Functor<InputElement>>;                                         \
-        using Policies_ = Policies<OutputElement, InputElement>;                                             \
-                                                                                                             \
-        return name<Policies_, OutputElement, InputElement, rank>(Policies_{}, scalar, array);               \
-    }                                                                                                        \
-                                                                                                             \
-                                                                                                             \
-    /* f<InputElement, InputElement>(scalar, array) */                                                       \
-    template<typename InputElement, Rank rank>                                                               \
-    auto name(InputElement const scalar, PartitionedArray<InputElement, rank> const& array)                  \
-    {                                                                                                        \
-        using OutputElement = OutputElementT<Functor<InputElement>>;                                         \
-                                                                                                             \
-        return name<OutputElement, InputElement, rank>(                                                      \
-            hpx::make_ready_future<InputElement>(scalar).share(), array);                                    \
-    }
-
-
-// All overloads *with* a Policies template parameter
-#define LUE_BINARY_LOCAL_OPERATION_OVERLOADS3(name, Functor)                                                 \
-                                                                                                             \
-    /* f(policies, array, array) */                                                                          \
-    template<typename Policies, typename InputElement, Rank rank>                                            \
-    auto name(                                                                                               \
-        Policies const& policies,                                                                            \
-        PartitionedArray<InputElement, rank> const& array1,                                                  \
-        PartitionedArray<InputElement, rank> const& array2)                                                  \
-    {                                                                                                        \
-        using OutputElement = OutputElementT<Functor<InputElement>>;                                         \
-                                                                                                             \
-        return binary_local_operation(policies, array1, array2, Functor<InputElement, OutputElement>{});     \
-    }                                                                                                        \
-                                                                                                             \
-                                                                                                             \
-    /* f(policies, array, scalar) */                                                                         \
-    template<typename Policies, typename OutputElement, typename InputElement, Rank rank>                    \
-    PartitionedArray<OutputElement, rank> name(                                                              \
-        Policies const& policies,                                                                            \
-        PartitionedArray<InputElement, rank> const& array,                                                   \
-        hpx::shared_future<InputElement> const& scalar)                                                      \
-    {                                                                                                        \
-        return binary_local_operation(policies, array, scalar, Functor<InputElement, OutputElement>{});      \
-    }                                                                                                        \
-                                                                                                             \
-                                                                                                             \
-    /* f(policies, array, scalar) */                                                                         \
-    template<typename Policies, typename InputElement, Rank rank>                                            \
-    auto name(                                                                                               \
-        Policies const& policies,                                                                            \
-        PartitionedArray<InputElement, rank> const& array,                                                   \
-        hpx::shared_future<InputElement> const& scalar)                                                      \
-    {                                                                                                        \
-        using OutputElement = OutputElementT<Functor<InputElement>>;                                         \
-                                                                                                             \
-        return name<Policies, OutputElement, InputElement, rank>(policies, array, scalar);                   \
-    }                                                                                                        \
-                                                                                                             \
-                                                                                                             \
-    /* f(policies, array, scalar) */                                                                         \
-    template<typename Policies, typename InputElement, Rank rank>                                            \
-    auto name(                                                                                               \
-        Policies const& policies,                                                                            \
-        PartitionedArray<InputElement, rank> const& array,                                                   \
-        InputElement const scalar)                                                                           \
-    {                                                                                                        \
-        return name(policies, array, hpx::make_ready_future<InputElement>(scalar).share());                  \
-    }                                                                                                        \
-                                                                                                             \
-                                                                                                             \
-    /* f<OutputElement, InputElement>(policies, scalar_f, array) */                                          \
-    template<typename Policies, typename OutputElement, typename InputElement, Rank rank>                    \
-    PartitionedArray<OutputElement, rank> name(                                                              \
-        Policies const& policies,                                                                            \
-        hpx::shared_future<InputElement> const& scalar,                                                      \
-        PartitionedArray<InputElement, rank> const& array)                                                   \
-    {                                                                                                        \
-        return binary_local_operation(policies, scalar, array, Functor<InputElement, OutputElement>{});      \
-    }                                                                                                        \
-                                                                                                             \
-                                                                                                             \
-    /* f<OutputElement, InputElement(policies, scalar, array) */                                             \
-    template<typename Policies, typename OutputElement, typename InputElement, Rank rank>                    \
-    PartitionedArray<OutputElement, rank> name(                                                              \
-        Policies const& policies,                                                                            \
-        InputElement const scalar,                                                                           \
-        PartitionedArray<InputElement, rank> const& array)                                                   \
-    {                                                                                                        \
-        return binary_local_operation(                                                                       \
-            policies,                                                                                        \
-            hpx::make_ready_future<InputElement>(scalar),                                                    \
-            array,                                                                                           \
-            Functor<InputElement, OutputElement>{});                                                         \
-    }                                                                                                        \
-                                                                                                             \
-                                                                                                             \
-    /* f<InputElement, InputElement>(policies, scalar_f, array) */                                           \
-    template<typename Policies, typename InputElement, Rank rank>                                            \
-    auto name(                                                                                               \
-        Policies const& policies,                                                                            \
-        hpx::shared_future<InputElement> const& scalar,                                                      \
-        PartitionedArray<InputElement, rank> const& array)                                                   \
-    {                                                                                                        \
-        using OutputElement = OutputElementT<Functor<InputElement>>;                                         \
-                                                                                                             \
-        return name<Policies, OutputElement, InputElement, rank>(policies, scalar, array);                   \
-    }                                                                                                        \
-                                                                                                             \
-                                                                                                             \
-    /* f<InputElement, InputElement>(policies, scalar, array) */                                             \
-    template<typename Policies, typename InputElement, Rank rank>                                            \
-    auto name(                                                                                               \
-        Policies const& policies,                                                                            \
-        InputElement const scalar,                                                                           \
-        PartitionedArray<InputElement, rank> const& array)                                                   \
-    {                                                                                                        \
-        using OutputElement = OutputElementT<Functor<InputElement>>;                                         \
-                                                                                                             \
-        return name<Policies, OutputElement, InputElement, rank>(                                            \
-            policies, hpx::make_ready_future<InputElement>(scalar), array);                                  \
-    }
-
-
 // All overloads *with* a Policies template parameter
-#define LUE_BINARY_LOCAL_OPERATION_OVERLOADS4(name, Functor)                                                 \
+#define LUE_BINARY_LOCAL_OPERATION_OVERLOADS_WITH_POLICIES(name, Functor)                                    \
                                                                                                              \
     /* f(policies, array, array) */                                                                          \
     template<typename Policies, typename InputElement, Rank rank>                                            \
@@ -483,7 +75,7 @@ namespace lue {
         ->PartitionedArray<OutputElement, rank>                                                              \
     {                                                                                                        \
         return binary_local_operation(                                                                       \
-            policies, array, scalar.value(), Functor<InputElement, OutputElement>{});                        \
+            policies, array, scalar.future(), Functor<InputElement, OutputElement>{});                       \
     }                                                                                                        \
                                                                                                              \
                                                                                                              \
@@ -563,7 +155,7 @@ namespace lue {
         ->PartitionedArray<OutputElement, rank>                                                              \
     {                                                                                                        \
         return binary_local_operation(                                                                       \
-            policies, scalar.value(), array, Functor<InputElement, OutputElement>{});                        \
+            policies, scalar.future(), array, Functor<InputElement, OutputElement>{});                       \
     }                                                                                                        \
                                                                                                              \
                                                                                                              \
@@ -641,7 +233,7 @@ namespace lue {
         ->Scalar<OutputElement>                                                                              \
     {                                                                                                        \
         return binary_local_operation(                                                                       \
-            policies, scalar1.value(), scalar2.value(), Functor<InputElement, OutputElement>{});             \
+            policies, scalar1.future(), scalar2.future(), Functor<InputElement, OutputElement>{});           \
     }                                                                                                        \
                                                                                                              \
                                                                                                              \
@@ -662,7 +254,7 @@ namespace lue {
         ->Scalar<OutputElement>                                                                              \
     {                                                                                                        \
         return name<Policies, OutputElement, InputElement>(                                                  \
-            policies, scalar.value(), Scalar<InputElement>{value});                                          \
+            policies, scalar.future(), Scalar<InputElement>{value});                                         \
     }                                                                                                        \
                                                                                                              \
                                                                                                              \
@@ -682,7 +274,7 @@ namespace lue {
         ->Scalar<OutputElement>                                                                              \
     {                                                                                                        \
         return name<Policies, OutputElement, InputElement>(                                                  \
-            policies, Scalar<InputElement>{value}, scalar.value());                                          \
+            policies, Scalar<InputElement>{value}, scalar.future());                                         \
     }                                                                                                        \
                                                                                                              \
                                                                                                              \
@@ -721,7 +313,7 @@ namespace lue {
 
 
 // All overloads *without* a Policies template parameter
-#define LUE_BINARY_LOCAL_OPERATION_OVERLOADS5(name, Functor, Policies)                                       \
+#define LUE_BINARY_LOCAL_OPERATION_OVERLOADS_WITHOUT_POLICIES(name, Functor, Policies)                       \
                                                                                                              \
     /* f(array, array) */                                                                                    \
     template<typename InputElement, Rank rank>                                                               \
@@ -891,7 +483,7 @@ namespace lue {
         using Policies_ = Policies<OutputElement, InputElement>;                                             \
                                                                                                              \
         return name<Policies_, OutputElement, InputElement>(                                                 \
-            Policies_{}, scalar.value(), Scalar<InputElement>{value});                                       \
+            Policies_{}, scalar.future(), Scalar<InputElement>{value});                                      \
     }                                                                                                        \
                                                                                                              \
                                                                                                              \
@@ -914,7 +506,7 @@ namespace lue {
         using Policies_ = Policies<OutputElement, InputElement>;                                             \
                                                                                                              \
         return name<Policies_, OutputElement, InputElement>(                                                 \
-            Policies_{}, Scalar<InputElement>{value}, scalar.value());                                       \
+            Policies_{}, Scalar<InputElement>{value}, scalar.future());                                      \
     }                                                                                                        \
                                                                                                              \
                                                                                                              \
diff --git a/source/framework/algorithm/include/lue/framework/algorithm/close_to.hpp b/source/framework/algorithm/include/lue/framework/algorithm/close_to.hpp
index 3a2af49fa..b0c7d1698 100644
--- a/source/framework/algorithm/include/lue/framework/algorithm/close_to.hpp
+++ b/source/framework/algorithm/include/lue/framework/algorithm/close_to.hpp
@@ -59,6 +59,6 @@ namespace lue {
     }  // namespace detail
 
 
-    LUE_BINARY_LOCAL_OPERATION_OVERLOADS3(close_to, detail::CloseTo)
+    LUE_BINARY_LOCAL_OPERATION_OVERLOADS_WITH_POLICIES(close_to, detail::CloseTo)
 
 }  // namespace lue
diff --git a/source/framework/algorithm/include/lue/framework/algorithm/create_partitioned_array.hpp b/source/framework/algorithm/include/lue/framework/algorithm/create_partitioned_array.hpp
index 90d180d92..2687328d0 100644
--- a/source/framework/algorithm/include/lue/framework/algorithm/create_partitioned_array.hpp
+++ b/source/framework/algorithm/include/lue/framework/algorithm/create_partitioned_array.hpp
@@ -1053,7 +1053,7 @@ namespace lue {
         using Functor = InstantiateFilled<Element, rank>;
 
         return create_partitioned_array(
-            Policies{}, array_shape, partition_shape, Functor{fill_value.value()});
+            Policies{}, array_shape, partition_shape, Functor{fill_value.future()});
     }
 
 
diff --git a/source/framework/algorithm/include/lue/framework/algorithm/default_policies/add.hpp b/source/framework/algorithm/include/lue/framework/algorithm/default_policies/add.hpp
index 895ac41dd..978f72bf8 100644
--- a/source/framework/algorithm/include/lue/framework/algorithm/default_policies/add.hpp
+++ b/source/framework/algorithm/include/lue/framework/algorithm/default_policies/add.hpp
@@ -1,5 +1,6 @@
 #pragma once
 #include "lue/framework/algorithm/add.hpp"
+#include "lue/framework/algorithm/operator.hpp"
 
 
 namespace lue {
@@ -16,8 +17,8 @@ namespace lue {
 
     namespace default_policies {
 
-        LUE_BINARY_LOCAL_OPERATION_OVERLOADS5(add, detail::Add, policy::add::DefaultPolicies)
-        LUE_BINARY_ARITHMETIC_OPERATOR2(+, add)
+        LUE_BINARY_LOCAL_OPERATION_OVERLOADS_WITHOUT_POLICIES(add, detail::Add, policy::add::DefaultPolicies)
+        LUE_BINARY_ARITHMETIC_OPERATOR(+, add)
 
     }  // namespace default_policies
 }  // namespace lue
diff --git a/source/framework/algorithm/include/lue/framework/algorithm/default_policies/all.hpp b/source/framework/algorithm/include/lue/framework/algorithm/default_policies/all.hpp
index 022ee15cf..75dffcc17 100644
--- a/source/framework/algorithm/include/lue/framework/algorithm/default_policies/all.hpp
+++ b/source/framework/algorithm/include/lue/framework/algorithm/default_policies/all.hpp
@@ -15,7 +15,7 @@ namespace lue {
     namespace default_policies {
 
         template<typename Element, Rank rank>
-        hpx::future<Element> all(PartitionedArray<Element, rank> const& array)
+        auto all(PartitionedArray<Element, rank> const& array) -> Scalar<Element>
         {
             using Policies = policy::all::DefaultPolicies<Element>;
 
@@ -24,8 +24,8 @@ namespace lue {
 
 
         template<typename Element, Rank rank>
-        hpx::future<Element> all(
-            hpx::id_type const locality_id, ArrayPartition<Element, rank> const& partition)
+        auto all(hpx::id_type const locality_id, ArrayPartition<Element, rank> const& partition)
+            -> Scalar<Element>
         {
             using Policies = policy::all::DefaultPolicies<Element>;
 
diff --git a/source/framework/algorithm/include/lue/framework/algorithm/default_policies/close_to.hpp b/source/framework/algorithm/include/lue/framework/algorithm/default_policies/close_to.hpp
index 676dd08e8..e4522f171 100644
--- a/source/framework/algorithm/include/lue/framework/algorithm/default_policies/close_to.hpp
+++ b/source/framework/algorithm/include/lue/framework/algorithm/default_policies/close_to.hpp
@@ -1,5 +1,6 @@
 #pragma once
 #include "lue/framework/algorithm/close_to.hpp"
+#include "lue/framework/algorithm/pow.hpp"
 
 
 namespace lue {
@@ -16,7 +17,8 @@ namespace lue {
 
     namespace default_policies {
 
-        LUE_BINARY_LOCAL_OPERATION_OVERLOADS2(close_to, detail::CloseTo, policy::close_to::DefaultPolicies)
+        LUE_BINARY_LOCAL_OPERATION_OVERLOADS_WITHOUT_POLICIES(
+            close_to, detail::CloseTo, policy::close_to::DefaultPolicies)
 
     }  // namespace default_policies
 
diff --git a/source/framework/algorithm/include/lue/framework/algorithm/default_policies/divide.hpp b/source/framework/algorithm/include/lue/framework/algorithm/default_policies/divide.hpp
index 5d4995bce..5388bdc3b 100644
--- a/source/framework/algorithm/include/lue/framework/algorithm/default_policies/divide.hpp
+++ b/source/framework/algorithm/include/lue/framework/algorithm/default_policies/divide.hpp
@@ -16,7 +16,8 @@ namespace lue {
 
     namespace default_policies {
 
-        LUE_BINARY_LOCAL_OPERATION_OVERLOADS2(divide, detail::Divide, policy::divide::DefaultPolicies)
+        LUE_BINARY_LOCAL_OPERATION_OVERLOADS_WITHOUT_POLICIES(
+            divide, detail::Divide, policy::divide::DefaultPolicies)
         LUE_BINARY_ARITHMETIC_OPERATOR(/, divide)
 
     }  // namespace default_policies
diff --git a/source/framework/algorithm/include/lue/framework/algorithm/default_policies/equal_to.hpp b/source/framework/algorithm/include/lue/framework/algorithm/default_policies/equal_to.hpp
index 8585dced3..ae07b8ea3 100644
--- a/source/framework/algorithm/include/lue/framework/algorithm/default_policies/equal_to.hpp
+++ b/source/framework/algorithm/include/lue/framework/algorithm/default_policies/equal_to.hpp
@@ -1,5 +1,6 @@
 #pragma once
 #include "lue/framework/algorithm/equal_to.hpp"
+#include "lue/framework/algorithm/operator.hpp"
 
 
 namespace lue {
@@ -42,7 +43,8 @@ namespace lue {
         }
 
 
-        LUE_BINARY_LOCAL_OPERATION_OVERLOADS2(equal_to, detail::EqualTo, policy::equal_to::DefaultPolicies)
+        LUE_BINARY_LOCAL_OPERATION_OVERLOADS_WITHOUT_POLICIES(
+            equal_to, detail::EqualTo, policy::equal_to::DefaultPolicies)
         LUE_BINARY_COMPARISON_OPERATOR(==, equal_to)
 
     }  // namespace default_policies
diff --git a/source/framework/algorithm/include/lue/framework/algorithm/default_policies/greater_than.hpp b/source/framework/algorithm/include/lue/framework/algorithm/default_policies/greater_than.hpp
index b3a0a3930..40adba019 100644
--- a/source/framework/algorithm/include/lue/framework/algorithm/default_policies/greater_than.hpp
+++ b/source/framework/algorithm/include/lue/framework/algorithm/default_policies/greater_than.hpp
@@ -16,7 +16,7 @@ namespace lue {
 
     namespace default_policies {
 
-        LUE_BINARY_LOCAL_OPERATION_OVERLOADS2(
+        LUE_BINARY_LOCAL_OPERATION_OVERLOADS_WITHOUT_POLICIES(
             greater_than, detail::GreaterThan, policy::greater_than::DefaultPolicies)
         LUE_BINARY_COMPARISON_OPERATOR(>, greater_than)
 
diff --git a/source/framework/algorithm/include/lue/framework/algorithm/default_policies/greater_than_equal_to.hpp b/source/framework/algorithm/include/lue/framework/algorithm/default_policies/greater_than_equal_to.hpp
index c319aedab..a6087c96e 100644
--- a/source/framework/algorithm/include/lue/framework/algorithm/default_policies/greater_than_equal_to.hpp
+++ b/source/framework/algorithm/include/lue/framework/algorithm/default_policies/greater_than_equal_to.hpp
@@ -16,7 +16,7 @@ namespace lue {
 
     namespace default_policies {
 
-        LUE_BINARY_LOCAL_OPERATION_OVERLOADS2(
+        LUE_BINARY_LOCAL_OPERATION_OVERLOADS_WITHOUT_POLICIES(
             greater_than_equal_to, detail::GreaterThanEqualTo, policy::greater_than_equal_to::DefaultPolicies)
         LUE_BINARY_COMPARISON_OPERATOR(>=, greater_than_equal_to)
 
diff --git a/source/framework/algorithm/include/lue/framework/algorithm/default_policies/less_than.hpp b/source/framework/algorithm/include/lue/framework/algorithm/default_policies/less_than.hpp
index a774d37ff..e55c8b315 100644
--- a/source/framework/algorithm/include/lue/framework/algorithm/default_policies/less_than.hpp
+++ b/source/framework/algorithm/include/lue/framework/algorithm/default_policies/less_than.hpp
@@ -16,7 +16,8 @@ namespace lue {
 
     namespace default_policies {
 
-        LUE_BINARY_LOCAL_OPERATION_OVERLOADS2(less_than, detail::LessThan, policy::less_than::DefaultPolicies)
+        LUE_BINARY_LOCAL_OPERATION_OVERLOADS_WITHOUT_POLICIES(
+            less_than, detail::LessThan, policy::less_than::DefaultPolicies)
         LUE_BINARY_COMPARISON_OPERATOR(<, less_than)
 
     }  // namespace default_policies
diff --git a/source/framework/algorithm/include/lue/framework/algorithm/default_policies/less_than_equal_to.hpp b/source/framework/algorithm/include/lue/framework/algorithm/default_policies/less_than_equal_to.hpp
index c933c7d68..57b93ba8f 100644
--- a/source/framework/algorithm/include/lue/framework/algorithm/default_policies/less_than_equal_to.hpp
+++ b/source/framework/algorithm/include/lue/framework/algorithm/default_policies/less_than_equal_to.hpp
@@ -16,7 +16,7 @@ namespace lue {
 
     namespace default_policies {
 
-        LUE_BINARY_LOCAL_OPERATION_OVERLOADS2(
+        LUE_BINARY_LOCAL_OPERATION_OVERLOADS_WITHOUT_POLICIES(
             less_than_equal_to, detail::LessThanEqualTo, policy::less_than_equal_to::DefaultPolicies)
         LUE_BINARY_COMPARISON_OPERATOR(<=, less_than_equal_to)
 
diff --git a/source/framework/algorithm/include/lue/framework/algorithm/default_policies/logical_and.hpp b/source/framework/algorithm/include/lue/framework/algorithm/default_policies/logical_and.hpp
index c16415697..47d915fde 100644
--- a/source/framework/algorithm/include/lue/framework/algorithm/default_policies/logical_and.hpp
+++ b/source/framework/algorithm/include/lue/framework/algorithm/default_policies/logical_and.hpp
@@ -17,7 +17,7 @@ namespace lue {
 
     namespace default_policies {
 
-        LUE_BINARY_LOCAL_OPERATION_OVERLOADS2(
+        LUE_BINARY_LOCAL_OPERATION_OVERLOADS_WITHOUT_POLICIES(
             logical_and, detail::LogicalAnd, policy::logical_and::DefaultPolicies)
         LUE_BINARY_LOGICAL_OPERATOR(&&, logical_and)
 
diff --git a/source/framework/algorithm/include/lue/framework/algorithm/default_policies/logical_exclusive_or.hpp b/source/framework/algorithm/include/lue/framework/algorithm/default_policies/logical_exclusive_or.hpp
index d2c8eebae..60e88a3aa 100644
--- a/source/framework/algorithm/include/lue/framework/algorithm/default_policies/logical_exclusive_or.hpp
+++ b/source/framework/algorithm/include/lue/framework/algorithm/default_policies/logical_exclusive_or.hpp
@@ -17,7 +17,7 @@ namespace lue {
 
     namespace default_policies {
 
-        LUE_BINARY_LOCAL_OPERATION_OVERLOADS2(
+        LUE_BINARY_LOCAL_OPERATION_OVERLOADS_WITHOUT_POLICIES(
             logical_exclusive_or, detail::LogicalExclusiveOr, policy::logical_exclusive_or::DefaultPolicies)
 
     }  // namespace default_policies
diff --git a/source/framework/algorithm/include/lue/framework/algorithm/default_policies/logical_inclusive_or.hpp b/source/framework/algorithm/include/lue/framework/algorithm/default_policies/logical_inclusive_or.hpp
index 035eb09e0..c08c6287d 100644
--- a/source/framework/algorithm/include/lue/framework/algorithm/default_policies/logical_inclusive_or.hpp
+++ b/source/framework/algorithm/include/lue/framework/algorithm/default_policies/logical_inclusive_or.hpp
@@ -17,7 +17,7 @@ namespace lue {
 
     namespace default_policies {
 
-        LUE_BINARY_LOCAL_OPERATION_OVERLOADS2(
+        LUE_BINARY_LOCAL_OPERATION_OVERLOADS_WITHOUT_POLICIES(
             logical_inclusive_or, detail::LogicalInclusiveOr, policy::logical_inclusive_or::DefaultPolicies)
         LUE_BINARY_LOGICAL_OPERATOR(||, logical_inclusive_or)
 
diff --git a/source/framework/algorithm/include/lue/framework/algorithm/default_policies/maximum.hpp b/source/framework/algorithm/include/lue/framework/algorithm/default_policies/maximum.hpp
index 9c9cfde27..507f9f9af 100644
--- a/source/framework/algorithm/include/lue/framework/algorithm/default_policies/maximum.hpp
+++ b/source/framework/algorithm/include/lue/framework/algorithm/default_policies/maximum.hpp
@@ -15,7 +15,7 @@ namespace lue {
     namespace default_policies {
 
         template<typename Element, Rank rank>
-        auto maximum(PartitionedArray<Element, rank> const& array) -> hpx::future<Element>
+        auto maximum(PartitionedArray<Element, rank> const& array) -> Scalar<Element>
         {
             using Policies = policy::maximum::DefaultPolicies<Element>;
 
diff --git a/source/framework/algorithm/include/lue/framework/algorithm/default_policies/minimum.hpp b/source/framework/algorithm/include/lue/framework/algorithm/default_policies/minimum.hpp
index 7ae2d549e..e2ad52097 100644
--- a/source/framework/algorithm/include/lue/framework/algorithm/default_policies/minimum.hpp
+++ b/source/framework/algorithm/include/lue/framework/algorithm/default_policies/minimum.hpp
@@ -15,7 +15,7 @@ namespace lue {
     namespace default_policies {
 
         template<typename Element, Rank rank>
-        auto minimum(PartitionedArray<Element, rank> const& array) -> hpx::future<Element>
+        auto minimum(PartitionedArray<Element, rank> const& array) -> Scalar<Element>
         {
             using Policies = policy::minimum::DefaultPolicies<Element>;
 
diff --git a/source/framework/algorithm/include/lue/framework/algorithm/default_policies/multiply.hpp b/source/framework/algorithm/include/lue/framework/algorithm/default_policies/multiply.hpp
index c55fa0381..2fd114a90 100644
--- a/source/framework/algorithm/include/lue/framework/algorithm/default_policies/multiply.hpp
+++ b/source/framework/algorithm/include/lue/framework/algorithm/default_policies/multiply.hpp
@@ -16,7 +16,8 @@ namespace lue {
 
     namespace default_policies {
 
-        LUE_BINARY_LOCAL_OPERATION_OVERLOADS2(multiply, detail::Multiply, policy::multiply::DefaultPolicies)
+        LUE_BINARY_LOCAL_OPERATION_OVERLOADS_WITHOUT_POLICIES(
+            multiply, detail::Multiply, policy::multiply::DefaultPolicies)
         LUE_BINARY_ARITHMETIC_OPERATOR(*, multiply)
 
     }  // namespace default_policies
diff --git a/source/framework/algorithm/include/lue/framework/algorithm/default_policies/none.hpp b/source/framework/algorithm/include/lue/framework/algorithm/default_policies/none.hpp
index 184150386..a2ec56133 100644
--- a/source/framework/algorithm/include/lue/framework/algorithm/default_policies/none.hpp
+++ b/source/framework/algorithm/include/lue/framework/algorithm/default_policies/none.hpp
@@ -15,7 +15,7 @@ namespace lue {
     namespace default_policies {
 
         template<typename Element, Rank rank>
-        hpx::future<Element> none(PartitionedArray<Element, rank> const& array)
+        auto none(PartitionedArray<Element, rank> const& array) -> Scalar<Element>
         {
             using Functor = detail::None<Element>;
             using Policies = policy::none::DefaultPolicies<Element>;
diff --git a/source/framework/algorithm/include/lue/framework/algorithm/default_policies/not_equal_to.hpp b/source/framework/algorithm/include/lue/framework/algorithm/default_policies/not_equal_to.hpp
index 45d810d21..9ab5dffe7 100644
--- a/source/framework/algorithm/include/lue/framework/algorithm/default_policies/not_equal_to.hpp
+++ b/source/framework/algorithm/include/lue/framework/algorithm/default_policies/not_equal_to.hpp
@@ -16,7 +16,7 @@ namespace lue {
 
     namespace default_policies {
 
-        LUE_BINARY_LOCAL_OPERATION_OVERLOADS2(
+        LUE_BINARY_LOCAL_OPERATION_OVERLOADS_WITHOUT_POLICIES(
             not_equal_to, detail::NotEqualTo, policy::not_equal_to::DefaultPolicies)
         LUE_BINARY_COMPARISON_OPERATOR(!=, not_equal_to)
 
diff --git a/source/framework/algorithm/include/lue/framework/algorithm/default_policies/subtract.hpp b/source/framework/algorithm/include/lue/framework/algorithm/default_policies/subtract.hpp
index 20e5ce5bb..76975bfe5 100644
--- a/source/framework/algorithm/include/lue/framework/algorithm/default_policies/subtract.hpp
+++ b/source/framework/algorithm/include/lue/framework/algorithm/default_policies/subtract.hpp
@@ -16,7 +16,8 @@ namespace lue {
 
     namespace default_policies {
 
-        LUE_BINARY_LOCAL_OPERATION_OVERLOADS2(subtract, detail::Subtract, policy::subtract::DefaultPolicies)
+        LUE_BINARY_LOCAL_OPERATION_OVERLOADS_WITHOUT_POLICIES(
+            subtract, detail::Subtract, policy::subtract::DefaultPolicies)
         LUE_BINARY_ARITHMETIC_OPERATOR(-, subtract)
 
     }  // namespace default_policies
diff --git a/source/framework/algorithm/include/lue/framework/algorithm/default_policies/sum.hpp b/source/framework/algorithm/include/lue/framework/algorithm/default_policies/sum.hpp
index 27bd069cf..3ec433a6c 100644
--- a/source/framework/algorithm/include/lue/framework/algorithm/default_policies/sum.hpp
+++ b/source/framework/algorithm/include/lue/framework/algorithm/default_policies/sum.hpp
@@ -15,7 +15,7 @@ namespace lue {
     namespace default_policies {
 
         template<typename Element, Rank rank>
-        auto sum(PartitionedArray<Element, rank> const& array) -> hpx::future<Element>
+        auto sum(PartitionedArray<Element, rank> const& array) -> Scalar<Element>
         {
             using Policies = policy::sum::DefaultPolicies<Element>;
 
diff --git a/source/framework/algorithm/include/lue/framework/algorithm/default_policies/unique.hpp b/source/framework/algorithm/include/lue/framework/algorithm/default_policies/unique.hpp
index 5b6d6c226..f0f21696d 100644
--- a/source/framework/algorithm/include/lue/framework/algorithm/default_policies/unique.hpp
+++ b/source/framework/algorithm/include/lue/framework/algorithm/default_policies/unique.hpp
@@ -15,7 +15,7 @@ namespace lue {
     namespace default_policies {
 
         template<typename Element, Rank rank>
-        hpx::future<std::set<Element>> unique(PartitionedArray<Element, rank> const& array)
+        auto unique(PartitionedArray<Element, rank> const& array) -> hpx::future<std::set<Element>>
         {
             using Policies = policy::unique::DefaultPolicies<Element>;
 
diff --git a/source/framework/algorithm/include/lue/framework/algorithm/default_policies/where.hpp b/source/framework/algorithm/include/lue/framework/algorithm/default_policies/where.hpp
index bd3902c53..c1e7424f3 100644
--- a/source/framework/algorithm/include/lue/framework/algorithm/default_policies/where.hpp
+++ b/source/framework/algorithm/include/lue/framework/algorithm/default_policies/where.hpp
@@ -16,152 +16,180 @@ namespace lue {
 
     namespace default_policies {
 
+        // where(array, array, array)
         template<typename ConditionElement, typename Element, Rank rank>
-        PartitionedArray<Element, rank> where(
+        auto where(
             PartitionedArray<ConditionElement, rank> const& condition,
             PartitionedArray<Element, rank> const& true_array,
-            PartitionedArray<Element, rank> const& false_array)
+            PartitionedArray<Element, rank> const& false_array) -> PartitionedArray<Element, rank>
         {
-            // where(condition_array, true_array, false_array)
             using Policies = policy::where::DefaultPolicies<Element, ConditionElement, Element, Element>;
 
             return where(Policies{}, condition, true_array, false_array);
         }
 
 
+        // where(array, array, value_f)
         template<typename ConditionElement, typename Element, Rank rank>
-        PartitionedArray<Element, rank> where(
+        auto where(
             PartitionedArray<ConditionElement, rank> const& condition,
             PartitionedArray<Element, rank> const& true_array,
-            hpx::shared_future<Element> const false_value)
+            hpx::shared_future<Element> const& false_value_f) -> PartitionedArray<Element, rank>
         {
-            // where(condition_array, true_array, false_value_f)
             using Policies = policy::where::DefaultPolicies<Element, ConditionElement, Element, Element>;
 
-            return where(Policies{}, condition, true_array, false_value);
+            return where(Policies{}, condition, true_array, false_value_f);
         }
 
 
+        // where(array, value_f, array)
         template<typename ConditionElement, typename Element, Rank rank>
-        PartitionedArray<Element, rank> where(
+        auto where(
             PartitionedArray<ConditionElement, rank> const& condition,
-            hpx::shared_future<Element> const true_value,
-            PartitionedArray<Element, rank> const& false_array)
+            hpx::shared_future<Element> const& true_value_f,
+            PartitionedArray<Element, rank> const& false_array) -> PartitionedArray<Element, rank>
         {
-            // where(condition_array, true_value_f, false_array)
             using Policies = policy::where::DefaultPolicies<Element, ConditionElement, Element, Element>;
 
-            return where(Policies{}, condition, true_value, false_array);
+            return where(Policies{}, condition, true_value_f, false_array);
         }
 
 
+        // where(array, value_f, value_f)
         template<typename ConditionElement, typename Element, Rank rank>
-        PartitionedArray<Element, rank> where(
+        auto where(
             PartitionedArray<ConditionElement, rank> const& condition,
-            hpx::shared_future<Element> const true_value,
-            hpx::shared_future<Element> const false_value)
+            hpx::shared_future<Element> const& true_value_f,
+            hpx::shared_future<Element> const& false_value_f) -> PartitionedArray<Element, rank>
         {
-            // where(condition_array, true_value_f, false_value_f)
             using Policies = policy::where::DefaultPolicies<Element, ConditionElement, Element, Element>;
 
-            return where(Policies{}, condition, true_value, false_value);
+            return where(Policies{}, condition, true_value_f, false_value_f);
         }
 
 
+        // where(array, array, scalar)
         template<typename ConditionElement, typename Element, Rank rank>
-        PartitionedArray<Element, rank> where(
+        auto where(
             PartitionedArray<ConditionElement, rank> const& condition,
             PartitionedArray<Element, rank> const& true_array,
-            Element const false_value)
+            Scalar<Element> const& false_scalar) -> PartitionedArray<Element, rank>
         {
-            // where(condition_array, true_array, false_value)
-            return where(condition, true_array, hpx::make_ready_future<Element>(false_value).share());
+            using Policies = policy::where::DefaultPolicies<Element, ConditionElement, Element, Element>;
+
+            return where(Policies{}, condition, true_array, false_scalar);
         }
 
 
-        template<typename Policies, typename ConditionElement, typename Element, Rank rank>
-        PartitionedArray<Element, rank> where(
-            Policies const& policies,
+        // where(array, scalar, array)
+        template<typename ConditionElement, typename Element, Rank rank>
+        auto where(
             PartitionedArray<ConditionElement, rank> const& condition,
-            Element const true_value,
-            PartitionedArray<Element, rank> const& false_array)
+            Scalar<Element> const& true_scalar,
+            PartitionedArray<Element, rank> const& false_array) -> PartitionedArray<Element, rank>
         {
-            // where(policies, condition_array, true_value, false_array)
-            return where(
-                policies, condition, hpx::make_ready_future<Element>(true_value).share(), false_array);
+            using Policies = policy::where::DefaultPolicies<Element, ConditionElement, Element, Element>;
+
+            return where(Policies{}, condition, true_scalar, false_array);
         }
 
 
+        // where(array, scalar, scalar)
         template<typename ConditionElement, typename Element, Rank rank>
-        PartitionedArray<Element, rank> where(
+        auto where(
             PartitionedArray<ConditionElement, rank> const& condition,
-            Element const true_value,
-            PartitionedArray<Element, rank> const& false_array)
+            Scalar<Element> const& true_scalar,
+            Scalar<Element> const& false_scalar) -> PartitionedArray<Element, rank>
         {
-            // where(condition_array, true_value, false_array)
-            return where(condition, hpx::make_ready_future<Element>(true_value).share(), false_array);
+            using Policies = policy::where::DefaultPolicies<Element, ConditionElement, Element, Element>;
+
+            return where(Policies{}, condition, true_scalar, false_scalar);
         }
 
 
-        template<typename Policies, typename ConditionElement, typename Element, Rank rank>
-        PartitionedArray<Element, rank> where(
-            Policies const& policies,
+        // where(array, array, value)
+        template<typename ConditionElement, typename Element, Rank rank>
+        auto where(
+            PartitionedArray<ConditionElement, rank> const& condition,
+            PartitionedArray<Element, rank> const& true_array,
+            Element const false_value_f) -> PartitionedArray<Element, rank>
+        {
+            using Policies = policy::where::DefaultPolicies<Element, ConditionElement, Element, Element>;
+
+            return where(Policies{}, condition, true_array, false_value_f);
+        }
+
+
+        // where(array, value, array)
+        template<typename ConditionElement, typename Element, Rank rank>
+        auto where(
             PartitionedArray<ConditionElement, rank> const& condition,
             Element const true_value,
-            Element const false_value)
+            PartitionedArray<Element, rank> const& false_array) -> PartitionedArray<Element, rank>
         {
-            // where(policies, condition_array, true_value, false_value)
-            return where(
-                policies,
-                condition,
-                hpx::make_ready_future<Element>(true_value).share(),
-                hpx::make_ready_future<Element>(false_value).share());
+            using Policies = policy::where::DefaultPolicies<Element, ConditionElement, Element, Element>;
+
+            return where(Policies{}, condition, true_value, false_array);
         }
 
 
+        // where(array, value, value)
         template<typename ConditionElement, typename Element, Rank rank>
-        PartitionedArray<Element, rank> where(
+        auto where(
             PartitionedArray<ConditionElement, rank> const& condition,
             Element const true_value,
-            Element const false_value)
+            Element const false_value) -> PartitionedArray<Element, rank>
         {
-            // where(condition_array, true_value, false_value)
-            return where(
-                condition,
-                hpx::make_ready_future<Element>(true_value).share(),
-                hpx::make_ready_future<Element>(false_value).share());
+            using Policies = policy::where::DefaultPolicies<Element, ConditionElement, Element, Element>;
+
+            return where(Policies{}, condition, true_value, false_value);
         }
 
 
+        // ---------------------------------------------------------------------
+
+
+        // where(array, array)
         template<typename ConditionElement, typename Element, Rank rank>
-        PartitionedArray<Element, rank> where(
+        auto where(
             PartitionedArray<ConditionElement, rank> const& condition,
-            PartitionedArray<Element, rank> const& true_array)
+            PartitionedArray<Element, rank> const& true_array) -> PartitionedArray<Element, rank>
         {
-            // where(condition_array, true_array)
             using Policies = policy::where::DefaultPolicies<Element, ConditionElement, Element>;
 
             return where(Policies{}, condition, true_array);
         }
 
 
+        // where(array, value_f)
         template<typename ConditionElement, typename Element, Rank rank>
-        PartitionedArray<Element, rank> where(
+        auto where(
             PartitionedArray<ConditionElement, rank> const& condition,
-            hpx::shared_future<Element> const true_value)
+            hpx::shared_future<Element> const& true_value_f) -> PartitionedArray<Element, rank>
         {
-            // where(condition_array, true_value_f)
             using Policies = policy::where::DefaultPolicies<Element, ConditionElement, Element>;
 
-            return where(Policies{}, condition, true_value);
+            return where(Policies{}, condition, true_value_f);
+        }
+
+
+        // where(array, scalar)
+        template<typename ConditionElement, typename Element, Rank rank>
+        auto where(
+            PartitionedArray<ConditionElement, rank> const& condition, Scalar<Element> const& true_scalar)
+            -> PartitionedArray<Element, rank>
+        {
+            using Policies = policy::where::DefaultPolicies<Element, ConditionElement, Element>;
+
+            return where(Policies{}, condition, true_scalar);
         }
 
 
+        // where(array, value)
         template<typename ConditionElement, typename Element, Rank rank>
-        PartitionedArray<Element, rank> where(
-            PartitionedArray<ConditionElement, rank> const& condition, Element const true_value)
+        auto where(PartitionedArray<ConditionElement, rank> const& condition, Element const true_value)
+            -> PartitionedArray<Element, rank>
         {
-            // where(condition_array, true_value)
             using Policies = policy::where::DefaultPolicies<Element, ConditionElement, Element>;
 
             return where(Policies{}, condition, true_value);
diff --git a/source/framework/algorithm/include/lue/framework/algorithm/definition/binary_local_operation.hpp b/source/framework/algorithm/include/lue/framework/algorithm/definition/binary_local_operation.hpp
index 83db501db..a688ead2e 100644
--- a/source/framework/algorithm/include/lue/framework/algorithm/definition/binary_local_operation.hpp
+++ b/source/framework/algorithm/include/lue/framework/algorithm/definition/binary_local_operation.hpp
@@ -686,42 +686,6 @@ namespace lue {
         ArgumentType<void(Functor)> const&);
 
 #define LUE_INSTANTIATE_BINARY_LOCAL_OPERATION(                                                              \
-    Policies, OutputElement, InputElement1, InputElement2, rank, Functor)                                    \
-                                                                                                             \
-    template LUE_LOCAL_OPERATION_EXPORT PartitionedArray<OutputElement, rank> binary_local_operation<        \
-        ArgumentType<void(Policies)>,                                                                        \
-        InputElement1,                                                                                       \
-        InputElement2,                                                                                       \
-        rank,                                                                                                \
-        ArgumentType<void(Functor)>>(                                                                        \
-        ArgumentType<void(Policies)> const&,                                                                 \
-        hpx::shared_future<InputElement1> const&,                                                            \
-        PartitionedArray<InputElement2, rank> const&,                                                        \
-        ArgumentType<void(Functor)> const&);                                                                 \
-                                                                                                             \
-    template LUE_LOCAL_OPERATION_EXPORT PartitionedArray<OutputElement, rank> binary_local_operation<        \
-        ArgumentType<void(Policies)>,                                                                        \
-        InputElement1,                                                                                       \
-        InputElement2,                                                                                       \
-        rank,                                                                                                \
-        ArgumentType<void(Functor)>>(                                                                        \
-        ArgumentType<void(Policies)> const&,                                                                 \
-        PartitionedArray<InputElement1, rank> const&,                                                        \
-        hpx::shared_future<InputElement2> const&,                                                            \
-        ArgumentType<void(Functor)> const&);                                                                 \
-                                                                                                             \
-    template LUE_LOCAL_OPERATION_EXPORT PartitionedArray<OutputElement, rank> binary_local_operation<        \
-        ArgumentType<void(Policies)>,                                                                        \
-        InputElement1,                                                                                       \
-        InputElement2,                                                                                       \
-        rank,                                                                                                \
-        ArgumentType<void(Functor)>>(                                                                        \
-        ArgumentType<void(Policies)> const&,                                                                 \
-        PartitionedArray<InputElement1, rank> const&,                                                        \
-        PartitionedArray<InputElement2, rank> const&,                                                        \
-        ArgumentType<void(Functor)> const&);
-
-#define LUE_INSTANTIATE_BINARY_LOCAL_OPERATION2(                                                             \
     Policies, OutputElement, InputElement1, InputElement2, rank, Functor)                                    \
                                                                                                              \
     template LUE_LOCAL_OPERATION_EXPORT PartitionedArray<OutputElement, rank> binary_local_operation<        \
diff --git a/source/framework/algorithm/include/lue/framework/algorithm/definition/maximum.hpp b/source/framework/algorithm/include/lue/framework/algorithm/definition/maximum.hpp
index f22320597..d165cd344 100644
--- a/source/framework/algorithm/include/lue/framework/algorithm/definition/maximum.hpp
+++ b/source/framework/algorithm/include/lue/framework/algorithm/definition/maximum.hpp
@@ -55,7 +55,7 @@ namespace lue {
     template<typename Policies, Rank rank>
     auto maximum(
         Policies const& policies, PartitionedArray<policy::InputElementT<Policies, 0>, rank> const& array)
-        -> hpx::future<policy::OutputElementT<Policies, 0>>
+        -> Scalar<policy::OutputElementT<Policies, 0>>
     {
         using Functor =
             detail::Maximum<policy::InputElementT<Policies, 0>, policy::OutputElementT<Policies, 0>>;
@@ -71,4 +71,4 @@ namespace lue {
     template LUE_GLOBAL_OPERATION_EXPORT auto maximum<ArgumentType<void(Policies)>, rank>(                   \
         ArgumentType<void(Policies)> const&,                                                                 \
         PartitionedArray<policy::InputElementT<Policies, 0>, rank> const&)                                   \
-        ->hpx::future<policy::OutputElementT<Policies, 0>>;
+        ->Scalar<policy::OutputElementT<Policies, 0>>;
diff --git a/source/framework/algorithm/include/lue/framework/algorithm/definition/minimum.hpp b/source/framework/algorithm/include/lue/framework/algorithm/definition/minimum.hpp
index 7927dda76..cfe81681b 100644
--- a/source/framework/algorithm/include/lue/framework/algorithm/definition/minimum.hpp
+++ b/source/framework/algorithm/include/lue/framework/algorithm/definition/minimum.hpp
@@ -51,7 +51,7 @@ namespace lue {
     template<typename Policies, Rank rank>
     auto minimum(
         Policies const& policies, PartitionedArray<policy::InputElementT<Policies, 0>, rank> const& array)
-        -> hpx::future<policy::OutputElementT<Policies, 0>>
+        -> Scalar<policy::OutputElementT<Policies, 0>>
     {
         using Functor =
             detail::Minimum<policy::InputElementT<Policies, 0>, policy::OutputElementT<Policies, 0>>;
@@ -67,4 +67,4 @@ namespace lue {
     template LUE_GLOBAL_OPERATION_EXPORT auto minimum<ArgumentType<void(Policies)>, rank>(                   \
         ArgumentType<void(Policies)> const&,                                                                 \
         PartitionedArray<policy::InputElementT<Policies, 0>, rank> const&)                                   \
-        ->hpx::future<policy::OutputElementT<Policies, 0>>;
+        ->Scalar<policy::OutputElementT<Policies, 0>>;
diff --git a/source/framework/algorithm/include/lue/framework/algorithm/definition/sum.hpp b/source/framework/algorithm/include/lue/framework/algorithm/definition/sum.hpp
index e1afaab3d..8969bf481 100644
--- a/source/framework/algorithm/include/lue/framework/algorithm/definition/sum.hpp
+++ b/source/framework/algorithm/include/lue/framework/algorithm/definition/sum.hpp
@@ -51,7 +51,7 @@ namespace lue {
     template<typename Policies, Rank rank>
     auto sum(
         Policies const& policies, PartitionedArray<policy::InputElementT<Policies, 0>, rank> const& array)
-        -> hpx::future<policy::OutputElementT<Policies, 0>>
+        -> Scalar<policy::OutputElementT<Policies, 0>>
     {
         using Functor = detail::Sum<policy::InputElementT<Policies, 0>, policy::OutputElementT<Policies, 0>>;
 
@@ -66,4 +66,4 @@ namespace lue {
     template LUE_GLOBAL_OPERATION_EXPORT auto sum<ArgumentType<void(Policies)>, rank>(                       \
         ArgumentType<void(Policies)> const&,                                                                 \
         PartitionedArray<policy::InputElementT<Policies, 0>, rank> const&)                                   \
-        ->hpx::future<policy::OutputElementT<Policies, 0>>;
+        ->Scalar<policy::OutputElementT<Policies, 0>>;
diff --git a/source/framework/algorithm/include/lue/framework/algorithm/definition/unary_local_operation.hpp b/source/framework/algorithm/include/lue/framework/algorithm/definition/unary_local_operation.hpp
index f8fbfae99..7ac25f76b 100644
--- a/source/framework/algorithm/include/lue/framework/algorithm/definition/unary_local_operation.hpp
+++ b/source/framework/algorithm/include/lue/framework/algorithm/definition/unary_local_operation.hpp
@@ -162,7 +162,7 @@ namespace lue {
 
                     return output_value;
                 }),
-            input_scalar.value());
+            input_scalar.future());
     }
 
 }  // namespace lue
diff --git a/source/framework/algorithm/include/lue/framework/algorithm/definition/where.hpp b/source/framework/algorithm/include/lue/framework/algorithm/definition/where.hpp
index 3bc5ccdec..8769a780c 100644
--- a/source/framework/algorithm/include/lue/framework/algorithm/definition/where.hpp
+++ b/source/framework/algorithm/include/lue/framework/algorithm/definition/where.hpp
@@ -7,513 +7,505 @@
 
 
 namespace lue {
-    namespace detail {
-        namespace where {
-
-            template<typename ConditionElement, typename InputElement>
-            class Where
-            {
-
-                public:
-
-                    using OutputElement = InputElement;
-
-                    constexpr OutputElement operator()(
-                        [[maybe_unused]] ConditionElement const condition,
-                        InputElement const true_value) const noexcept
-                    {
-                        // False conditions are assumed to be out of domain. They must
-                        // have been already handled by the caller.
-                        lue_hpx_assert(condition);
-
-                        return true_value;
-                    }
-            };
-
-
-            template<
-                typename Policies,
-                typename ConditionPartition,
-                typename TruePartition,
-                typename FalsePartition>
-            class OverloadPicker
-            {
-            };
-
-
-            template<typename Policies, typename ConditionElement, typename Element, Rank rank>
-            class OverloadPicker<
-                Policies,
-                ArrayPartition<ConditionElement, rank>,
-                ArrayPartition<Element, rank>,
-                ArrayPartition<Element, rank>>
-            {
-
-                public:
-
-                    using ConditionPartition = ArrayPartition<ConditionElement, rank>;
-                    using Partition = ArrayPartition<Element, rank>;
-
-                    static Partition where_partition(
-                        Policies const& policies,
-                        ConditionPartition const& condition_partition,
-                        Partition const& true_partition,
-                        Partition const& false_partition)
-                    {
-                        using Offset = OffsetT<ConditionPartition>;
-                        using ConditionData = DataT<ConditionPartition>;
-                        using Data = DataT<Partition>;
-
-                        lue_hpx_assert(condition_partition.is_ready());
-                        lue_hpx_assert(true_partition.is_ready());
-                        lue_hpx_assert(false_partition.is_ready());
-
-                        return hpx::dataflow(
-                            hpx::launch::async,
-                            hpx::unwrapping(
-
-                                [policies, condition_partition, true_partition, false_partition](
-                                    Offset const& offset,
-                                    ConditionData const& condition_data,
-                                    Data const& true_data,
-                                    Data const& false_data)
+    namespace detail::where {
+
+        template<typename ConditionElement, typename InputElement>
+        class Where
+        {
+
+            public:
+
+                using OutputElement = InputElement;
+
+                constexpr auto operator()(
+                    [[maybe_unused]] ConditionElement const condition,
+                    InputElement const true_value) const noexcept -> OutputElement
+                {
+                    // False conditions are assumed to be out of domain. They must
+                    // have been already handled by the caller.
+                    lue_hpx_assert(condition);
+
+                    return true_value;
+                }
+        };
+
+
+        template<
+            typename Policies,
+            typename ConditionPartition,
+            typename TruePartition,
+            typename FalsePartition>
+        class OverloadPicker
+        {
+        };
+
+
+        template<typename Policies, typename ConditionElement, typename Element, Rank rank>
+        class OverloadPicker<
+            Policies,
+            ArrayPartition<ConditionElement, rank>,
+            ArrayPartition<Element, rank>,
+            ArrayPartition<Element, rank>>
+        {
+
+            public:
+
+                using ConditionPartition = ArrayPartition<ConditionElement, rank>;
+                using Partition = ArrayPartition<Element, rank>;
+
+                static auto where_partition(
+                    Policies const& policies,
+                    ConditionPartition const& condition_partition,
+                    Partition const& true_partition,
+                    Partition const& false_partition) -> Partition
+                {
+                    using Offset = OffsetT<ConditionPartition>;
+                    using ConditionData = DataT<ConditionPartition>;
+                    using Data = DataT<Partition>;
+
+                    lue_hpx_assert(condition_partition.is_ready());
+                    lue_hpx_assert(true_partition.is_ready());
+                    lue_hpx_assert(false_partition.is_ready());
+
+                    return hpx::dataflow(
+                        hpx::launch::async,
+                        hpx::unwrapping(
+
+                            [policies, condition_partition, true_partition, false_partition](
+                                Offset const& offset,
+                                ConditionData const& condition_data,
+                                Data const& true_data,
+                                Data const& false_data)
+                            {
+                                AnnotateFunction annotation{"where"};
+
+                                HPX_UNUSED(condition_partition);
+                                HPX_UNUSED(true_partition);
+                                HPX_UNUSED(false_partition);
+
+                                Data output_partition_data{condition_data.shape()};
+
+                                auto const& dp = policies.domain_policy();
+                                auto const& indp1 =
+                                    std::get<0>(policies.inputs_policies()).input_no_data_policy();
+                                auto const& indp2 =
+                                    std::get<1>(policies.inputs_policies()).input_no_data_policy();
+                                auto const& indp3 =
+                                    std::get<2>(policies.inputs_policies()).input_no_data_policy();
+                                auto const& ondp =
+                                    std::get<0>(policies.outputs_policies()).output_no_data_policy();
+
+                                Count const nr_elements{lue::nr_elements(condition_data)};
+                                lue_hpx_assert(lue::nr_elements(true_data) == nr_elements);
+                                lue_hpx_assert(lue::nr_elements(false_data) == nr_elements);
+
+                                // No-data is generated at:
+                                // - No-data in condition expression
+                                // - True in condition expression && no-data in true expression
+                                // - False in condition expression && no-data in false expression
+
+                                for (Index i = 0; i < nr_elements; ++i)
                                 {
-                                    AnnotateFunction annotation{"where"};
-
-                                    HPX_UNUSED(condition_partition);
-                                    HPX_UNUSED(true_partition);
-                                    HPX_UNUSED(false_partition);
-
-                                    Data output_partition_data{condition_data.shape()};
-
-                                    auto const& dp = policies.domain_policy();
-                                    auto const& indp1 =
-                                        std::get<0>(policies.inputs_policies()).input_no_data_policy();
-                                    auto const& indp2 =
-                                        std::get<1>(policies.inputs_policies()).input_no_data_policy();
-                                    auto const& indp3 =
-                                        std::get<2>(policies.inputs_policies()).input_no_data_policy();
-                                    auto const& ondp =
-                                        std::get<0>(policies.outputs_policies()).output_no_data_policy();
-
-                                    Count const nr_elements{lue::nr_elements(condition_data)};
-                                    lue_hpx_assert(lue::nr_elements(true_data) == nr_elements);
-                                    lue_hpx_assert(lue::nr_elements(false_data) == nr_elements);
-
-                                    // No-data is generated at:
-                                    // - No-data in condition expression
-                                    // - True in condition expression && no-data in true expression
-                                    // - False in condition expression && no-data in false expression
-
-                                    for (Index i = 0; i < nr_elements; ++i)
+                                    if (indp1.is_no_data(condition_data, i))
                                     {
-                                        if (indp1.is_no_data(condition_data, i))
-                                        {
-                                            ondp.mark_no_data(output_partition_data, i);
-                                        }
-                                        else if (!dp.within_domain(
-                                                     condition_data[i], true_data[i], false_data[i]))
+                                        ondp.mark_no_data(output_partition_data, i);
+                                    }
+                                    else if (!dp.within_domain(
+                                                 condition_data[i], true_data[i], false_data[i]))
+                                    {
+                                        ondp.mark_no_data(output_partition_data, i);
+                                    }
+                                    else
+                                    {
+                                        if (condition_data[i])
                                         {
-                                            ondp.mark_no_data(output_partition_data, i);
+                                            if (indp2.is_no_data(true_data, i))
+                                            {
+                                                ondp.mark_no_data(output_partition_data, i);
+                                            }
+                                            else
+                                            {
+                                                output_partition_data[i] = true_data[i];
+                                            }
                                         }
                                         else
                                         {
-                                            if (condition_data[i])
+                                            if (indp3.is_no_data(false_data, i))
                                             {
-                                                if (indp2.is_no_data(true_data, i))
-                                                {
-                                                    ondp.mark_no_data(output_partition_data, i);
-                                                }
-                                                else
-                                                {
-                                                    output_partition_data[i] = true_data[i];
-                                                }
+                                                ondp.mark_no_data(output_partition_data, i);
                                             }
                                             else
                                             {
-                                                if (indp3.is_no_data(false_data, i))
-                                                {
-                                                    ondp.mark_no_data(output_partition_data, i);
-                                                }
-                                                else
-                                                {
-                                                    output_partition_data[i] = false_data[i];
-                                                }
+                                                output_partition_data[i] = false_data[i];
                                             }
                                         }
                                     }
-
-                                    return Partition{
-                                        hpx::find_here(), offset, std::move(output_partition_data)};
                                 }
 
-                                ),
-                            condition_partition.offset(),
-                            condition_partition.data(),
-                            true_partition.data(),
-                            false_partition.data());
-                    }
-
-                    struct Action:
-                        hpx::actions::make_action<decltype(&where_partition), &where_partition, Action>::type
-                    {
-                    };
-            };
-
-
-            template<typename Policies, typename ConditionElement, typename Element, Rank rank>
-            class OverloadPicker<
-                Policies,
-                ArrayPartition<ConditionElement, rank>,
-                ArrayPartition<Element, rank>,
-                Element>
-            {
-
-                public:
-
-                    using ConditionPartition = ArrayPartition<ConditionElement, rank>;
-                    using Partition = ArrayPartition<Element, rank>;
-
-                    static Partition where_partition(
-                        Policies const& policies,
-                        ConditionPartition const& condition_partition,
-                        Partition const& true_partition,
-                        Element const false_scalar)
-                    {
-                        using Offset = OffsetT<ConditionPartition>;
-                        using ConditionData = DataT<ConditionPartition>;
-                        using Data = DataT<Partition>;
-
-                        lue_hpx_assert(condition_partition.is_ready());
-                        lue_hpx_assert(true_partition.is_ready());
-
-                        return hpx::dataflow(
-                            hpx::launch::async,
-                            hpx::unwrapping(
-
-                                [policies, condition_partition, true_partition, false_scalar](
-                                    Offset const& offset,
-                                    ConditionData const& condition_data,
-                                    Data const& true_data)
-                                {
-                                    AnnotateFunction annotation{"where_partition"};
+                                return Partition{hpx::find_here(), offset, std::move(output_partition_data)};
+                            }
+
+                            ),
+                        condition_partition.offset(),
+                        condition_partition.data(),
+                        true_partition.data(),
+                        false_partition.data());
+                }
 
-                                    HPX_UNUSED(condition_partition);
-                                    HPX_UNUSED(true_partition);
+                struct Action:
+                    hpx::actions::make_action<decltype(&where_partition), &where_partition, Action>::type
+                {
+                };
+        };
 
-                                    Data output_partition_data{condition_data.shape()};
 
-                                    auto const& dp = policies.domain_policy();
-                                    auto const& indp1 =
-                                        std::get<0>(policies.inputs_policies()).input_no_data_policy();
-                                    auto const& indp2 =
-                                        std::get<1>(policies.inputs_policies()).input_no_data_policy();
-                                    auto const& indp3 =
-                                        std::get<2>(policies.inputs_policies()).input_no_data_policy();
-                                    auto const& ondp =
-                                        std::get<0>(policies.outputs_policies()).output_no_data_policy();
+        template<typename Policies, typename ConditionElement, typename Element, Rank rank>
+        class OverloadPicker<
+            Policies,
+            ArrayPartition<ConditionElement, rank>,
+            ArrayPartition<Element, rank>,
+            Element>
+        {
 
-                                    Count const nr_elements{lue::nr_elements(condition_data)};
-                                    lue_hpx_assert(lue::nr_elements(true_data) == nr_elements);
+            public:
 
-                                    // No-data is generated at:
-                                    // - No-data in condition expression
-                                    // - True in condition expression && no-data in true expression
-                                    // - False in condition expression && no-data in false expression
+                using ConditionPartition = ArrayPartition<ConditionElement, rank>;
+                using Partition = ArrayPartition<Element, rank>;
 
-                                    for (Index i = 0; i < nr_elements; ++i)
+                static auto where_partition(
+                    Policies const& policies,
+                    ConditionPartition const& condition_partition,
+                    Partition const& true_partition,
+                    Element const false_scalar) -> Partition
+                {
+                    using Offset = OffsetT<ConditionPartition>;
+                    using ConditionData = DataT<ConditionPartition>;
+                    using Data = DataT<Partition>;
+
+                    lue_hpx_assert(condition_partition.is_ready());
+                    lue_hpx_assert(true_partition.is_ready());
+
+                    return hpx::dataflow(
+                        hpx::launch::async,
+                        hpx::unwrapping(
+
+                            [policies, condition_partition, true_partition, false_scalar](
+                                Offset const& offset,
+                                ConditionData const& condition_data,
+                                Data const& true_data)
+                            {
+                                AnnotateFunction annotation{"where_partition"};
+
+                                HPX_UNUSED(condition_partition);
+                                HPX_UNUSED(true_partition);
+
+                                Data output_partition_data{condition_data.shape()};
+
+                                auto const& dp = policies.domain_policy();
+                                auto const& indp1 =
+                                    std::get<0>(policies.inputs_policies()).input_no_data_policy();
+                                auto const& indp2 =
+                                    std::get<1>(policies.inputs_policies()).input_no_data_policy();
+                                auto const& indp3 =
+                                    std::get<2>(policies.inputs_policies()).input_no_data_policy();
+                                auto const& ondp =
+                                    std::get<0>(policies.outputs_policies()).output_no_data_policy();
+
+                                Count const nr_elements{lue::nr_elements(condition_data)};
+                                lue_hpx_assert(lue::nr_elements(true_data) == nr_elements);
+
+                                // No-data is generated at:
+                                // - No-data in condition expression
+                                // - True in condition expression && no-data in true expression
+                                // - False in condition expression && no-data in false expression
+
+                                for (Index i = 0; i < nr_elements; ++i)
+                                {
+                                    if (indp1.is_no_data(condition_data, i))
                                     {
-                                        if (indp1.is_no_data(condition_data, i))
-                                        {
-                                            ondp.mark_no_data(output_partition_data, i);
-                                        }
-                                        else if (!dp.within_domain(
-                                                     condition_data[i], true_data[i], false_scalar))
+                                        ondp.mark_no_data(output_partition_data, i);
+                                    }
+                                    else if (!dp.within_domain(condition_data[i], true_data[i], false_scalar))
+                                    {
+                                        ondp.mark_no_data(output_partition_data, i);
+                                    }
+                                    else
+                                    {
+                                        if (condition_data[i])
                                         {
-                                            ondp.mark_no_data(output_partition_data, i);
+                                            if (indp2.is_no_data(true_data, i))
+                                            {
+                                                ondp.mark_no_data(output_partition_data, i);
+                                            }
+                                            else
+                                            {
+                                                output_partition_data[i] = true_data[i];
+                                            }
                                         }
                                         else
                                         {
-                                            if (condition_data[i])
+                                            if (indp3.is_no_data(false_scalar))
                                             {
-                                                if (indp2.is_no_data(true_data, i))
-                                                {
-                                                    ondp.mark_no_data(output_partition_data, i);
-                                                }
-                                                else
-                                                {
-                                                    output_partition_data[i] = true_data[i];
-                                                }
+                                                ondp.mark_no_data(output_partition_data, i);
                                             }
                                             else
                                             {
-                                                if (indp3.is_no_data(false_scalar))
-                                                {
-                                                    ondp.mark_no_data(output_partition_data, i);
-                                                }
-                                                else
-                                                {
-                                                    output_partition_data[i] = false_scalar;
-                                                }
+                                                output_partition_data[i] = false_scalar;
                                             }
                                         }
                                     }
-
-                                    return Partition{
-                                        hpx::find_here(), offset, std::move(output_partition_data)};
                                 }
 
-                                ),
-                            condition_partition.offset(),
-                            condition_partition.data(),
-                            true_partition.data());
-                    }
-
-                    struct Action:
-                        hpx::actions::make_action<decltype(&where_partition), &where_partition, Action>::type
-                    {
-                    };
-            };
-
-
-            template<typename Policies, typename ConditionElement, typename Element, Rank rank>
-            class OverloadPicker<
-                Policies,
-                ArrayPartition<ConditionElement, rank>,
-                Element,
-                ArrayPartition<Element, rank>>
-            {
-
-                public:
-
-                    using ConditionPartition = ArrayPartition<ConditionElement, rank>;
-                    using Partition = ArrayPartition<Element, rank>;
-
-                    static Partition where_partition(
-                        Policies const& policies,
-                        ConditionPartition const& condition_partition,
-                        Element const true_scalar,
-                        Partition const& false_partition)
-                    {
-                        using Offset = OffsetT<ConditionPartition>;
-                        using ConditionData = DataT<ConditionPartition>;
-                        using Data = DataT<Partition>;
-
-                        lue_hpx_assert(condition_partition.is_ready());
-                        lue_hpx_assert(false_partition.is_ready());
-
-                        return hpx::dataflow(
-                            hpx::launch::async,
-                            hpx::unwrapping(
-
-                                [policies, condition_partition, true_scalar, false_partition](
-                                    Offset const& offset,
-                                    ConditionData const& condition_data,
-                                    Data const& false_data)
-                                {
-                                    AnnotateFunction annotation{"where_partition"};
+                                return Partition{hpx::find_here(), offset, std::move(output_partition_data)};
+                            }
 
-                                    HPX_UNUSED(condition_partition);
-                                    HPX_UNUSED(false_partition);
+                            ),
+                        condition_partition.offset(),
+                        condition_partition.data(),
+                        true_partition.data());
+                }
 
-                                    Data output_partition_data{condition_data.shape()};
+                struct Action:
+                    hpx::actions::make_action<decltype(&where_partition), &where_partition, Action>::type
+                {
+                };
+        };
 
-                                    auto const& dp = policies.domain_policy();
-                                    auto const& indp1 =
-                                        std::get<0>(policies.inputs_policies()).input_no_data_policy();
-                                    auto const& indp2 =
-                                        std::get<1>(policies.inputs_policies()).input_no_data_policy();
-                                    auto const& indp3 =
-                                        std::get<2>(policies.inputs_policies()).input_no_data_policy();
-                                    auto const& ondp =
-                                        std::get<0>(policies.outputs_policies()).output_no_data_policy();
 
-                                    Count const nr_elements{lue::nr_elements(condition_data)};
-                                    lue_hpx_assert(lue::nr_elements(false_data) == nr_elements);
+        template<typename Policies, typename ConditionElement, typename Element, Rank rank>
+        class OverloadPicker<
+            Policies,
+            ArrayPartition<ConditionElement, rank>,
+            Element,
+            ArrayPartition<Element, rank>>
+        {
 
-                                    // No-data is generated at:
-                                    // - No-data in condition expression
-                                    // - True in condition expression && no-data in true expression
-                                    // - False in condition expression && no-data in false expression
+            public:
 
-                                    for (Index i = 0; i < nr_elements; ++i)
+                using ConditionPartition = ArrayPartition<ConditionElement, rank>;
+                using Partition = ArrayPartition<Element, rank>;
+
+                static auto where_partition(
+                    Policies const& policies,
+                    ConditionPartition const& condition_partition,
+                    Element const true_scalar,
+                    Partition const& false_partition) -> Partition
+                {
+                    using Offset = OffsetT<ConditionPartition>;
+                    using ConditionData = DataT<ConditionPartition>;
+                    using Data = DataT<Partition>;
+
+                    lue_hpx_assert(condition_partition.is_ready());
+                    lue_hpx_assert(false_partition.is_ready());
+
+                    return hpx::dataflow(
+                        hpx::launch::async,
+                        hpx::unwrapping(
+
+                            [policies, condition_partition, true_scalar, false_partition](
+                                Offset const& offset,
+                                ConditionData const& condition_data,
+                                Data const& false_data)
+                            {
+                                AnnotateFunction annotation{"where_partition"};
+
+                                HPX_UNUSED(condition_partition);
+                                HPX_UNUSED(false_partition);
+
+                                Data output_partition_data{condition_data.shape()};
+
+                                auto const& dp = policies.domain_policy();
+                                auto const& indp1 =
+                                    std::get<0>(policies.inputs_policies()).input_no_data_policy();
+                                auto const& indp2 =
+                                    std::get<1>(policies.inputs_policies()).input_no_data_policy();
+                                auto const& indp3 =
+                                    std::get<2>(policies.inputs_policies()).input_no_data_policy();
+                                auto const& ondp =
+                                    std::get<0>(policies.outputs_policies()).output_no_data_policy();
+
+                                Count const nr_elements{lue::nr_elements(condition_data)};
+                                lue_hpx_assert(lue::nr_elements(false_data) == nr_elements);
+
+                                // No-data is generated at:
+                                // - No-data in condition expression
+                                // - True in condition expression && no-data in true expression
+                                // - False in condition expression && no-data in false expression
+
+                                for (Index i = 0; i < nr_elements; ++i)
+                                {
+                                    if (indp1.is_no_data(condition_data, i))
                                     {
-                                        if (indp1.is_no_data(condition_data, i))
-                                        {
-                                            ondp.mark_no_data(output_partition_data, i);
-                                        }
-                                        else if (!dp.within_domain(
-                                                     condition_data[i], true_scalar, false_data[i]))
+                                        ondp.mark_no_data(output_partition_data, i);
+                                    }
+                                    else if (!dp.within_domain(condition_data[i], true_scalar, false_data[i]))
+                                    {
+                                        ondp.mark_no_data(output_partition_data, i);
+                                    }
+                                    else
+                                    {
+                                        if (condition_data[i])
                                         {
-                                            ondp.mark_no_data(output_partition_data, i);
+                                            if (indp3.is_no_data(true_scalar))
+                                            {
+                                                ondp.mark_no_data(output_partition_data, i);
+                                            }
+                                            else
+                                            {
+                                                output_partition_data[i] = true_scalar;
+                                            }
                                         }
                                         else
                                         {
-                                            if (condition_data[i])
+                                            if (indp2.is_no_data(false_data, i))
                                             {
-                                                if (indp3.is_no_data(true_scalar))
-                                                {
-                                                    ondp.mark_no_data(output_partition_data, i);
-                                                }
-                                                else
-                                                {
-                                                    output_partition_data[i] = true_scalar;
-                                                }
+                                                ondp.mark_no_data(output_partition_data, i);
                                             }
                                             else
                                             {
-                                                if (indp2.is_no_data(false_data, i))
-                                                {
-                                                    ondp.mark_no_data(output_partition_data, i);
-                                                }
-                                                else
-                                                {
-                                                    output_partition_data[i] = false_data[i];
-                                                }
+                                                output_partition_data[i] = false_data[i];
                                             }
                                         }
                                     }
-
-                                    return Partition{
-                                        hpx::find_here(), offset, std::move(output_partition_data)};
                                 }
 
-                                ),
-                            condition_partition.offset(),
-                            condition_partition.data(),
-                            false_partition.data());
-                    }
+                                return Partition{hpx::find_here(), offset, std::move(output_partition_data)};
+                            }
+
+                            ),
+                        condition_partition.offset(),
+                        condition_partition.data(),
+                        false_partition.data());
+                }
 
-                    struct Action:
-                        hpx::actions::make_action<decltype(&where_partition), &where_partition, Action>::type
-                    {
-                    };
-            };
+                struct Action:
+                    hpx::actions::make_action<decltype(&where_partition), &where_partition, Action>::type
+                {
+                };
+        };
 
 
-            template<typename Policies, typename ConditionElement, typename Element, Rank rank>
-            class OverloadPicker<Policies, ArrayPartition<ConditionElement, rank>, Element, Element>
-            {
+        template<typename Policies, typename ConditionElement, typename Element, Rank rank>
+        class OverloadPicker<Policies, ArrayPartition<ConditionElement, rank>, Element, Element>
+        {
 
-                public:
+            public:
 
-                    using ConditionPartition = ArrayPartition<ConditionElement, rank>;
-                    using Partition = ArrayPartition<Element, rank>;
+                using ConditionPartition = ArrayPartition<ConditionElement, rank>;
+                using Partition = ArrayPartition<Element, rank>;
 
-                    static Partition where_partition(
-                        Policies const& policies,
-                        ConditionPartition const& condition_partition,
-                        Element const true_scalar,
-                        Element const false_scalar)
-                    {
-                        using Offset = OffsetT<ConditionPartition>;
-                        using ConditionData = DataT<ConditionPartition>;
-                        using Data = DataT<Partition>;
+                static auto where_partition(
+                    Policies const& policies,
+                    ConditionPartition const& condition_partition,
+                    Element const true_scalar,
+                    Element const false_scalar) -> Partition
+                {
+                    using Offset = OffsetT<ConditionPartition>;
+                    using ConditionData = DataT<ConditionPartition>;
+                    using Data = DataT<Partition>;
 
-                        lue_hpx_assert(condition_partition.is_ready());
+                    lue_hpx_assert(condition_partition.is_ready());
 
-                        return hpx::dataflow(
-                            hpx::launch::async,
-                            hpx::unwrapping(
+                    return hpx::dataflow(
+                        hpx::launch::async,
+                        hpx::unwrapping(
 
-                                [policies, condition_partition, true_scalar, false_scalar](
-                                    Offset const& offset, ConditionData const& condition_data)
-                                {
-                                    AnnotateFunction annotation{"where_partition"};
+                            [policies, condition_partition, true_scalar, false_scalar](
+                                Offset const& offset, ConditionData const& condition_data)
+                            {
+                                AnnotateFunction annotation{"where_partition"};
 
-                                    HPX_UNUSED(condition_partition);
+                                HPX_UNUSED(condition_partition);
 
-                                    Data output_partition_data{condition_data.shape()};
+                                Data output_partition_data{condition_data.shape()};
 
-                                    auto const& dp = policies.domain_policy();
-                                    auto const& indp1 =
-                                        std::get<0>(policies.inputs_policies()).input_no_data_policy();
-                                    auto const& indp2 =
-                                        std::get<1>(policies.inputs_policies()).input_no_data_policy();
-                                    auto const& indp3 =
-                                        std::get<2>(policies.inputs_policies()).input_no_data_policy();
-                                    auto const& ondp =
-                                        std::get<0>(policies.outputs_policies()).output_no_data_policy();
+                                auto const& dp = policies.domain_policy();
+                                auto const& indp1 =
+                                    std::get<0>(policies.inputs_policies()).input_no_data_policy();
+                                auto const& indp2 =
+                                    std::get<1>(policies.inputs_policies()).input_no_data_policy();
+                                auto const& indp3 =
+                                    std::get<2>(policies.inputs_policies()).input_no_data_policy();
+                                auto const& ondp =
+                                    std::get<0>(policies.outputs_policies()).output_no_data_policy();
 
-                                    Count const nr_elements{lue::nr_elements(condition_data)};
+                                Count const nr_elements{lue::nr_elements(condition_data)};
 
-                                    // No-data is generated at:
-                                    // - No-data in condition expression
-                                    // - True in condition expression && no-data in true expression
-                                    // - False in condition expression && no-data in false expression
+                                // No-data is generated at:
+                                // - No-data in condition expression
+                                // - True in condition expression && no-data in true expression
+                                // - False in condition expression && no-data in false expression
 
-                                    for (Index i = 0; i < nr_elements; ++i)
+                                for (Index i = 0; i < nr_elements; ++i)
+                                {
+                                    if (indp1.is_no_data(condition_data, i))
                                     {
-                                        if (indp1.is_no_data(condition_data, i))
-                                        {
-                                            ondp.mark_no_data(output_partition_data, i);
-                                        }
-                                        else if (!dp.within_domain(
-                                                     condition_data[i], true_scalar, false_scalar))
+                                        ondp.mark_no_data(output_partition_data, i);
+                                    }
+                                    else if (!dp.within_domain(condition_data[i], true_scalar, false_scalar))
+                                    {
+                                        ondp.mark_no_data(output_partition_data, i);
+                                    }
+                                    else
+                                    {
+                                        if (condition_data[i])
                                         {
-                                            ondp.mark_no_data(output_partition_data, i);
+                                            if (indp3.is_no_data(true_scalar))
+                                            {
+                                                ondp.mark_no_data(output_partition_data, i);
+                                            }
+                                            else
+                                            {
+                                                output_partition_data[i] = true_scalar;
+                                            }
                                         }
                                         else
                                         {
-                                            if (condition_data[i])
+                                            if (indp2.is_no_data(false_scalar))
                                             {
-                                                if (indp3.is_no_data(true_scalar))
-                                                {
-                                                    ondp.mark_no_data(output_partition_data, i);
-                                                }
-                                                else
-                                                {
-                                                    output_partition_data[i] = true_scalar;
-                                                }
+                                                ondp.mark_no_data(output_partition_data, i);
                                             }
                                             else
                                             {
-                                                if (indp2.is_no_data(false_scalar))
-                                                {
-                                                    ondp.mark_no_data(output_partition_data, i);
-                                                }
-                                                else
-                                                {
-                                                    output_partition_data[i] = false_scalar;
-                                                }
+                                                output_partition_data[i] = false_scalar;
                                             }
                                         }
                                     }
-
-                                    return Partition{
-                                        hpx::find_here(), offset, std::move(output_partition_data)};
                                 }
 
-                                ),
-                            condition_partition.offset(),
-                            condition_partition.data());
-                    }
+                                return Partition{hpx::find_here(), offset, std::move(output_partition_data)};
+                            }
 
-                    struct Action:
-                        hpx::actions::make_action<decltype(&where_partition), &where_partition, Action>::type
-                    {
-                    };
-            };
+                            ),
+                        condition_partition.offset(),
+                        condition_partition.data());
+                }
+
+                struct Action:
+                    hpx::actions::make_action<decltype(&where_partition), &where_partition, Action>::type
+                {
+                };
+        };
 
 
-            template<
-                typename Policies,
-                typename ConditionPartition,
-                typename TruePartition,
-                typename FalsePartition>
-            using WherePartitionAction =
-                typename OverloadPicker<Policies, ConditionPartition, TruePartition, FalsePartition>::Action;
+        template<
+            typename Policies,
+            typename ConditionPartition,
+            typename TruePartition,
+            typename FalsePartition>
+        using WherePartitionAction =
+            typename OverloadPicker<Policies, ConditionPartition, TruePartition, FalsePartition>::Action;
 
-        }  // namespace where
-    }      // namespace detail
+    }  // namespace detail::where
 
 
+    // where(array, array, array)
     template<typename Policies, typename ConditionElement, typename Element, Rank rank>
-    PartitionedArray<Element, rank> where(
+    auto where(
         Policies const& policies,
         PartitionedArray<ConditionElement, rank> const& condition,
         PartitionedArray<Element, rank> const& true_array,
-        PartitionedArray<Element, rank> const& false_array)
+        PartitionedArray<Element, rank> const& false_array) -> PartitionedArray<Element, rank>
     {
         using ConditionArray = PartitionedArray<ConditionElement, rank>;
         using ConditionPartitions = PartitionsT<ConditionArray>;
@@ -558,12 +550,13 @@ namespace lue {
     }
 
 
+    // where(array, array, value_f)
     template<typename Policies, typename ConditionElement, typename Element, Rank rank>
-    PartitionedArray<Element, rank> where(
+    auto where(
         Policies const& policies,
         PartitionedArray<ConditionElement, rank> const& condition,
         PartitionedArray<Element, rank> const& true_array,
-        hpx::shared_future<Element> const false_value)
+        hpx::shared_future<Element> const& false_value_f) -> PartitionedArray<Element, rank>
     {
         using ConditionArray = PartitionedArray<ConditionElement, rank>;
         using ConditionPartitions = PartitionsT<ConditionArray>;
@@ -590,29 +583,30 @@ namespace lue {
                 [locality_id = localities[p], action, policies](
                     ConditionPartition const& condition_partition,
                     Partition const& true_partition,
-                    hpx::shared_future<Element> const& false_value)
+                    hpx::shared_future<Element> const& false_value_f)
                 {
                     AnnotateFunction annotation{"where"};
 
                     return action(
-                        locality_id, policies, condition_partition, true_partition, false_value.get());
+                        locality_id, policies, condition_partition, true_partition, false_value_f.get());
                 },
 
                 condition_partitions[p],
                 true_partitions[p],
-                false_value);
+                false_value_f);
         }
 
         return Array{shape(condition), localities, std::move(output_partitions)};
     }
 
 
+    // where(array, value_f, array)
     template<typename Policies, typename ConditionElement, typename Element, Rank rank>
-    PartitionedArray<Element, rank> where(
+    auto where(
         Policies const& policies,
         PartitionedArray<ConditionElement, rank> const& condition,
-        hpx::shared_future<Element> const true_value,
-        PartitionedArray<Element, rank> const& false_array)
+        hpx::shared_future<Element> const& true_value_f,
+        PartitionedArray<Element, rank> const& false_array) -> PartitionedArray<Element, rank>
     {
         using ConditionArray = PartitionedArray<ConditionElement, rank>;
         using ConditionPartitions = PartitionsT<ConditionArray>;
@@ -638,17 +632,17 @@ namespace lue {
 
                 [locality_id = localities[p], action, policies](
                     ConditionPartition const& condition_partition,
-                    hpx::shared_future<Element> const& true_value,
+                    hpx::shared_future<Element> const& true_value_f,
                     Partition const& false_partition)
                 {
                     AnnotateFunction annotation{"where"};
 
                     return action(
-                        locality_id, policies, condition_partition, true_value.get(), false_partition);
+                        locality_id, policies, condition_partition, true_value_f.get(), false_partition);
                 },
 
                 condition_partitions[p],
-                true_value,
+                true_value_f,
                 false_partitions[p]);
         }
 
@@ -656,12 +650,13 @@ namespace lue {
     }
 
 
+    // where(array, value_f, value_f)
     template<typename Policies, typename ConditionElement, typename Element, Rank rank>
-    PartitionedArray<Element, rank> where(
+    auto where(
         Policies const& policies,
         PartitionedArray<ConditionElement, rank> const& condition,
-        hpx::shared_future<Element> const true_value,
-        hpx::shared_future<Element> const false_value)
+        hpx::shared_future<Element> const& true_value_f,
+        hpx::shared_future<Element> const& false_value_f) -> PartitionedArray<Element, rank>
     {
         using ConditionArray = PartitionedArray<ConditionElement, rank>;
         using ConditionPartitions = PartitionsT<ConditionArray>;
@@ -683,29 +678,30 @@ namespace lue {
 
                 [locality_id = localities[p], action, policies](
                     ConditionPartition const& condition_partition,
-                    hpx::shared_future<Element> const& true_value,
-                    hpx::shared_future<Element> const& false_value)
+                    hpx::shared_future<Element> const& true_value_f,
+                    hpx::shared_future<Element> const& false_value_f)
                 {
                     AnnotateFunction annotation{"where"};
 
                     return action(
-                        locality_id, policies, condition_partition, true_value.get(), false_value.get());
+                        locality_id, policies, condition_partition, true_value_f.get(), false_value_f.get());
                 },
 
                 condition_partitions[p],
-                true_value,
-                false_value);
+                true_value_f,
+                false_value_f);
         }
 
         return Array{shape(condition), localities, std::move(output_partitions)};
     }
 
 
+    // where(array, array)
     template<typename Policies, typename ConditionElement, typename Element, Rank rank>
-    PartitionedArray<Element, rank> where(
+    auto where(
         Policies const& policies,
         PartitionedArray<ConditionElement, rank> const& condition,
-        PartitionedArray<Element, rank> const& true_array)
+        PartitionedArray<Element, rank> const& true_array) -> PartitionedArray<Element, rank>
     {
         using Functor = detail::where::Where<ConditionElement, Element>;
 
@@ -713,15 +709,29 @@ namespace lue {
     }
 
 
+    // where(array, value_f)
     template<typename Policies, typename ConditionElement, typename Element, Rank rank>
-    PartitionedArray<Element, rank> where(
+    auto where(
         Policies const& policies,
         PartitionedArray<ConditionElement, rank> const& condition,
-        hpx::shared_future<Element> const true_value)
+        hpx::shared_future<Element> const& true_value_f) -> PartitionedArray<Element, rank>
     {
         using Functor = detail::where::Where<ConditionElement, Element>;
 
-        return binary_local_operation(policies, condition, true_value, Functor{});
+        return binary_local_operation(policies, condition, true_value_f, Functor{});
+    }
+
+
+    // where(array, scalar)
+    template<typename Policies, typename ConditionElement, typename Element, Rank rank>
+    auto where(
+        Policies const& policies,
+        PartitionedArray<ConditionElement, rank> const& condition,
+        Scalar<Element> const& true_scalar) -> PartitionedArray<Element, rank>
+    {
+        using Functor = detail::where::Where<ConditionElement, Element>;
+
+        return binary_local_operation(policies, condition, true_scalar.future(), Functor{});
     }
 
 }  // namespace lue
@@ -739,7 +749,13 @@ namespace lue {
     where<ArgumentType<void(Policies)>, ConditionElement, Element, rank>(                                    \
         ArgumentType<void(Policies)> const&,                                                                 \
         PartitionedArray<ConditionElement, rank> const&,                                                     \
-        hpx::shared_future<Element> const);
+        Scalar<Element> const&);                                                                             \
+                                                                                                             \
+    template LUE_LOCAL_OPERATION_EXPORT PartitionedArray<Element, rank>                                      \
+    where<ArgumentType<void(Policies)>, ConditionElement, Element, rank>(                                    \
+        ArgumentType<void(Policies)> const&,                                                                 \
+        PartitionedArray<ConditionElement, rank> const&,                                                     \
+        hpx::shared_future<Element> const&);
 
 
 #define LUE_INSTANTIATE_WHERE3(Policies, ConditionElement, Element, rank)                                    \
@@ -756,18 +772,39 @@ namespace lue {
         ArgumentType<void(Policies)> const&,                                                                 \
         PartitionedArray<ConditionElement, rank> const&,                                                     \
         PartitionedArray<Element, rank> const&,                                                              \
-        hpx::shared_future<Element> const);                                                                  \
+        hpx::shared_future<Element> const&);                                                                 \
+                                                                                                             \
+    template LUE_LOCAL_OPERATION_EXPORT PartitionedArray<Element, rank>                                      \
+    where<ArgumentType<void(Policies)>, ConditionElement, Element, rank>(                                    \
+        ArgumentType<void(Policies)> const&,                                                                 \
+        PartitionedArray<ConditionElement, rank> const&,                                                     \
+        hpx::shared_future<Element> const&,                                                                  \
+        PartitionedArray<Element, rank> const&);                                                             \
+                                                                                                             \
+    template LUE_LOCAL_OPERATION_EXPORT PartitionedArray<Element, rank>                                      \
+    where<ArgumentType<void(Policies)>, ConditionElement, Element, rank>(                                    \
+        ArgumentType<void(Policies)> const&,                                                                 \
+        PartitionedArray<ConditionElement, rank> const&,                                                     \
+        hpx::shared_future<Element> const&,                                                                  \
+        hpx::shared_future<Element> const&);                                                                 \
+                                                                                                             \
+    template LUE_LOCAL_OPERATION_EXPORT PartitionedArray<Element, rank>                                      \
+    where<ArgumentType<void(Policies)>, ConditionElement, Element, rank>(                                    \
+        ArgumentType<void(Policies)> const&,                                                                 \
+        PartitionedArray<ConditionElement, rank> const&,                                                     \
+        PartitionedArray<Element, rank> const&,                                                              \
+        Scalar<Element> const&);                                                                             \
                                                                                                              \
     template LUE_LOCAL_OPERATION_EXPORT PartitionedArray<Element, rank>                                      \
     where<ArgumentType<void(Policies)>, ConditionElement, Element, rank>(                                    \
         ArgumentType<void(Policies)> const&,                                                                 \
         PartitionedArray<ConditionElement, rank> const&,                                                     \
-        hpx::shared_future<Element> const,                                                                   \
+        Scalar<Element> const&,                                                                              \
         PartitionedArray<Element, rank> const&);                                                             \
                                                                                                              \
     template LUE_LOCAL_OPERATION_EXPORT PartitionedArray<Element, rank>                                      \
     where<ArgumentType<void(Policies)>, ConditionElement, Element, rank>(                                    \
         ArgumentType<void(Policies)> const&,                                                                 \
         PartitionedArray<ConditionElement, rank> const&,                                                     \
-        hpx::shared_future<Element> const,                                                                   \
-        hpx::shared_future<Element> const);
+        Scalar<Element> const&,                                                                              \
+        Scalar<Element> const&);
diff --git a/source/framework/algorithm/include/lue/framework/algorithm/divide.hpp b/source/framework/algorithm/include/lue/framework/algorithm/divide.hpp
index 2c747009f..a41f64fb4 100644
--- a/source/framework/algorithm/include/lue/framework/algorithm/divide.hpp
+++ b/source/framework/algorithm/include/lue/framework/algorithm/divide.hpp
@@ -46,6 +46,6 @@ namespace lue {
     }  // namespace policy::divide
 
 
-    LUE_BINARY_LOCAL_OPERATION_OVERLOADS3(divide, detail::Divide)
+    LUE_BINARY_LOCAL_OPERATION_OVERLOADS_WITH_POLICIES(divide, detail::Divide)
 
 }  // namespace lue
diff --git a/source/framework/algorithm/include/lue/framework/algorithm/equal_to.hpp b/source/framework/algorithm/include/lue/framework/algorithm/equal_to.hpp
index b6a3f912b..86a5b7bca 100644
--- a/source/framework/algorithm/include/lue/framework/algorithm/equal_to.hpp
+++ b/source/framework/algorithm/include/lue/framework/algorithm/equal_to.hpp
@@ -25,6 +25,6 @@ namespace lue {
     }  // namespace detail
 
 
-    LUE_BINARY_LOCAL_OPERATION_OVERLOADS3(equal_to, detail::EqualTo)
+    LUE_BINARY_LOCAL_OPERATION_OVERLOADS_WITH_POLICIES(equal_to, detail::EqualTo)
 
 }  // namespace lue
diff --git a/source/framework/algorithm/include/lue/framework/algorithm/greater_than.hpp b/source/framework/algorithm/include/lue/framework/algorithm/greater_than.hpp
index b06a7c5b5..3e34f178f 100644
--- a/source/framework/algorithm/include/lue/framework/algorithm/greater_than.hpp
+++ b/source/framework/algorithm/include/lue/framework/algorithm/greater_than.hpp
@@ -25,6 +25,6 @@ namespace lue {
     }  // namespace detail
 
 
-    LUE_BINARY_LOCAL_OPERATION_OVERLOADS3(greater_than, detail::GreaterThan)
+    LUE_BINARY_LOCAL_OPERATION_OVERLOADS_WITH_POLICIES(greater_than, detail::GreaterThan)
 
 }  // namespace lue
diff --git a/source/framework/algorithm/include/lue/framework/algorithm/greater_than_equal_to.hpp b/source/framework/algorithm/include/lue/framework/algorithm/greater_than_equal_to.hpp
index 811dae6c8..f21d0b546 100644
--- a/source/framework/algorithm/include/lue/framework/algorithm/greater_than_equal_to.hpp
+++ b/source/framework/algorithm/include/lue/framework/algorithm/greater_than_equal_to.hpp
@@ -25,6 +25,6 @@ namespace lue {
     }  // namespace detail
 
 
-    LUE_BINARY_LOCAL_OPERATION_OVERLOADS3(greater_than_equal_to, detail::GreaterThanEqualTo)
+    LUE_BINARY_LOCAL_OPERATION_OVERLOADS_WITH_POLICIES(greater_than_equal_to, detail::GreaterThanEqualTo)
 
 }  // namespace lue
diff --git a/source/framework/algorithm/include/lue/framework/algorithm/less_than.hpp b/source/framework/algorithm/include/lue/framework/algorithm/less_than.hpp
index f52da8906..21c87000a 100644
--- a/source/framework/algorithm/include/lue/framework/algorithm/less_than.hpp
+++ b/source/framework/algorithm/include/lue/framework/algorithm/less_than.hpp
@@ -26,6 +26,6 @@ namespace lue {
     }  // namespace detail
 
 
-    LUE_BINARY_LOCAL_OPERATION_OVERLOADS3(less_than, detail::LessThan)
+    LUE_BINARY_LOCAL_OPERATION_OVERLOADS_WITH_POLICIES(less_than, detail::LessThan)
 
 }  // namespace lue
diff --git a/source/framework/algorithm/include/lue/framework/algorithm/less_than_equal_to.hpp b/source/framework/algorithm/include/lue/framework/algorithm/less_than_equal_to.hpp
index 0ae1edd54..58d050c96 100644
--- a/source/framework/algorithm/include/lue/framework/algorithm/less_than_equal_to.hpp
+++ b/source/framework/algorithm/include/lue/framework/algorithm/less_than_equal_to.hpp
@@ -25,6 +25,6 @@ namespace lue {
     }  // namespace detail
 
 
-    LUE_BINARY_LOCAL_OPERATION_OVERLOADS3(less_than_equal_to, detail::LessThanEqualTo)
+    LUE_BINARY_LOCAL_OPERATION_OVERLOADS_WITH_POLICIES(less_than_equal_to, detail::LessThanEqualTo)
 
 }  // namespace lue
diff --git a/source/framework/algorithm/include/lue/framework/algorithm/logical_and.hpp b/source/framework/algorithm/include/lue/framework/algorithm/logical_and.hpp
index cfd2e0df2..e175bebc9 100644
--- a/source/framework/algorithm/include/lue/framework/algorithm/logical_and.hpp
+++ b/source/framework/algorithm/include/lue/framework/algorithm/logical_and.hpp
@@ -27,6 +27,6 @@ namespace lue {
     }  // namespace detail
 
 
-    LUE_BINARY_LOCAL_OPERATION_OVERLOADS3(logical_and, detail::LogicalAnd)
+    LUE_BINARY_LOCAL_OPERATION_OVERLOADS_WITH_POLICIES(logical_and, detail::LogicalAnd)
 
 }  // namespace lue
diff --git a/source/framework/algorithm/include/lue/framework/algorithm/logical_exclusive_or.hpp b/source/framework/algorithm/include/lue/framework/algorithm/logical_exclusive_or.hpp
index 2118ec6fc..d30165dd9 100644
--- a/source/framework/algorithm/include/lue/framework/algorithm/logical_exclusive_or.hpp
+++ b/source/framework/algorithm/include/lue/framework/algorithm/logical_exclusive_or.hpp
@@ -27,6 +27,6 @@ namespace lue {
     }  // namespace detail
 
 
-    LUE_BINARY_LOCAL_OPERATION_OVERLOADS3(logical_exclusive_or, detail::LogicalExclusiveOr)
+    LUE_BINARY_LOCAL_OPERATION_OVERLOADS_WITH_POLICIES(logical_exclusive_or, detail::LogicalExclusiveOr)
 
 }  // namespace lue
diff --git a/source/framework/algorithm/include/lue/framework/algorithm/logical_inclusive_or.hpp b/source/framework/algorithm/include/lue/framework/algorithm/logical_inclusive_or.hpp
index 8819452b0..1cfefd4b9 100644
--- a/source/framework/algorithm/include/lue/framework/algorithm/logical_inclusive_or.hpp
+++ b/source/framework/algorithm/include/lue/framework/algorithm/logical_inclusive_or.hpp
@@ -27,6 +27,6 @@ namespace lue {
     }  // namespace detail
 
 
-    LUE_BINARY_LOCAL_OPERATION_OVERLOADS3(logical_inclusive_or, detail::LogicalInclusiveOr)
+    LUE_BINARY_LOCAL_OPERATION_OVERLOADS_WITH_POLICIES(logical_inclusive_or, detail::LogicalInclusiveOr)
 
 }  // namespace lue
diff --git a/source/framework/algorithm/include/lue/framework/algorithm/maximum.hpp b/source/framework/algorithm/include/lue/framework/algorithm/maximum.hpp
index 87660b94d..1a88f9061 100644
--- a/source/framework/algorithm/include/lue/framework/algorithm/maximum.hpp
+++ b/source/framework/algorithm/include/lue/framework/algorithm/maximum.hpp
@@ -1,5 +1,6 @@
 #pragma once
 #include "lue/framework/algorithm/policy.hpp"
+#include "lue/framework/algorithm/scalar.hpp"
 #include "lue/framework/partitioned_array.hpp"
 
 
@@ -8,6 +9,6 @@ namespace lue {
     template<typename Policies, Rank rank>
     auto maximum(
         Policies const& policies, PartitionedArray<policy::InputElementT<Policies, 0>, rank> const& array)
-        -> hpx::future<policy::OutputElementT<Policies, 0>>;
+        -> Scalar<policy::OutputElementT<Policies, 0>>;
 
 }  // namespace lue
diff --git a/source/framework/algorithm/include/lue/framework/algorithm/minimum.hpp b/source/framework/algorithm/include/lue/framework/algorithm/minimum.hpp
index 4c1635597..c1fee7a4a 100644
--- a/source/framework/algorithm/include/lue/framework/algorithm/minimum.hpp
+++ b/source/framework/algorithm/include/lue/framework/algorithm/minimum.hpp
@@ -1,5 +1,6 @@
 #pragma once
 #include "lue/framework/algorithm/policy.hpp"
+#include "lue/framework/algorithm/scalar.hpp"
 #include "lue/framework/partitioned_array.hpp"
 
 
@@ -8,6 +9,6 @@ namespace lue {
     template<typename Policies, Rank rank>
     auto minimum(
         Policies const& policies, PartitionedArray<policy::InputElementT<Policies, 0>, rank> const& array)
-        -> hpx::future<policy::OutputElementT<Policies, 0>>;
+        -> Scalar<policy::OutputElementT<Policies, 0>>;
 
 }  // namespace lue
diff --git a/source/framework/algorithm/include/lue/framework/algorithm/multiply.hpp b/source/framework/algorithm/include/lue/framework/algorithm/multiply.hpp
index a3d8b9a79..ef639006c 100644
--- a/source/framework/algorithm/include/lue/framework/algorithm/multiply.hpp
+++ b/source/framework/algorithm/include/lue/framework/algorithm/multiply.hpp
@@ -26,6 +26,6 @@ namespace lue {
     }  // namespace detail
 
 
-    LUE_BINARY_LOCAL_OPERATION_OVERLOADS3(multiply, detail::Multiply)
+    LUE_BINARY_LOCAL_OPERATION_OVERLOADS_WITH_POLICIES(multiply, detail::Multiply)
 
 }  // namespace lue
diff --git a/source/framework/algorithm/include/lue/framework/algorithm/not_equal_to.hpp b/source/framework/algorithm/include/lue/framework/algorithm/not_equal_to.hpp
index bab844639..a87166c02 100644
--- a/source/framework/algorithm/include/lue/framework/algorithm/not_equal_to.hpp
+++ b/source/framework/algorithm/include/lue/framework/algorithm/not_equal_to.hpp
@@ -26,6 +26,6 @@ namespace lue {
     }  // namespace detail
 
 
-    LUE_BINARY_LOCAL_OPERATION_OVERLOADS3(not_equal_to, detail::NotEqualTo)
+    LUE_BINARY_LOCAL_OPERATION_OVERLOADS_WITH_POLICIES(not_equal_to, detail::NotEqualTo)
 
 }  // namespace lue
diff --git a/source/framework/algorithm/include/lue/framework/algorithm/operator.hpp b/source/framework/algorithm/include/lue/framework/algorithm/operator.hpp
index 1b7260bda..7db54c8f7 100644
--- a/source/framework/algorithm/include/lue/framework/algorithm/operator.hpp
+++ b/source/framework/algorithm/include/lue/framework/algorithm/operator.hpp
@@ -2,47 +2,6 @@
 
 
 #define LUE_BINARY_ARITHMETIC_OPERATOR(symbol, name)                                                         \
-    template<typename Element, Rank rank>                                                                    \
-    PartitionedArray<Element, rank> operator symbol(                                                         \
-        PartitionedArray<Element, rank> const& lhs, PartitionedArray<Element, rank> const& rhs)              \
-    {                                                                                                        \
-        return name(lhs, rhs);                                                                               \
-    }                                                                                                        \
-                                                                                                             \
-                                                                                                             \
-    template<typename Element, Rank rank>                                                                    \
-    PartitionedArray<Element, rank> operator symbol(                                                         \
-        PartitionedArray<Element, rank> const& lhs, hpx::shared_future<Element> const& rhs)                  \
-    {                                                                                                        \
-        return name(lhs, rhs);                                                                               \
-    }                                                                                                        \
-                                                                                                             \
-                                                                                                             \
-    template<typename Element, Rank rank>                                                                    \
-    PartitionedArray<Element, rank> operator symbol(                                                         \
-        hpx::shared_future<Element> const& lhs, PartitionedArray<Element, rank> const& rhs)                  \
-    {                                                                                                        \
-        return name(lhs, rhs);                                                                               \
-    }                                                                                                        \
-                                                                                                             \
-                                                                                                             \
-    template<typename Element, Rank rank>                                                                    \
-    PartitionedArray<Element, rank> operator symbol(                                                         \
-        PartitionedArray<Element, rank> const& lhs, Element const rhs)                                       \
-    {                                                                                                        \
-        return name(lhs, rhs);                                                                               \
-    }                                                                                                        \
-                                                                                                             \
-                                                                                                             \
-    template<typename Element, Rank rank>                                                                    \
-    PartitionedArray<Element, rank> operator symbol(                                                         \
-        Element const lhs, PartitionedArray<Element, rank> const& rhs)                                       \
-    {                                                                                                        \
-        return name(lhs, rhs);                                                                               \
-    }
-
-
-#define LUE_BINARY_ARITHMETIC_OPERATOR2(symbol, name)                                                        \
                                                                                                              \
     /* array + array */                                                                                      \
     template<typename Element, Rank rank>                                                                    \
@@ -114,6 +73,8 @@
 
 
 #define LUE_BINARY_COMPARISON_OPERATOR(symbol, name)                                                         \
+                                                                                                             \
+    /* array == array */                                                                                     \
     template<typename Element, Rank rank>                                                                    \
     PartitionedArray<std::uint8_t, rank> operator symbol(                                                    \
         PartitionedArray<Element, rank> const& lhs, PartitionedArray<Element, rank> const& rhs)              \
@@ -121,23 +82,23 @@
         return name(lhs, rhs);                                                                               \
     }                                                                                                        \
                                                                                                              \
-                                                                                                             \
+    /* array == scalar */                                                                                    \
     template<typename Element, Rank rank>                                                                    \
     PartitionedArray<std::uint8_t, rank> operator symbol(                                                    \
-        PartitionedArray<Element, rank> const& lhs, hpx::shared_future<Element> const& rhs)                  \
+        PartitionedArray<Element, rank> const& lhs, Scalar<Element> const& rhs)                              \
     {                                                                                                        \
         return name(lhs, rhs);                                                                               \
     }                                                                                                        \
                                                                                                              \
-                                                                                                             \
+    /* scalar == array */                                                                                    \
     template<typename Element, Rank rank>                                                                    \
     PartitionedArray<std::uint8_t, rank> operator symbol(                                                    \
-        hpx::shared_future<Element> const& lhs, PartitionedArray<Element, rank> const& rhs)                  \
+        Scalar<Element> const& lhs, PartitionedArray<Element, rank> const& rhs)                              \
     {                                                                                                        \
         return name(lhs, rhs);                                                                               \
     }                                                                                                        \
                                                                                                              \
-                                                                                                             \
+    /* array == value */                                                                                     \
     template<typename Element, Rank rank>                                                                    \
     PartitionedArray<std::uint8_t, rank> operator symbol(                                                    \
         PartitionedArray<Element, rank> const& lhs, Element const rhs)                                       \
@@ -145,10 +106,24 @@
         return name(lhs, rhs);                                                                               \
     }                                                                                                        \
                                                                                                              \
-                                                                                                             \
+    /* value == array */                                                                                     \
     template<typename Element, Rank rank>                                                                    \
     PartitionedArray<std::uint8_t, rank> operator symbol(                                                    \
         Element const lhs, PartitionedArray<Element, rank> const& rhs)                                       \
+    {                                                                                                        \
+        return name(lhs, rhs);                                                                               \
+    }                                                                                                        \
+                                                                                                             \
+    /* scalar == value */                                                                                    \
+    template<typename Element>                                                                               \
+    auto operator symbol(Scalar<Element> const& lhs, Element const rhs)->Scalar<std::uint8_t>                \
+    {                                                                                                        \
+        return name(lhs, rhs);                                                                               \
+    }                                                                                                        \
+                                                                                                             \
+    /* value == scalar */                                                                                    \
+    template<typename Element>                                                                               \
+    auto operator symbol(Element const lhs, Scalar<Element> const& rhs)->Scalar<std::uint8_t>                \
     {                                                                                                        \
         return name(lhs, rhs);                                                                               \
     }
diff --git a/source/framework/algorithm/include/lue/framework/algorithm/pow.hpp b/source/framework/algorithm/include/lue/framework/algorithm/pow.hpp
index 19053c6c9..30759d494 100644
--- a/source/framework/algorithm/include/lue/framework/algorithm/pow.hpp
+++ b/source/framework/algorithm/include/lue/framework/algorithm/pow.hpp
@@ -51,6 +51,19 @@ namespace lue {
     }  // namespace policy::pow
 
 
-    LUE_BINARY_LOCAL_OPERATION_OVERLOADS(pow, detail::Pow)
+    LUE_BINARY_LOCAL_OPERATION_OVERLOADS_WITH_POLICIES(pow, detail::Pow)
+
+    namespace default_policies {
+
+        LUE_BINARY_LOCAL_OPERATION_OVERLOADS_WITHOUT_POLICIES(pow, detail::Pow, policy::pow::DefaultPolicies)
+
+    }  // namespace default_policies
+
+    namespace value_policies {
+
+        LUE_BINARY_LOCAL_OPERATION_OVERLOADS_WITHOUT_POLICIES(
+            pow, detail::Pow, policy::pow::DefaultValuePolicies)
+
+    }  // namespace value_policies
 
 }  // namespace lue
diff --git a/source/framework/algorithm/include/lue/framework/algorithm/scalar.hpp b/source/framework/algorithm/include/lue/framework/algorithm/scalar.hpp
index 304f50559..2966774cf 100644
--- a/source/framework/algorithm/include/lue/framework/algorithm/scalar.hpp
+++ b/source/framework/algorithm/include/lue/framework/algorithm/scalar.hpp
@@ -1,4 +1,5 @@
 #pragma once
+#include "lue/framework/core/type_traits.hpp"
 #include <hpx/future.hpp>
 
 
@@ -167,7 +168,7 @@ namespace lue {
 
                 The result can be used to attach continuations to.
             */
-            auto value() const -> hpx::shared_future<Element> const&
+            auto future() const -> hpx::shared_future<Element> const&
             {
                 return _value_f;
             }
@@ -179,4 +180,19 @@ namespace lue {
             hpx::shared_future<Element> _value_f;
     };
 
+
+    namespace detail {
+
+        // Specialization for PartitionedArray
+        template<typename E>
+        class ArrayTraits<Scalar<E>>
+        {
+
+            public:
+
+                using Element = E;
+        };
+
+    }  // namespace detail
+
 }  // namespace lue
diff --git a/source/framework/algorithm/include/lue/framework/algorithm/subtract.hpp b/source/framework/algorithm/include/lue/framework/algorithm/subtract.hpp
index ce6bbefaa..e0f940b79 100644
--- a/source/framework/algorithm/include/lue/framework/algorithm/subtract.hpp
+++ b/source/framework/algorithm/include/lue/framework/algorithm/subtract.hpp
@@ -26,6 +26,6 @@ namespace lue {
     }  // namespace detail
 
 
-    LUE_BINARY_LOCAL_OPERATION_OVERLOADS3(subtract, detail::Subtract)
+    LUE_BINARY_LOCAL_OPERATION_OVERLOADS_WITH_POLICIES(subtract, detail::Subtract)
 
 }  // namespace lue
diff --git a/source/framework/algorithm/include/lue/framework/algorithm/sum.hpp b/source/framework/algorithm/include/lue/framework/algorithm/sum.hpp
index 73145ef1f..a947c56f8 100644
--- a/source/framework/algorithm/include/lue/framework/algorithm/sum.hpp
+++ b/source/framework/algorithm/include/lue/framework/algorithm/sum.hpp
@@ -1,5 +1,6 @@
 #pragma once
 #include "lue/framework/algorithm/policy.hpp"
+#include "lue/framework/algorithm/scalar.hpp"
 #include "lue/framework/partitioned_array.hpp"
 
 
@@ -8,6 +9,6 @@ namespace lue {
     template<typename Policies, Rank rank>
     auto sum(
         Policies const& policies, PartitionedArray<policy::InputElementT<Policies, 0>, rank> const& array)
-        -> hpx::future<policy::OutputElementT<Policies, 0>>;
+        -> Scalar<policy::OutputElementT<Policies, 0>>;
 
 }  // namespace lue
diff --git a/source/framework/algorithm/include/lue/framework/algorithm/unary_aggregate_operation.hpp b/source/framework/algorithm/include/lue/framework/algorithm/unary_aggregate_operation.hpp
index f874a6ca1..5efb4ff53 100644
--- a/source/framework/algorithm/include/lue/framework/algorithm/unary_aggregate_operation.hpp
+++ b/source/framework/algorithm/include/lue/framework/algorithm/unary_aggregate_operation.hpp
@@ -1,5 +1,6 @@
 #pragma once
 #include "lue/framework/algorithm/functor_traits.hpp"
+#include "lue/framework/algorithm/scalar.hpp"
 #include "lue/framework/core/annotate.hpp"
 #include "lue/framework/partitioned_array.hpp"
 
@@ -8,8 +9,9 @@ namespace lue {
     namespace detail {
 
         template<typename Policies, typename InputPartition, typename OutputElement, typename Functor>
-        hpx::future<OutputElement> unary_aggregate_operation_partition(
+        auto unary_aggregate_operation_partition(
             Policies const& policies, InputPartition const& input_partition, Functor functor)
+            -> hpx::future<OutputElement>
         {
             AnnotateFunction annotation{"unary_aggregate_operation"};
 
@@ -113,11 +115,11 @@ namespace lue {
 
 
     template<typename Policies, typename InputElement, Rank rank, typename Functor>
-    hpx::future<OutputElementT<Functor>> unary_aggregate_operation(
+    auto unary_aggregate_operation(
         hpx::id_type const locality_id,
         Policies const& policies,
         ArrayPartition<InputElement, rank> const& input_partition,
-        Functor const& functor)
+        Functor const& functor) -> hpx::future<OutputElementT<Functor>>
     {
         AnnotateFunction annotation{"unary_aggregate_operation"};
 
@@ -138,10 +140,10 @@ namespace lue {
 
 
     template<typename Policies, typename InputElement, Rank rank, typename Functor>
-    hpx::future<OutputElementT<Functor>> unary_aggregate_operation(
+    auto unary_aggregate_operation(
         Policies const& policies,
         PartitionedArray<InputElement, rank> const& input_array,
-        Functor const& functor)
+        Functor const& functor) -> Scalar<OutputElementT<Functor>>
     {
         AnnotateFunction annotation{"unary_aggregate_operation"};
 
@@ -178,7 +180,7 @@ namespace lue {
         return hpx::when_all(partition_results.begin(), partition_results.end())
             .then(hpx::unwrapping(
 
-                [policies, functor](auto&& partition_results)
+                [policies, functor](auto&& partition_results) -> OutputElement
                 {
                     AnnotateFunction annotation{"unary_aggregate_operation"};
 
diff --git a/source/framework/algorithm/include/lue/framework/algorithm/uniform.hpp b/source/framework/algorithm/include/lue/framework/algorithm/uniform.hpp
index 373fef550..dbc5bcac7 100644
--- a/source/framework/algorithm/include/lue/framework/algorithm/uniform.hpp
+++ b/source/framework/algorithm/include/lue/framework/algorithm/uniform.hpp
@@ -336,7 +336,7 @@ namespace lue {
         using Functor = InstantiateUniform<policy::OutputElementT<Policies, 0>, rank<Shape>>;
 
         return create_partitioned_array(
-            policies, array_shape, partition_shape, Functor{min_value.value(), max_value.value()});
+            policies, array_shape, partition_shape, Functor{min_value.future(), max_value.future()});
     }
 
 
@@ -368,7 +368,8 @@ namespace lue {
     {
         using Functor = InstantiateUniform<policy::OutputElementT<Policies, 0>, rank<Shape>>;
 
-        return create_partitioned_array(policies, array_shape, Functor{min_value.value(), max_value.value()});
+        return create_partitioned_array(
+            policies, array_shape, Functor{min_value.future(), max_value.future()});
     }
 
 
diff --git a/source/framework/algorithm/include/lue/framework/algorithm/unique.hpp b/source/framework/algorithm/include/lue/framework/algorithm/unique.hpp
index b0a4cfe3a..6296b1b77 100644
--- a/source/framework/algorithm/include/lue/framework/algorithm/unique.hpp
+++ b/source/framework/algorithm/include/lue/framework/algorithm/unique.hpp
@@ -15,7 +15,7 @@ namespace lue {
                     ready once the algorithm has finished
     */
     template<typename Policies, typename Element, Rank rank>
-    hpx::future<std::set<Element>> unique(
-        Policies const& policies, PartitionedArray<Element, rank> const& array);
+    auto unique(Policies const& policies, PartitionedArray<Element, rank> const& array)
+        -> hpx::future<std::set<Element>>;
 
 }  // namespace lue
diff --git a/source/framework/algorithm/include/lue/framework/algorithm/value_policies/add.hpp b/source/framework/algorithm/include/lue/framework/algorithm/value_policies/add.hpp
index 3435f0a61..82b2034ed 100644
--- a/source/framework/algorithm/include/lue/framework/algorithm/value_policies/add.hpp
+++ b/source/framework/algorithm/include/lue/framework/algorithm/value_policies/add.hpp
@@ -37,8 +37,9 @@ namespace lue {
 
     namespace value_policies {
 
-        LUE_BINARY_LOCAL_OPERATION_OVERLOADS5(add, detail::Add, policy::add::DefaultValuePolicies)
-        LUE_BINARY_ARITHMETIC_OPERATOR2(+, add)
+        LUE_BINARY_LOCAL_OPERATION_OVERLOADS_WITHOUT_POLICIES(
+            add, detail::Add, policy::add::DefaultValuePolicies)
+        LUE_BINARY_ARITHMETIC_OPERATOR(+, add)
 
     }  // namespace value_policies
 }  // namespace lue
diff --git a/source/framework/algorithm/include/lue/framework/algorithm/value_policies/all.hpp b/source/framework/algorithm/include/lue/framework/algorithm/value_policies/all.hpp
index 2fc157f2b..6310dc4a1 100644
--- a/source/framework/algorithm/include/lue/framework/algorithm/value_policies/all.hpp
+++ b/source/framework/algorithm/include/lue/framework/algorithm/value_policies/all.hpp
@@ -17,7 +17,7 @@ namespace lue {
     namespace value_policies {
 
         template<typename Element, Rank rank>
-        hpx::future<Element> all(PartitionedArray<Element, rank> const& array)
+        auto all(PartitionedArray<Element, rank> const& array) -> Scalar<Element>
         {
             using Policies = policy::all::DefaultValuePolicies<Element>;
 
@@ -26,8 +26,8 @@ namespace lue {
 
 
         template<typename Element, Rank rank>
-        hpx::future<Element> all(
-            hpx::id_type const locality_id, ArrayPartition<Element, rank> const& partition)
+        auto all(hpx::id_type const locality_id, ArrayPartition<Element, rank> const& partition)
+            -> Scalar<Element>
         {
             using Policies = policy::all::DefaultValuePolicies<Element>;
 
diff --git a/source/framework/algorithm/include/lue/framework/algorithm/value_policies/close_to.hpp b/source/framework/algorithm/include/lue/framework/algorithm/value_policies/close_to.hpp
index 96b6fc507..f9d2900c6 100644
--- a/source/framework/algorithm/include/lue/framework/algorithm/value_policies/close_to.hpp
+++ b/source/framework/algorithm/include/lue/framework/algorithm/value_policies/close_to.hpp
@@ -16,7 +16,7 @@ namespace lue {
 
     namespace value_policies {
 
-        LUE_BINARY_LOCAL_OPERATION_OVERLOADS2(
+        LUE_BINARY_LOCAL_OPERATION_OVERLOADS_WITHOUT_POLICIES(
             close_to, detail::CloseTo, policy::close_to::DefaultValuePolicies)
 
     }  // namespace value_policies
diff --git a/source/framework/algorithm/include/lue/framework/algorithm/value_policies/divide.hpp b/source/framework/algorithm/include/lue/framework/algorithm/value_policies/divide.hpp
index 433833300..76b1f692a 100644
--- a/source/framework/algorithm/include/lue/framework/algorithm/value_policies/divide.hpp
+++ b/source/framework/algorithm/include/lue/framework/algorithm/value_policies/divide.hpp
@@ -37,7 +37,8 @@ namespace lue {
 
     namespace value_policies {
 
-        LUE_BINARY_LOCAL_OPERATION_OVERLOADS2(divide, detail::Divide, policy::divide::DefaultValuePolicies)
+        LUE_BINARY_LOCAL_OPERATION_OVERLOADS_WITHOUT_POLICIES(
+            divide, detail::Divide, policy::divide::DefaultValuePolicies)
         LUE_BINARY_ARITHMETIC_OPERATOR(/, divide)
 
     }  // namespace value_policies
diff --git a/source/framework/algorithm/include/lue/framework/algorithm/value_policies/equal_to.hpp b/source/framework/algorithm/include/lue/framework/algorithm/value_policies/equal_to.hpp
index 066681cab..f53ed44d5 100644
--- a/source/framework/algorithm/include/lue/framework/algorithm/value_policies/equal_to.hpp
+++ b/source/framework/algorithm/include/lue/framework/algorithm/value_policies/equal_to.hpp
@@ -42,7 +42,7 @@ namespace lue {
         }
 
 
-        LUE_BINARY_LOCAL_OPERATION_OVERLOADS2(
+        LUE_BINARY_LOCAL_OPERATION_OVERLOADS_WITHOUT_POLICIES(
             equal_to, detail::EqualTo, policy::equal_to::DefaultValuePolicies)
         LUE_BINARY_COMPARISON_OPERATOR(==, equal_to)
 
diff --git a/source/framework/algorithm/include/lue/framework/algorithm/value_policies/greater_than.hpp b/source/framework/algorithm/include/lue/framework/algorithm/value_policies/greater_than.hpp
index d1a95ea9d..7909f70fb 100644
--- a/source/framework/algorithm/include/lue/framework/algorithm/value_policies/greater_than.hpp
+++ b/source/framework/algorithm/include/lue/framework/algorithm/value_policies/greater_than.hpp
@@ -16,7 +16,7 @@ namespace lue {
 
     namespace value_policies {
 
-        LUE_BINARY_LOCAL_OPERATION_OVERLOADS2(
+        LUE_BINARY_LOCAL_OPERATION_OVERLOADS_WITHOUT_POLICIES(
             greater_than, detail::GreaterThan, policy::greater_than::DefaultValuePolicies)
         LUE_BINARY_COMPARISON_OPERATOR(>, greater_than)
 
diff --git a/source/framework/algorithm/include/lue/framework/algorithm/value_policies/greater_than_equal_to.hpp b/source/framework/algorithm/include/lue/framework/algorithm/value_policies/greater_than_equal_to.hpp
index c4a1ac3ab..eba01bf58 100644
--- a/source/framework/algorithm/include/lue/framework/algorithm/value_policies/greater_than_equal_to.hpp
+++ b/source/framework/algorithm/include/lue/framework/algorithm/value_policies/greater_than_equal_to.hpp
@@ -16,7 +16,7 @@ namespace lue {
 
     namespace value_policies {
 
-        LUE_BINARY_LOCAL_OPERATION_OVERLOADS2(
+        LUE_BINARY_LOCAL_OPERATION_OVERLOADS_WITHOUT_POLICIES(
             greater_than_equal_to,
             detail::GreaterThanEqualTo,
             policy::greater_than_equal_to::DefaultValuePolicies)
diff --git a/source/framework/algorithm/include/lue/framework/algorithm/value_policies/less_than.hpp b/source/framework/algorithm/include/lue/framework/algorithm/value_policies/less_than.hpp
index e35a2a38a..4bfecee86 100644
--- a/source/framework/algorithm/include/lue/framework/algorithm/value_policies/less_than.hpp
+++ b/source/framework/algorithm/include/lue/framework/algorithm/value_policies/less_than.hpp
@@ -16,7 +16,7 @@ namespace lue {
 
     namespace value_policies {
 
-        LUE_BINARY_LOCAL_OPERATION_OVERLOADS2(
+        LUE_BINARY_LOCAL_OPERATION_OVERLOADS_WITHOUT_POLICIES(
             less_than, detail::LessThan, policy::less_than::DefaultValuePolicies)
         LUE_BINARY_COMPARISON_OPERATOR(<, less_than)
 
diff --git a/source/framework/algorithm/include/lue/framework/algorithm/value_policies/less_than_equal_to.hpp b/source/framework/algorithm/include/lue/framework/algorithm/value_policies/less_than_equal_to.hpp
index 96067e1e3..b625530eb 100644
--- a/source/framework/algorithm/include/lue/framework/algorithm/value_policies/less_than_equal_to.hpp
+++ b/source/framework/algorithm/include/lue/framework/algorithm/value_policies/less_than_equal_to.hpp
@@ -16,7 +16,7 @@ namespace lue {
 
     namespace value_policies {
 
-        LUE_BINARY_LOCAL_OPERATION_OVERLOADS2(
+        LUE_BINARY_LOCAL_OPERATION_OVERLOADS_WITHOUT_POLICIES(
             less_than_equal_to, detail::LessThanEqualTo, policy::less_than_equal_to::DefaultValuePolicies)
         LUE_BINARY_COMPARISON_OPERATOR(<=, less_than_equal_to)
 
diff --git a/source/framework/algorithm/include/lue/framework/algorithm/value_policies/logical_and.hpp b/source/framework/algorithm/include/lue/framework/algorithm/value_policies/logical_and.hpp
index ef8054073..6d70297f7 100644
--- a/source/framework/algorithm/include/lue/framework/algorithm/value_policies/logical_and.hpp
+++ b/source/framework/algorithm/include/lue/framework/algorithm/value_policies/logical_and.hpp
@@ -17,7 +17,7 @@ namespace lue {
 
     namespace value_policies {
 
-        LUE_BINARY_LOCAL_OPERATION_OVERLOADS2(
+        LUE_BINARY_LOCAL_OPERATION_OVERLOADS_WITHOUT_POLICIES(
             logical_and, detail::LogicalAnd, policy::logical_and::DefaultValuePolicies)
         LUE_BINARY_LOGICAL_OPERATOR(&&, logical_and)
 
diff --git a/source/framework/algorithm/include/lue/framework/algorithm/value_policies/logical_exclusive_or.hpp b/source/framework/algorithm/include/lue/framework/algorithm/value_policies/logical_exclusive_or.hpp
index c0c47f74e..3eb22b213 100644
--- a/source/framework/algorithm/include/lue/framework/algorithm/value_policies/logical_exclusive_or.hpp
+++ b/source/framework/algorithm/include/lue/framework/algorithm/value_policies/logical_exclusive_or.hpp
@@ -17,7 +17,7 @@ namespace lue {
 
     namespace value_policies {
 
-        LUE_BINARY_LOCAL_OPERATION_OVERLOADS2(
+        LUE_BINARY_LOCAL_OPERATION_OVERLOADS_WITHOUT_POLICIES(
             logical_exclusive_or,
             detail::LogicalExclusiveOr,
             policy::logical_exclusive_or::DefaultValuePolicies)
diff --git a/source/framework/algorithm/include/lue/framework/algorithm/value_policies/logical_inclusive_or.hpp b/source/framework/algorithm/include/lue/framework/algorithm/value_policies/logical_inclusive_or.hpp
index eae0967cf..76f6beb58 100644
--- a/source/framework/algorithm/include/lue/framework/algorithm/value_policies/logical_inclusive_or.hpp
+++ b/source/framework/algorithm/include/lue/framework/algorithm/value_policies/logical_inclusive_or.hpp
@@ -17,7 +17,7 @@ namespace lue {
 
     namespace value_policies {
 
-        LUE_BINARY_LOCAL_OPERATION_OVERLOADS2(
+        LUE_BINARY_LOCAL_OPERATION_OVERLOADS_WITHOUT_POLICIES(
             logical_inclusive_or,
             detail::LogicalInclusiveOr,
             policy::logical_inclusive_or::DefaultValuePolicies)
diff --git a/source/framework/algorithm/include/lue/framework/algorithm/value_policies/maximum.hpp b/source/framework/algorithm/include/lue/framework/algorithm/value_policies/maximum.hpp
index c60f0fdf5..ed70de409 100644
--- a/source/framework/algorithm/include/lue/framework/algorithm/value_policies/maximum.hpp
+++ b/source/framework/algorithm/include/lue/framework/algorithm/value_policies/maximum.hpp
@@ -17,7 +17,7 @@ namespace lue {
     namespace value_policies {
 
         template<typename Element, Rank rank>
-        hpx::future<Element> maximum(PartitionedArray<Element, rank> const& array)
+        auto maximum(PartitionedArray<Element, rank> const& array) -> Scalar<Element>
         {
             using Policies = policy::maximum::DefaultValuePolicies<Element>;
 
diff --git a/source/framework/algorithm/include/lue/framework/algorithm/value_policies/minimum.hpp b/source/framework/algorithm/include/lue/framework/algorithm/value_policies/minimum.hpp
index 4fe1f0052..6ea8f5f7f 100644
--- a/source/framework/algorithm/include/lue/framework/algorithm/value_policies/minimum.hpp
+++ b/source/framework/algorithm/include/lue/framework/algorithm/value_policies/minimum.hpp
@@ -17,7 +17,7 @@ namespace lue {
     namespace value_policies {
 
         template<typename Element, Rank rank>
-        hpx::future<Element> minimum(PartitionedArray<Element, rank> const& array)
+        auto minimum(PartitionedArray<Element, rank> const& array) -> Scalar<Element>
         {
             using Policies = policy::minimum::DefaultValuePolicies<Element>;
 
diff --git a/source/framework/algorithm/include/lue/framework/algorithm/value_policies/multiply.hpp b/source/framework/algorithm/include/lue/framework/algorithm/value_policies/multiply.hpp
index c1230436b..6394a7270 100644
--- a/source/framework/algorithm/include/lue/framework/algorithm/value_policies/multiply.hpp
+++ b/source/framework/algorithm/include/lue/framework/algorithm/value_policies/multiply.hpp
@@ -37,7 +37,7 @@ namespace lue {
 
     namespace value_policies {
 
-        LUE_BINARY_LOCAL_OPERATION_OVERLOADS2(
+        LUE_BINARY_LOCAL_OPERATION_OVERLOADS_WITHOUT_POLICIES(
             multiply, detail::Multiply, policy::multiply::DefaultValuePolicies)
         LUE_BINARY_ARITHMETIC_OPERATOR(*, multiply)
 
diff --git a/source/framework/algorithm/include/lue/framework/algorithm/value_policies/none.hpp b/source/framework/algorithm/include/lue/framework/algorithm/value_policies/none.hpp
index 0dd3208cf..21c405f42 100644
--- a/source/framework/algorithm/include/lue/framework/algorithm/value_policies/none.hpp
+++ b/source/framework/algorithm/include/lue/framework/algorithm/value_policies/none.hpp
@@ -17,7 +17,7 @@ namespace lue {
     namespace value_policies {
 
         template<typename Element, Rank rank>
-        hpx::future<Element> none(PartitionedArray<Element, rank> const& array)
+        auto none(PartitionedArray<Element, rank> const& array) -> Scalar<Element>
         {
             using Functor = detail::None<Element>;
             using Policies = policy::none::DefaultValuePolicies<Element>;
diff --git a/source/framework/algorithm/include/lue/framework/algorithm/value_policies/not_equal_to.hpp b/source/framework/algorithm/include/lue/framework/algorithm/value_policies/not_equal_to.hpp
index 571f5cc05..26d282d12 100644
--- a/source/framework/algorithm/include/lue/framework/algorithm/value_policies/not_equal_to.hpp
+++ b/source/framework/algorithm/include/lue/framework/algorithm/value_policies/not_equal_to.hpp
@@ -16,7 +16,7 @@ namespace lue {
 
     namespace value_policies {
 
-        LUE_BINARY_LOCAL_OPERATION_OVERLOADS2(
+        LUE_BINARY_LOCAL_OPERATION_OVERLOADS_WITHOUT_POLICIES(
             not_equal_to, detail::NotEqualTo, policy::not_equal_to::DefaultValuePolicies)
         LUE_BINARY_COMPARISON_OPERATOR(!=, not_equal_to)
 
diff --git a/source/framework/algorithm/include/lue/framework/algorithm/value_policies/subtract.hpp b/source/framework/algorithm/include/lue/framework/algorithm/value_policies/subtract.hpp
index 46ee50924..7ca2d40c6 100644
--- a/source/framework/algorithm/include/lue/framework/algorithm/value_policies/subtract.hpp
+++ b/source/framework/algorithm/include/lue/framework/algorithm/value_policies/subtract.hpp
@@ -37,7 +37,7 @@ namespace lue {
 
     namespace value_policies {
 
-        LUE_BINARY_LOCAL_OPERATION_OVERLOADS2(
+        LUE_BINARY_LOCAL_OPERATION_OVERLOADS_WITHOUT_POLICIES(
             subtract, detail::Subtract, policy::subtract::DefaultValuePolicies)
         LUE_BINARY_ARITHMETIC_OPERATOR(-, subtract)
 
diff --git a/source/framework/algorithm/include/lue/framework/algorithm/value_policies/sum.hpp b/source/framework/algorithm/include/lue/framework/algorithm/value_policies/sum.hpp
index ff8b51647..d917e1d64 100644
--- a/source/framework/algorithm/include/lue/framework/algorithm/value_policies/sum.hpp
+++ b/source/framework/algorithm/include/lue/framework/algorithm/value_policies/sum.hpp
@@ -17,7 +17,7 @@ namespace lue {
     namespace value_policies {
 
         template<typename Element, Rank rank>
-        auto sum(PartitionedArray<Element, rank> const& array) -> hpx::future<Element>
+        auto sum(PartitionedArray<Element, rank> const& array) -> Scalar<Element>
         {
             using Policies = policy::sum::DefaultValuePolicies<Element>;
 
diff --git a/source/framework/algorithm/include/lue/framework/algorithm/value_policies/unique.hpp b/source/framework/algorithm/include/lue/framework/algorithm/value_policies/unique.hpp
index cb72b837c..834285405 100644
--- a/source/framework/algorithm/include/lue/framework/algorithm/value_policies/unique.hpp
+++ b/source/framework/algorithm/include/lue/framework/algorithm/value_policies/unique.hpp
@@ -17,7 +17,7 @@ namespace lue {
     namespace value_policies {
 
         template<typename Element, Rank rank>
-        hpx::future<std::set<Element>> unique(PartitionedArray<Element, rank> const& array)
+        auto unique(PartitionedArray<Element, rank> const& array) -> hpx::future<std::set<Element>>
         {
             using Policies = policy::unique::DefaultValuePolicies<Element>;
 
diff --git a/source/framework/algorithm/include/lue/framework/algorithm/value_policies/where.hpp b/source/framework/algorithm/include/lue/framework/algorithm/value_policies/where.hpp
index bc8428fab..e65c0c33e 100644
--- a/source/framework/algorithm/include/lue/framework/algorithm/value_policies/where.hpp
+++ b/source/framework/algorithm/include/lue/framework/algorithm/value_policies/where.hpp
@@ -16,152 +16,180 @@ namespace lue {
 
     namespace value_policies {
 
+        // where(array, array, array)
         template<typename ConditionElement, typename Element, Rank rank>
-        PartitionedArray<Element, rank> where(
+        auto where(
             PartitionedArray<ConditionElement, rank> const& condition,
             PartitionedArray<Element, rank> const& true_array,
-            PartitionedArray<Element, rank> const& false_array)
+            PartitionedArray<Element, rank> const& false_array) -> PartitionedArray<Element, rank>
         {
-            // where(condition_array, true_array, false_array)
             using Policies = policy::where::DefaultValuePolicies<Element, ConditionElement, Element, Element>;
 
             return where(Policies{}, condition, true_array, false_array);
         }
 
 
+        // where(array, array, value_f)
         template<typename ConditionElement, typename Element, Rank rank>
-        PartitionedArray<Element, rank> where(
+        auto where(
             PartitionedArray<ConditionElement, rank> const& condition,
             PartitionedArray<Element, rank> const& true_array,
-            hpx::shared_future<Element> const false_value)
+            hpx::shared_future<Element> const& false_value_f) -> PartitionedArray<Element, rank>
         {
-            // where(condition_array, true_array, false_value_f)
             using Policies = policy::where::DefaultValuePolicies<Element, ConditionElement, Element, Element>;
 
-            return where(Policies{}, condition, true_array, false_value);
+            return where(Policies{}, condition, true_array, false_value_f);
         }
 
 
+        // where(array, value_f, array)
         template<typename ConditionElement, typename Element, Rank rank>
-        PartitionedArray<Element, rank> where(
+        auto where(
             PartitionedArray<ConditionElement, rank> const& condition,
-            hpx::shared_future<Element> const true_value,
-            PartitionedArray<Element, rank> const& false_array)
+            hpx::shared_future<Element> const& true_value_f,
+            PartitionedArray<Element, rank> const& false_array) -> PartitionedArray<Element, rank>
         {
-            // where(condition_array, true_value_f, false_array)
             using Policies = policy::where::DefaultValuePolicies<Element, ConditionElement, Element, Element>;
 
-            return where(Policies{}, condition, true_value, false_array);
+            return where(Policies{}, condition, true_value_f, false_array);
         }
 
 
+        // where(array, value_f, value_f)
         template<typename ConditionElement, typename Element, Rank rank>
-        PartitionedArray<Element, rank> where(
+        auto where(
             PartitionedArray<ConditionElement, rank> const& condition,
-            hpx::shared_future<Element> const true_value,
-            hpx::shared_future<Element> const false_value)
+            hpx::shared_future<Element> const& true_value_f,
+            hpx::shared_future<Element> const& false_value_f) -> PartitionedArray<Element, rank>
         {
-            // where(condition_array, true_value_f, false_value_f)
             using Policies = policy::where::DefaultValuePolicies<Element, ConditionElement, Element, Element>;
 
-            return where(Policies{}, condition, true_value, false_value);
+            return where(Policies{}, condition, true_value_f, false_value_f);
         }
 
 
+        // where(array, array, scalar)
         template<typename ConditionElement, typename Element, Rank rank>
-        PartitionedArray<Element, rank> where(
+        auto where(
             PartitionedArray<ConditionElement, rank> const& condition,
             PartitionedArray<Element, rank> const& true_array,
-            Element const false_value)
+            Scalar<Element> const& false_scalar) -> PartitionedArray<Element, rank>
         {
-            // where(condition_array, true_array, false_value)
-            return where(condition, true_array, hpx::make_ready_future<Element>(false_value).share());
+            using Policies = policy::where::DefaultValuePolicies<Element, ConditionElement, Element, Element>;
+
+            return where(Policies{}, condition, true_array, false_scalar);
         }
 
 
-        template<typename Policies, typename ConditionElement, typename Element, Rank rank>
-        PartitionedArray<Element, rank> where(
-            Policies const& policies,
+        // where(array, scalar, array)
+        template<typename ConditionElement, typename Element, Rank rank>
+        auto where(
             PartitionedArray<ConditionElement, rank> const& condition,
-            Element const true_value,
-            PartitionedArray<Element, rank> const& false_array)
+            Scalar<Element> const& true_scalar,
+            PartitionedArray<Element, rank> const& false_array) -> PartitionedArray<Element, rank>
         {
-            // where(policies, condition_array, true_value, false_array)
-            return where(
-                policies, condition, hpx::make_ready_future<Element>(true_value).share(), false_array);
+            using Policies = policy::where::DefaultValuePolicies<Element, ConditionElement, Element, Element>;
+
+            return where(Policies{}, condition, true_scalar, false_array);
         }
 
 
+        // where(array, scalar, scalar)
         template<typename ConditionElement, typename Element, Rank rank>
-        PartitionedArray<Element, rank> where(
+        auto where(
             PartitionedArray<ConditionElement, rank> const& condition,
-            Element const true_value,
-            PartitionedArray<Element, rank> const& false_array)
+            Scalar<Element> const& true_scalar,
+            Scalar<Element> const& false_scalar) -> PartitionedArray<Element, rank>
         {
-            // where(condition_array, true_value, false_array)
-            return where(condition, hpx::make_ready_future<Element>(true_value).share(), false_array);
+            using Policies = policy::where::DefaultValuePolicies<Element, ConditionElement, Element, Element>;
+
+            return where(Policies{}, condition, true_scalar, false_scalar);
         }
 
 
-        template<typename Policies, typename ConditionElement, typename Element, Rank rank>
-        PartitionedArray<Element, rank> where(
-            Policies const& policies,
+        // where(array, array, value)
+        template<typename ConditionElement, typename Element, Rank rank>
+        auto where(
+            PartitionedArray<ConditionElement, rank> const& condition,
+            PartitionedArray<Element, rank> const& true_array,
+            Element const false_value) -> PartitionedArray<Element, rank>
+        {
+            using Policies = policy::where::DefaultValuePolicies<Element, ConditionElement, Element, Element>;
+
+            return where(Policies{}, condition, true_array, false_value);
+        }
+
+
+        // where(array, value, array)
+        template<typename ConditionElement, typename Element, Rank rank>
+        auto where(
             PartitionedArray<ConditionElement, rank> const& condition,
             Element const true_value,
-            Element const false_value)
+            PartitionedArray<Element, rank> const& false_array) -> PartitionedArray<Element, rank>
         {
-            // where(policies, condition_array, true_value, false_value)
-            return where(
-                policies,
-                condition,
-                hpx::make_ready_future<Element>(true_value).share(),
-                hpx::make_ready_future<Element>(false_value).share());
+            using Policies = policy::where::DefaultValuePolicies<Element, ConditionElement, Element, Element>;
+
+            return where(Policies{}, condition, true_value, false_array);
         }
 
 
+        // where(array, value, value)
         template<typename ConditionElement, typename Element, Rank rank>
-        PartitionedArray<Element, rank> where(
+        auto where(
             PartitionedArray<ConditionElement, rank> const& condition,
             Element const true_value,
-            Element const false_value)
+            Element const false_value) -> PartitionedArray<Element, rank>
         {
-            // where(condition_array, true_value, false_value)
-            return where(
-                condition,
-                hpx::make_ready_future<Element>(true_value).share(),
-                hpx::make_ready_future<Element>(false_value).share());
+            using Policies = policy::where::DefaultValuePolicies<Element, ConditionElement, Element, Element>;
+
+            return where(Policies{}, condition, true_value, false_value);
         }
 
 
+        // ---------------------------------------------------------------------
+
+
+        // where(array, array)
         template<typename ConditionElement, typename Element, Rank rank>
-        PartitionedArray<Element, rank> where(
+        auto where(
             PartitionedArray<ConditionElement, rank> const& condition,
-            PartitionedArray<Element, rank> const& true_array)
+            PartitionedArray<Element, rank> const& true_array) -> PartitionedArray<Element, rank>
         {
-            // where(condition_array, true_array)
             using Policies = policy::where::DefaultValuePolicies<Element, ConditionElement, Element>;
 
             return where(Policies{}, condition, true_array);
         }
 
 
+        // where(array, value_f)
         template<typename ConditionElement, typename Element, Rank rank>
-        PartitionedArray<Element, rank> where(
+        auto where(
             PartitionedArray<ConditionElement, rank> const& condition,
-            hpx::shared_future<Element> const true_value)
+            hpx::shared_future<Element> const& true_value_f) -> PartitionedArray<Element, rank>
         {
-            // where(condition_array, true_value_f)
             using Policies = policy::where::DefaultValuePolicies<Element, ConditionElement, Element>;
 
-            return where(Policies{}, condition, true_value);
+            return where(Policies{}, condition, true_value_f);
+        }
+
+
+        // where(array, scalar)
+        template<typename ConditionElement, typename Element, Rank rank>
+        auto where(
+            PartitionedArray<ConditionElement, rank> const& condition, Scalar<Element> const& true_scalar)
+            -> PartitionedArray<Element, rank>
+        {
+            using Policies = policy::where::DefaultValuePolicies<Element, ConditionElement, Element>;
+
+            return where(Policies{}, condition, true_scalar);
         }
 
 
+        // where(array, value)
         template<typename ConditionElement, typename Element, Rank rank>
-        PartitionedArray<Element, rank> where(
-            PartitionedArray<ConditionElement, rank> const& condition, Element const true_value)
+        auto where(PartitionedArray<ConditionElement, rank> const& condition, Element const true_value)
+            -> PartitionedArray<Element, rank>
         {
-            // where(condition_array, true_value)
             using Policies = policy::where::DefaultValuePolicies<Element, ConditionElement, Element>;
 
             return where(Policies{}, condition, true_value);
diff --git a/source/framework/algorithm/include/lue/framework/algorithm/where.hpp b/source/framework/algorithm/include/lue/framework/algorithm/where.hpp
index 921912115..ced248d05 100644
--- a/source/framework/algorithm/include/lue/framework/algorithm/where.hpp
+++ b/source/framework/algorithm/include/lue/framework/algorithm/where.hpp
@@ -1,5 +1,6 @@
 #pragma once
 #include "lue/framework/algorithm/policy.hpp"
+#include "lue/framework/algorithm/scalar.hpp"
 #include "lue/framework/partitioned_array.hpp"
 
 
@@ -12,9 +13,9 @@ namespace lue {
 
             public:
 
-                static constexpr bool within_domain(
+                static constexpr auto within_domain(
                     [[maybe_unused]] ConditionElement const condition,
-                    ExpressionElement const... expression) noexcept
+                    ExpressionElement const... expression) noexcept -> bool
                 {
                     if constexpr (sizeof...(expression) == 1)
                     {
@@ -35,74 +36,151 @@ namespace lue {
     }  // namespace policy::where
 
 
+    // where(policies, array, array, array)
     template<typename Policies, typename ConditionElement, typename Element, Rank rank>
-    PartitionedArray<Element, rank> where(
+    auto where(
         Policies const& policies,
         PartitionedArray<ConditionElement, rank> const& condition,
         PartitionedArray<Element, rank> const& true_array,
-        PartitionedArray<Element, rank> const& false_array);
+        PartitionedArray<Element, rank> const& false_array) -> PartitionedArray<Element, rank>;
+
+    // where(policies, array, array, value_f)
+    template<typename Policies, typename ConditionElement, typename Element, Rank rank>
+    auto where(
+        Policies const& policies,
+        PartitionedArray<ConditionElement, rank> const& condition,
+        PartitionedArray<Element, rank> const& true_array,
+        hpx::shared_future<Element> const& false_value_f) -> PartitionedArray<Element, rank>;
+
+    // where(policies, array, value_f, array)
+    template<typename Policies, typename ConditionElement, typename Element, Rank rank>
+    auto where(
+        Policies const& policies,
+        PartitionedArray<ConditionElement, rank> const& condition,
+        hpx::shared_future<Element> const& true_value_f,
+        PartitionedArray<Element, rank> const& false_array) -> PartitionedArray<Element, rank>;
+
+    // where(policies, array, value_f, value_f)
+    template<typename Policies, typename ConditionElement, typename Element, Rank rank>
+    auto where(
+        Policies const& policies,
+        PartitionedArray<ConditionElement, rank> const& condition,
+        hpx::shared_future<Element> const& true_value_f,
+        hpx::shared_future<Element> const& false_value_f) -> PartitionedArray<Element, rank>;
 
 
+    // where(policies, array, array, scalar)
     template<typename Policies, typename ConditionElement, typename Element, Rank rank>
-    PartitionedArray<Element, rank> where(
+    auto where(
         Policies const& policies,
         PartitionedArray<ConditionElement, rank> const& condition,
         PartitionedArray<Element, rank> const& true_array,
-        hpx::shared_future<Element> const false_value);
+        Scalar<Element> const& false_scalar) -> PartitionedArray<Element, rank>
+    {
+        return where(policies, condition, true_array, false_scalar.future());
+    }
 
 
+    // where(policies, array, scalar, array)
     template<typename Policies, typename ConditionElement, typename Element, Rank rank>
-    PartitionedArray<Element, rank> where(
+    auto where(
         Policies const& policies,
         PartitionedArray<ConditionElement, rank> const& condition,
-        hpx::shared_future<Element> const true_value,
-        PartitionedArray<Element, rank> const& false_array);
+        Scalar<Element> const& true_scalar,
+        PartitionedArray<Element, rank> const& false_array) -> PartitionedArray<Element, rank>
+    {
+        return where(policies, condition, true_scalar.future(), false_array);
+    }
 
 
+    // where(policies, array, scalar, scalar)
     template<typename Policies, typename ConditionElement, typename Element, Rank rank>
-    PartitionedArray<Element, rank> where(
+    auto where(
         Policies const& policies,
         PartitionedArray<ConditionElement, rank> const& condition,
-        hpx::shared_future<Element> const true_value,
-        hpx::shared_future<Element> const false_value);
+        Scalar<Element> const& true_scalar,
+        Scalar<Element> const& false_scalar) -> PartitionedArray<Element, rank>
+    {
+        return where(policies, condition, true_scalar.future(), false_scalar.future());
+    }
 
 
+    // where(policies, array, array, value)
     template<typename Policies, typename ConditionElement, typename Element, Rank rank>
-    PartitionedArray<Element, rank> where(
+    auto where(
         Policies const& policies,
         PartitionedArray<ConditionElement, rank> const& condition,
         PartitionedArray<Element, rank> const& true_array,
-        Element const false_value)
+        Element const false_value) -> PartitionedArray<Element, rank>
     {
-        // where(policies, condition_array, true_array, false_value)
         return where(policies, condition, true_array, hpx::make_ready_future<Element>(false_value).share());
     }
 
 
+    // where(policies, array, value, array)
+    template<typename Policies, typename ConditionElement, typename Element, Rank rank>
+    auto where(
+        Policies const& policies,
+        PartitionedArray<ConditionElement, rank> const& condition,
+        Element const true_value,
+        PartitionedArray<Element, rank> const& false_array) -> PartitionedArray<Element, rank>
+    {
+        return where(policies, condition, hpx::make_ready_future<Element>(true_value).share(), false_array);
+    }
+
+
+    // where(policies, array, value, value)
+    template<typename Policies, typename ConditionElement, typename Element, Rank rank>
+    auto where(
+        Policies const& policies,
+        PartitionedArray<ConditionElement, rank> const& condition,
+        Element const true_value,
+        Element const false_value) -> PartitionedArray<Element, rank>
+    {
+        return where(
+            policies,
+            condition,
+            hpx::make_ready_future<Element>(true_value).share(),
+            hpx::make_ready_future<Element>(false_value).share());
+    }
+
+
     // -----------------------------------------------------------------------------
 
 
+    // where(policies, array, array)
     template<typename Policies, typename ConditionElement, typename Element, Rank rank>
-    PartitionedArray<Element, rank> where(
+    auto where(
         Policies const& policies,
         PartitionedArray<ConditionElement, rank> const& condition,
-        PartitionedArray<Element, rank> const& true_array);
+        PartitionedArray<Element, rank> const& true_array) -> PartitionedArray<Element, rank>;
+
+    // where(policies, array, value_f)
+    template<typename Policies, typename ConditionElement, typename Element, Rank rank>
+    auto where(
+        Policies const& policies,
+        PartitionedArray<ConditionElement, rank> const& condition,
+        hpx::shared_future<Element> const& true_value_f) -> PartitionedArray<Element, rank>;
 
 
+    // where(policies, array, scalar)
     template<typename Policies, typename ConditionElement, typename Element, Rank rank>
-    PartitionedArray<Element, rank> where(
+    auto where(
         Policies const& policies,
         PartitionedArray<ConditionElement, rank> const& condition,
-        hpx::shared_future<Element> const true_value);
+        Scalar<Element> const true_scalar) -> PartitionedArray<Element, rank>
+    {
+        return where(policies, condition, true_scalar.future());
+    }
 
 
+    // where(policies, array, value)
     template<typename Policies, typename ConditionElement, typename Element, Rank rank>
-    PartitionedArray<Element, rank> where(
+    auto where(
         Policies const& policies,
         PartitionedArray<ConditionElement, rank> const& condition,
-        Element const true_value)
+        Element const true_value) -> PartitionedArray<Element, rank>
     {
-        // where(policies, condition_array, true_value)
         return where(policies, condition, hpx::make_ready_future<Element>(true_value).share());
     }
 
diff --git a/source/framework/algorithm/src/local_operation/add.cpp.in b/source/framework/algorithm/src/local_operation/add.cpp.in
index faca722f8..8a6ccea76 100644
--- a/source/framework/algorithm/src/local_operation/add.cpp.in
+++ b/source/framework/algorithm/src/local_operation/add.cpp.in
@@ -5,7 +5,7 @@
 
 namespace lue {
 
-    LUE_INSTANTIATE_BINARY_LOCAL_OPERATION2(
+    LUE_INSTANTIATE_BINARY_LOCAL_OPERATION(
             ESC(policy::add::{{ Policies }}<{{ Element }}, {{ Element }}>),
             {{ Element }},
             {{ Element }},
diff --git a/source/framework/api/cxx/doc/index.md b/source/framework/api/cxx/doc/index.md
index da0dc33df..d8aca9b3b 100644
--- a/source/framework/api/cxx/doc/index.md
+++ b/source/framework/api/cxx/doc/index.md
@@ -1,60 +1,9 @@
-- `create_array`
-    - Should it return a field, like currently, or an array?
-    - Compare to scalars. Although a scalar can be used to represent a field, some functions really require a
-      scalar to be passed. It doesn't make sense to pass anything else. It therefore is good if type info
-      keeps attached to variables as long as possible.
+# `lue_framework_api_cxx`
 
-1. Keep type info as long as possible
-1. Support easy conversion from specialized types to general types:
+<!--
+Parse error (Doxygen, Breathe, ...)
 
-    - scalar / array → field
-    - The other way around is not needed(?)
-    - Is this permanent? Maybe the specialized type is still needed?
-
-        - Can we store a variant in a variant and have the visit recurse to the leave type?
-        - `Field = variant<Array, Scalar, Literal>`
-        - Maybe have an overload ourselves that calls visit on the joint variant of any variants and concrete
-          types passed in
-
-          1. Define Field variant as a combinations of Array and Scalar variants, and concrete types
-          1. Before using a Field instance, `flatten` the Field variant type to a variant type that does not
-             contain nested variants. The API user use Field, Array, Scalar instances, but the algorithms use
-             concrete types. The C++ API must translate types from general to concrete and call the correct
-             overloads.
-
-- C++: automatic conversion(?)
-- Python: automatic conversion(?)
-- C:
-
-    - `auto scalar_as_field(scalar) -> Field`
-    - `auto array_as_field(array) -> Field`
-
-- How about the element type info? A scalar / array is still a family of concrete types.
-
-Don't mix:
-
-- construct / destruct
-- create / destroy
-- new / delete
-- alloc / free
-
-C++ variant types (Scalar, Array, ...) can be created using a `create_<variant_type>` function, returning an
-instance of that variant type.
-
-- Python: Use this function in the custom constructor of a class wrapper
-- C: Use this function from the C equivalent of the `create_<variant_type>` function
-- → Pro: no need for templates, single create function for given set of arguments
-
-Destruction happens in the destructor of the variant type:
-
-- Python: happens automatically
-- C: Call `destroy_<variant_type`, which can call `delete` on the layered opaque pointer
-
-20240710
-
-- Having different types for Literal, Scalar, Array, Field gets us into overload hell again. What about only
-  using Field instances and let overload resolution figure out what is supported (and document this so users
-  know what to expect).
-
-    - A field is a value that varies through time and over space, or not
-    - Some functions require a field's value to not vary
+```{eval-rst}
+.. doxygenfunction:: lue::api::add
+```
+-->
diff --git a/source/framework/api/cxx/doc/notes.md b/source/framework/api/cxx/doc/notes.md
new file mode 100644
index 000000000..309a1010c
--- /dev/null
+++ b/source/framework/api/cxx/doc/notes.md
@@ -0,0 +1,60 @@
+- `create_array`
+    - Should it return a field, like currently, or an array?
+    - Compare to scalars. Although a scalar can be used to represent a field, some functions really require a
+      scalar to be passed. It doesn't make sense to pass anything else. It therefore is good if type info
+      keeps attached to variables as long as possible.
+
+1. Keep type info as long as possible
+1. Support easy conversion from specialized types to general types:
+
+    - scalar / array → field
+    - The other way around is not needed(?)
+    - Is this permanent? Maybe the specialized type is still needed?
+
+        - Can we store a variant in a variant and have the visit recurse to the leave type?
+        - `Field = variant<Array, Scalar, Literal>`
+        - Maybe have an overload ourselves that calls visit on the joint variant of any variants and concrete
+          types passed in
+
+          1. Define Field variant as a combinations of Array and Scalar variants, and concrete types
+          1. Before using a Field instance, `flatten` the Field variant type to a variant type that does not
+             contain nested variants. The API user use Field, Array, Scalar instances, but the algorithms use
+             concrete types. The C++ API must translate types from general to concrete and call the correct
+             overloads.
+
+- C++: automatic conversion(?)
+- Python: automatic conversion(?)
+- C:
+
+    - `auto scalar_as_field(scalar) -> Field`
+    - `auto array_as_field(array) -> Field`
+
+- How about the element type info? A scalar / array is still a family of concrete types.
+
+Don't mix:
+
+- construct / destruct
+- create / destroy
+- new / delete
+- alloc / free
+
+C++ variant types (Scalar, Array, ...) can be created using a `create_<variant_type>` function, returning an
+instance of that variant type.
+
+- Python: Use this function in the custom constructor of a class wrapper
+- C: Use this function from the C equivalent of the `create_<variant_type>` function
+- Pro: no need for templates, single create function for given set of arguments
+
+Destruction happens in the destructor of the variant type:
+
+- Python: happens automatically
+- C: Call `destroy_<variant_type`, which can call `delete` on the layered opaque pointer
+
+20240710
+
+- Having different types for Literal, Scalar, Array, Field gets us into overload hell again. What about only
+  using Field instances and let overload resolution figure out what is supported (and document this so users
+  know what to expect).
+
+    - A field is a value that varies through time and over space, or not
+    - Some functions require a field's value to not vary
diff --git a/source/framework/api/doc/index.md b/source/framework/api/doc/index.md
index a75648d3d..5bde9b789 100644
--- a/source/framework/api/doc/index.md
+++ b/source/framework/api/doc/index.md
@@ -1,28 +1,34 @@
-# LUE API
+# `lue_framework_api`
 
-The API libraries provide easy to use, high-level access to low-level functionality. The cxx library provides
-a public API to use when writing C++ code that uses LUE functionality. For example, people interested in
-implementing a simulation model in C++ should first look at the functionality provided by this library. It
-hides a lot of the complexities of using the lower level libraries.
+The API libraries provide easy to use, high-level access to low-level functionality. The
+`lue_framework_api_cxx` library provides a public API to use when writing C++ code that uses LUE framework
+functionality. For example, people interested in implementing a simulation model in C++ should first look at
+the functionality provided by this library. It hides a lot of the complexities of using the lower level
+libraries. People interested in using C or Python can use the language wrappers provided by the
+`lue_framework_api_c` and `lue_framework_api_python` libraries, respectively.
 
-The python library provides an API to use when writing Python code that uses LUE functionality. It contains
-Python language wrappers around the public API of the cxx library. API libraries wrapping the public API of
-the cxx library for other languages (e.g.: Fortran, Java, Julia, Lua, R, Rust) can use the same approach.
+:::{note}
+If language bindings for other languages than C, C++, and Python (e.g. for Fortran, Java, Julia, Lua, R, Rust)
+interest you, you may want to [help us](#doc-contribute) adding them. Do
+[contact](https://lue.computationalgeography.org/) us if you want to discuss this.
+:::
 
 The idea of the setup of the API libraries is to collect all functionality required by multiple language
-wrapping APIs in the cxx library and make these language wrapper libraries as small as possible, containing
-only the language-specific wrapper code. The same holds for the documentation. Most documentation must be
-associated with the cxx library, and this should be understandable by users of bindings for other languages.
+wrapping APIs in the `lue_framework_api_cxx` library and make the language wrapper libraries as small as
+possible, containing only the language-specific wrapper code. The same holds for the documentation. Most
+documentation must be associated with the `lue_framework_api_cxx` library, and this should be understandable
+by users of bindings for other languages.
 
 
 ## Design
 
-The algorithms in the cxx library hide the fact that they are overloaded for different argument types. The
-algorithms and the types used in this library are of a higher abstraction level than the libraries they depend
-on. The Field type is a variant that can be represented by several concrete types, like a PartitionedArray or
-a Scalar. Algorithms translating fields accepts fields and forward the call to the concrete algorithm that
-supports the passed in concrete types. If no such algorithm exists, a general overload is called that will
-throw an overload error exception.
+The algorithms in the `lue_framework_api_cxx` library hide the fact that they are overloaded for different
+argument types. The algorithms and the types used in this library are of a higher abstraction level than the
+libraries they depend on. The Field type is a variant that can be represented by several concrete types, like
+a {cpp:class}`lue::PartitionedArray` or a {cpp:class}`lue::Scalar`. Algorithms translating fields accept fields and
+forward the call to the concrete algorithm overload that supports the passed in concrete types. If no such
+algorithm exists, a general overload is called that will throw an overload error exception.
 
-Using the algorithms from the cxx library makes life for the user a lot easier. The drawback for the user of
-the C++ API is that overload errors only surface at runtime, not at compile-time.
+Using the algorithms from the `lue_framework_api_cxx` library makes life for the user a lot easier. A (minor)
+drawback for the user of the API's of statically typed languages like C and C++ is that overload errors only
+surface at runtime, not at compile-time.
diff --git a/source/framework/core/doc/index.md b/source/framework/core/doc/index.md
new file mode 100644
index 000000000..ed8abfde5
--- /dev/null
+++ b/source/framework/core/doc/index.md
@@ -0,0 +1,5 @@
+# `lue_framework_core`
+
+```{eval-rst}
+.. doxygenclass:: lue::Scalar
+```
diff --git a/source/framework/core/include/lue/framework/core/type_traits.hpp b/source/framework/core/include/lue/framework/core/type_traits.hpp
index 964ba4a2d..0b44d46f5 100644
--- a/source/framework/core/include/lue/framework/core/type_traits.hpp
+++ b/source/framework/core/include/lue/framework/core/type_traits.hpp
@@ -22,7 +22,7 @@ namespace lue {
         /*!
             @brief      Primary template for traits of an array-like type
             @tparam     Array-like type
-            @todo       Rename to TypeTraits
+            @todo       Rename to TypeTraits (FieldTraits?)
 
             Specializations add traits that are relevant for the actual array-like
             type. Some of these traits are relevant for all array-like types
diff --git a/source/framework/partitioned_array/doc/index.md b/source/framework/partitioned_array/doc/index.md
index 90a4fd3fd..d6ae784cf 100644
--- a/source/framework/partitioned_array/doc/index.md
+++ b/source/framework/partitioned_array/doc/index.md
@@ -1,4 +1,4 @@
-# Partitioned array
+# `lue_framework_partitioned_array`
 
 ```{eval-rst}
 .. doxygenclass:: lue::PartitionedArray
diff --git a/source/framework/partitioned_route/doc/index.md b/source/framework/partitioned_route/doc/index.md
index 69eab1355..c4f675943 100644
--- a/source/framework/partitioned_route/doc/index.md
+++ b/source/framework/partitioned_route/doc/index.md
@@ -1,4 +1,4 @@
-# Partitioned route
+# `lue_framework_partitioned_route`
 
 ```{eval-rst}
 .. doxygenclass:: lue::SerialRoute
diff --git a/source/framework/python/CMakeLists.txt b/source/framework/python/CMakeLists.txt
index af125ac86..34eb98ffb 100644
--- a/source/framework/python/CMakeLists.txt
+++ b/source/framework/python/CMakeLists.txt
@@ -129,6 +129,7 @@ add_library(lue_py_framework SHARED
     src/core/partitioned_array_int64.cpp
     src/core/partitioned_array_float.cpp
     src/core/partitioned_array_double.cpp
+    src/core/scalar.cpp
     src/core/wait.cpp
 
     src/io/read_array.cpp
diff --git a/source/framework/python/include/lue/py/framework/algorithm/add.hpp b/source/framework/python/include/lue/py/framework/algorithm/add.hpp
index 9d14ec08a..0a2833061 100644
--- a/source/framework/python/include/lue/py/framework/algorithm/add.hpp
+++ b/source/framework/python/include/lue/py/framework/algorithm/add.hpp
@@ -5,7 +5,14 @@
 namespace lue::framework {
 
     template<typename Element, Rank rank, typename Argument1, typename Argument2>
-    PartitionedArray<Element, rank> add(Argument1 const& argument1, Argument2 const& argument2)
+    auto add(Argument1 const& argument1, Argument2 const& argument2) -> PartitionedArray<Element, rank>
+    {
+        return value_policies::add(argument1, argument2);
+    }
+
+
+    template<typename Element, typename Argument1, typename Argument2>
+    auto add(Argument1 const& argument1, Argument2 const& argument2) -> Scalar<Element>
     {
         return value_policies::add(argument1, argument2);
     }
diff --git a/source/framework/python/include/lue/py/framework/algorithm/all.hpp b/source/framework/python/include/lue/py/framework/algorithm/all.hpp
index bc4a048d6..ee0ee1863 100644
--- a/source/framework/python/include/lue/py/framework/algorithm/all.hpp
+++ b/source/framework/python/include/lue/py/framework/algorithm/all.hpp
@@ -5,9 +5,9 @@
 namespace lue::framework {
 
     template<typename Element, Rank rank>
-    hpx::shared_future<Element> all(PartitionedArray<Element, rank> const& array)
+    auto all(PartitionedArray<Element, rank> const& array) -> Scalar<Element>
     {
-        return value_policies::all(array).share();
+        return value_policies::all(array);
     }
 
 }  // namespace lue::framework
diff --git a/source/framework/python/include/lue/py/framework/algorithm/divide.hpp b/source/framework/python/include/lue/py/framework/algorithm/divide.hpp
index c006dbeaf..49d86c284 100644
--- a/source/framework/python/include/lue/py/framework/algorithm/divide.hpp
+++ b/source/framework/python/include/lue/py/framework/algorithm/divide.hpp
@@ -5,7 +5,14 @@
 namespace lue::framework {
 
     template<typename Element, Rank rank, typename Argument1, typename Argument2>
-    PartitionedArray<Element, rank> divide(Argument1 const& argument1, Argument2 const& argument2)
+    auto divide(Argument1 const& argument1, Argument2 const& argument2) -> PartitionedArray<Element, rank>
+    {
+        return value_policies::divide(argument1, argument2);
+    }
+
+
+    template<typename Element, typename Argument1, typename Argument2>
+    auto divide(Argument1 const& argument1, Argument2 const& argument2) -> Scalar<Element>
     {
         return value_policies::divide(argument1, argument2);
     }
diff --git a/source/framework/python/include/lue/py/framework/algorithm/multiply.hpp b/source/framework/python/include/lue/py/framework/algorithm/multiply.hpp
index 1cdf79074..2de8243d2 100644
--- a/source/framework/python/include/lue/py/framework/algorithm/multiply.hpp
+++ b/source/framework/python/include/lue/py/framework/algorithm/multiply.hpp
@@ -5,7 +5,14 @@
 namespace lue::framework {
 
     template<typename Element, Rank rank, typename Argument1, typename Argument2>
-    PartitionedArray<Element, rank> multiply(Argument1 const& argument1, Argument2 const& argument2)
+    auto multiply(Argument1 const& argument1, Argument2 const& argument2) -> PartitionedArray<Element, rank>
+    {
+        return value_policies::multiply(argument1, argument2);
+    }
+
+
+    template<typename Element, typename Argument1, typename Argument2>
+    auto multiply(Argument1 const& argument1, Argument2 const& argument2) -> Scalar<Element>
     {
         return value_policies::multiply(argument1, argument2);
     }
diff --git a/source/framework/python/include/lue/py/framework/algorithm/pow.hpp b/source/framework/python/include/lue/py/framework/algorithm/pow.hpp
index 3aa14da23..b3eaca700 100644
--- a/source/framework/python/include/lue/py/framework/algorithm/pow.hpp
+++ b/source/framework/python/include/lue/py/framework/algorithm/pow.hpp
@@ -5,11 +5,18 @@
 namespace lue::framework {
 
     template<typename Element, Rank rank, typename Argument1, typename Argument2>
-    PartitionedArray<Element, rank> pow(Argument1 const& argument1, Argument2 const& argument2)
+    auto pow(Argument1 const& argument1, Argument2 const& argument2) -> PartitionedArray<Element, rank>
     {
         using Policies = policy::pow::DefaultValuePolicies<Element, Element>;
 
         return pow(Policies{}, argument1, argument2);
     }
 
+
+    template<typename Element, typename Argument1, typename Argument2>
+    auto pow(Argument1 const& argument1, Argument2 const& argument2) -> Scalar<Element>
+    {
+        return value_policies::pow(argument1, argument2);
+    }
+
 }  // namespace lue::framework
diff --git a/source/framework/python/include/lue/py/framework/algorithm/subtract.hpp b/source/framework/python/include/lue/py/framework/algorithm/subtract.hpp
index 54288a30e..be9d8342b 100644
--- a/source/framework/python/include/lue/py/framework/algorithm/subtract.hpp
+++ b/source/framework/python/include/lue/py/framework/algorithm/subtract.hpp
@@ -5,7 +5,14 @@
 namespace lue::framework {
 
     template<typename Element, Rank rank, typename Argument1, typename Argument2>
-    PartitionedArray<Element, rank> subtract(Argument1 const& argument1, Argument2 const& argument2)
+    auto subtract(Argument1 const& argument1, Argument2 const& argument2) -> PartitionedArray<Element, rank>
+    {
+        return value_policies::subtract(argument1, argument2);
+    }
+
+
+    template<typename Element, typename Argument1, typename Argument2>
+    auto subtract(Argument1 const& argument1, Argument2 const& argument2) -> Scalar<Element>
     {
         return value_policies::subtract(argument1, argument2);
     }
diff --git a/source/framework/python/include/lue/py/framework/core/partitioned_array.hpp b/source/framework/python/include/lue/py/framework/core/partitioned_array.hpp
index f7303d05f..89cfac8d8 100644
--- a/source/framework/python/include/lue/py/framework/core/partitioned_array.hpp
+++ b/source/framework/python/include/lue/py/framework/core/partitioned_array.hpp
@@ -46,7 +46,7 @@ namespace lue::framework {
         namespace lfr = lue::framework;
 
         using Array = PartitionedArray<Element, rank>;
-        using ElementF = hpx::shared_future<Element>;
+        using Scalar = Scalar<Element>;
 
         auto class_ =
             pybind11::class_<Array>(
@@ -124,7 +124,7 @@ namespace lue::framework {
                     pybind11::is_operator())
                 .def(
                     "__lt__",
-                    [](Array const& argument1, ElementF const& argument2)
+                    [](Array const& argument1, Scalar const& argument2)
                     { return lfr::less_than<ElementT<Array>, std::uint8_t, rank>(argument1, argument2); },
                     pybind11::is_operator())
 
@@ -145,7 +145,7 @@ namespace lue::framework {
                     pybind11::is_operator())
                 .def(
                     "__le__",
-                    [](Array const& argument1, ElementF const& argument2) {
+                    [](Array const& argument1, Scalar const& argument2) {
                         return lfr::less_than_equal_to<ElementT<Array>, std::uint8_t, rank>(
                             argument1, argument2);
                     },
@@ -164,7 +164,7 @@ namespace lue::framework {
                     pybind11::is_operator())
                 .def(
                     "__eq__",
-                    [](Array const& argument1, ElementF const& argument2)
+                    [](Array const& argument1, Scalar const& argument2)
                     { return lfr::equal_to<ElementT<Array>, std::uint8_t, rank>(argument1, argument2); },
                     pybind11::is_operator())
 
@@ -181,7 +181,7 @@ namespace lue::framework {
                     pybind11::is_operator())
                 .def(
                     "__ne__",
-                    [](Array const& argument1, ElementF const& argument2)
+                    [](Array const& argument1, Scalar const& argument2)
                     { return lfr::not_equal_to<ElementT<Array>, std::uint8_t, rank>(argument1, argument2); },
                     pybind11::is_operator())
 
@@ -198,7 +198,7 @@ namespace lue::framework {
                     pybind11::is_operator())
                 .def(
                     "__gt__",
-                    [](Array const& argument1, ElementF const& argument2)
+                    [](Array const& argument1, Scalar const& argument2)
                     { return lfr::greater_than<ElementT<Array>, std::uint8_t, rank>(argument1, argument2); },
                     pybind11::is_operator())
 
@@ -219,7 +219,7 @@ namespace lue::framework {
                     pybind11::is_operator())
                 .def(
                     "__ge__",
-                    [](Array const& argument1, ElementF const& argument2) {
+                    [](Array const& argument1, Scalar const& argument2) {
                         return lfr::greater_than_equal_to<ElementT<Array>, std::uint8_t, rank>(
                             argument1, argument2);
                     },
@@ -242,7 +242,7 @@ namespace lue::framework {
                 pybind11::is_operator())
             .def(
                 "__add__",
-                [](Array const& argument1, ElementF const& argument2)
+                [](Array const& argument1, Scalar const& argument2)
                 { return lfr::add<ElementT<Array>, rank>(argument1, argument2); },
                 pybind11::is_operator())
             .def(
@@ -252,7 +252,7 @@ namespace lue::framework {
                 pybind11::is_operator())
             .def(
                 "__radd__",
-                [](Array const& argument2, ElementF const& argument1)
+                [](Array const& argument2, Scalar const& argument1)
                 { return lfr::add<ElementT<Array>, rank>(argument1, argument2); },
                 pybind11::is_operator());
 
@@ -270,7 +270,7 @@ namespace lue::framework {
                 pybind11::is_operator())
             .def(
                 "__sub__",
-                [](Array const& argument1, ElementF const& argument2)
+                [](Array const& argument1, Scalar const& argument2)
                 { return lfr::subtract<ElementT<Array>, rank>(argument1, argument2); },
                 pybind11::is_operator())
             .def(
@@ -280,7 +280,7 @@ namespace lue::framework {
                 pybind11::is_operator())
             .def(
                 "__rsub__",
-                [](Array const& argument2, ElementF const& argument1)
+                [](Array const& argument2, Scalar const& argument1)
                 { return lfr::subtract<ElementT<Array>, rank>(argument1, argument2); },
                 pybind11::is_operator());
 
@@ -345,7 +345,7 @@ namespace lue::framework {
                     pybind11::is_operator())
                 .def(
                     "__mul__",
-                    [](Array const& argument1, ElementF const& argument2)
+                    [](Array const& argument1, Scalar const& argument2)
                     { return lfr::multiply<ElementT<Array>, rank>(argument1, argument2); },
                     pybind11::is_operator())
                 .def(
@@ -355,7 +355,7 @@ namespace lue::framework {
                     pybind11::is_operator())
                 .def(
                     "__rmul__",
-                    [](Array const& argument2, ElementF const& argument1)
+                    [](Array const& argument2, Scalar const& argument1)
                     { return lfr::multiply<ElementT<Array>, rank>(argument1, argument2); },
                     pybind11::is_operator());
 
@@ -373,7 +373,7 @@ namespace lue::framework {
                     pybind11::is_operator())
                 .def(
                     "__truediv__",
-                    [](Array const& argument1, ElementF const& argument2)
+                    [](Array const& argument1, Scalar const& argument2)
                     { return lfr::divide<ElementT<Array>, rank>(argument1, argument2); },
                     pybind11::is_operator())
                 .def(
@@ -383,7 +383,7 @@ namespace lue::framework {
                     pybind11::is_operator())
                 .def(
                     "__rtruediv__",
-                    [](Array const& argument2, ElementF const& argument1)
+                    [](Array const& argument2, Scalar const& argument1)
                     { return lfr::divide<ElementT<Array>, rank>(argument1, argument2); },
                     pybind11::is_operator());
 
@@ -401,7 +401,7 @@ namespace lue::framework {
                     pybind11::is_operator())
                 .def(
                     "__pow__",
-                    [](Array const& argument1, ElementF const& argument2)
+                    [](Array const& argument1, Scalar const& argument2)
                     { return lfr::pow<ElementT<Array>, rank>(argument1, argument2); },
                     pybind11::is_operator())
                 .def(
@@ -411,7 +411,7 @@ namespace lue::framework {
                     pybind11::is_operator())
                 .def(
                     "__rpow__",
-                    [](Array const& argument2, ElementF const& argument1)
+                    [](Array const& argument2, Scalar const& argument1)
                     { return lfr::pow<ElementT<Array>, rank>(argument1, argument2); },
                     pybind11::is_operator());
         }
diff --git a/source/framework/python/include/lue/py/framework/core/scalar.hpp b/source/framework/python/include/lue/py/framework/core/scalar.hpp
new file mode 100644
index 000000000..51bfe168b
--- /dev/null
+++ b/source/framework/python/include/lue/py/framework/core/scalar.hpp
@@ -0,0 +1,501 @@
+// #include "lue/py/framework/algorithm/abs.hpp"
+#include "lue/py/framework/algorithm/add.hpp"
+#include "lue/py/framework/algorithm/divide.hpp"
+// #include "lue/py/framework/algorithm/equal_to.hpp"
+// #include "lue/py/framework/algorithm/greater_than.hpp"
+// #include "lue/py/framework/algorithm/greater_than_equal_to.hpp"
+// #include "lue/py/framework/algorithm/less_than.hpp"
+// #include "lue/py/framework/algorithm/less_than_equal_to.hpp"
+// #include "lue/py/framework/algorithm/logical_and.hpp"
+// #include "lue/py/framework/algorithm/logical_exclusive_or.hpp"
+// #include "lue/py/framework/algorithm/logical_inclusive_or.hpp"
+// #include "lue/py/framework/algorithm/logical_not.hpp"
+#include "lue/py/framework/algorithm/multiply.hpp"
+// #include "lue/py/framework/algorithm/negate.hpp"
+// #include "lue/py/framework/algorithm/not_equal_to.hpp"
+#include "lue/py/framework/algorithm/pow.hpp"
+#include "lue/py/framework/algorithm/subtract.hpp"
+#include "lue/py/framework/stream.hpp"
+#include <pybind11/pybind11.h>
+
+
+using namespace pybind11::literals;
+
+
+namespace lue::framework {
+
+    namespace {
+
+        template<typename Element>
+        static std::string formal_string_representation([[maybe_unused]] Scalar<Element> const& scalar)
+        {
+            return fmt::format("Scalar<{}>{{}}", as_string<Element>());
+        }
+
+
+        template<typename Element>
+        static std::string informal_string_representation(Scalar<Element> const& scalar)
+        {
+            return formal_string_representation(scalar);
+        }
+
+
+        template<typename Element>
+        auto create_scalar(pybind11::object const& value) -> Scalar<Element>
+        {
+            return pybind11::cast<Element>(value);
+        }
+
+
+        auto create_scalar_py(pybind11::object const& dtype_args, pybind11::object const& value)
+            -> pybind11::object
+        {
+            pybind11::dtype const dtype{pybind11::dtype::from_args(dtype_args)};
+
+            // Switch on dtype and return a scalar of the right type
+
+            auto const kind = dtype.kind();
+            auto const size = dtype.itemsize();  // bytes
+            pybind11::object result;
+
+            switch (kind)
+            {
+                case 'i':
+                {
+                    // Signed integer
+                    switch (size)
+                    {
+                        case 4:
+                        {
+                            result = pybind11::cast(create_scalar<std::int32_t>(value));
+                            break;
+                        }
+                        case 8:
+                        {
+                            result = pybind11::cast(create_scalar<std::int64_t>(value));
+                            break;
+                        }
+                    }
+
+                    break;
+                }
+                case 'u':
+                {
+                    // Unsigned integer
+                    switch (size)
+                    {
+                        case 1:
+                        {
+                            result = pybind11::cast(create_scalar<std::uint8_t>(value));
+                            break;
+                        }
+                        case 4:
+                        {
+                            result = pybind11::cast(create_scalar<std::uint32_t>(value));
+                            break;
+                        }
+                        case 8:
+                        {
+                            result = pybind11::cast(create_scalar<std::uint64_t>(value));
+                            break;
+                        }
+                    }
+
+                    break;
+                }
+                case 'f':
+                {
+                    // Floating-point
+                    switch (size)
+                    {
+                        case 4:
+                        {
+                            result = pybind11::cast(create_scalar<float>(value));
+                            break;
+                        }
+                        case 8:
+                        {
+                            result = pybind11::cast(create_scalar<double>(value));
+                            break;
+                        }
+                    }
+
+                    break;
+                }
+            }
+
+            if (!result)
+            {
+                throw std::runtime_error(fmt::format("Unsupported dtype (kind={}, itemsize={})", kind, size));
+            }
+
+            return result;
+        }
+
+    }  // Anonymous namespace
+
+
+    template<typename Element>
+    void bind_scalar(pybind11::module& module)
+    {
+        namespace lfr = lue::framework;
+
+        using Scalar = lue::Scalar<Element>;
+        using Value = Element;
+
+        auto class_ =
+            pybind11::class_<Scalar>(
+                module,
+                fmt::format("Scalar<{}>", as_string<Element>()).c_str(),
+                fmt::format(
+                    R"(
+    Scalar containing element of type {}
+)",
+                    as_string<Element>())
+                    .c_str())
+
+                // .def(pybind11::init<Element>())
+
+                .def_property_readonly(
+                    "dtype",
+                    []([[maybe_unused]] Scalar const& self) { return dtype<Element>(); },
+                    "dtype docstring...")
+
+                .def_property_readonly(
+                    "future",
+                    [](Scalar const& self) -> hpx::shared_future<Element> { return self.future(); },
+                    "future docstring...")
+
+                .def("__repr__", [](Scalar const& scalar) { return formal_string_representation(scalar); })
+
+                .def("__str__", [](Scalar const& scalar) { return informal_string_representation(scalar); })
+
+                // bool(a), not a, if a, while a, ...
+                .def(
+                    "__bool__",
+                    []([[maybe_unused]] Scalar const& argument)
+                    {
+                        // ValueError
+                        throw std::invalid_argument("The truth value of a scalar is ambiguous");
+                    })
+
+            //                 // a < b
+            //                 .def(
+            //                     "__lt__",
+            //                     [](Scalar const& argument1, Scalar const& argument2)
+            //                     { return lfr::less_than<ElementT<Scalar>, std::uint8_t>(argument1,
+            //                     argument2); }, pybind11::is_operator())
+            //                 .def(
+            //                     "__lt__",
+            //                     [](Scalar const& argument1, Element const argument2)
+            //                     { return lfr::less_than<ElementT<Scalar>, std::uint8_t>(argument1,
+            //                     argument2); }, pybind11::is_operator())
+            //                 .def(
+            //                     "__lt__",
+            //                     [](Scalar const& argument1, Value const& argument2)
+            //                     { return lfr::less_than<ElementT<Scalar>, std::uint8_t>(argument1,
+            //                     argument2); }, pybind11::is_operator())
+            //
+            //                 // a <= b
+            //                 .def(
+            //                     "__le__",
+            //                     [](Scalar const& argument1, Scalar const& argument2) {
+            //                         return lfr::less_than_equal_to<ElementT<Scalar>, std::uint8_t>(
+            //                             argument1, argument2);
+            //                     },
+            //                     pybind11::is_operator())
+            //                 .def(
+            //                     "__le__",
+            //                     [](Scalar const& argument1, Element const argument2) {
+            //                         return lfr::less_than_equal_to<ElementT<Scalar>, std::uint8_t>(
+            //                             argument1, argument2);
+            //                     },
+            //                     pybind11::is_operator())
+            //                 .def(
+            //                     "__le__",
+            //                     [](Scalar const& argument1, Value const& argument2) {
+            //                         return lfr::less_than_equal_to<ElementT<Scalar>, std::uint8_t>(
+            //                             argument1, argument2);
+            //                     },
+            //                     pybind11::is_operator())
+            //
+            //                 // a == b
+            //                 .def(
+            //                     "__eq__",
+            //                     [](Scalar const& argument1, Scalar const& argument2)
+            //                     { return lfr::equal_to<ElementT<Scalar>, std::uint8_t>(argument1,
+            //                     argument2); }, pybind11::is_operator())
+            //                 .def(
+            //                     "__eq__",
+            //                     [](Scalar const& argument1, Element const argument2)
+            //                     { return lfr::equal_to<ElementT<Scalar>, std::uint8_t>(argument1,
+            //                     argument2); }, pybind11::is_operator())
+            //                 .def(
+            //                     "__eq__",
+            //                     [](Scalar const& argument1, Value const& argument2)
+            //                     { return lfr::equal_to<ElementT<Scalar>, std::uint8_t>(argument1,
+            //                     argument2); }, pybind11::is_operator())
+            //
+            //                 // a != b
+            //                 .def(
+            //                     "__ne__",
+            //                     [](Scalar const& argument1, Scalar const& argument2)
+            //                     { return lfr::not_equal_to<ElementT<Scalar>, std::uint8_t>(argument1,
+            //                     argument2); }, pybind11::is_operator())
+            //                 .def(
+            //                     "__ne__",
+            //                     [](Scalar const& argument1, Element const argument2)
+            //                     { return lfr::not_equal_to<ElementT<Scalar>, std::uint8_t>(argument1,
+            //                     argument2); }, pybind11::is_operator())
+            //                 .def(
+            //                     "__ne__",
+            //                     [](Scalar const& argument1, Value const& argument2)
+            //                     { return lfr::not_equal_to<ElementT<Scalar>, std::uint8_t>(argument1,
+            //                     argument2); }, pybind11::is_operator())
+            //
+            //                 // a > b
+            //                 .def(
+            //                     "__gt__",
+            //                     [](Scalar const& argument1, Scalar const& argument2)
+            //                     { return lfr::greater_than<ElementT<Scalar>, std::uint8_t>(argument1,
+            //                     argument2); }, pybind11::is_operator())
+            //                 .def(
+            //                     "__gt__",
+            //                     [](Scalar const& argument1, Element const argument2)
+            //                     { return lfr::greater_than<ElementT<Scalar>, std::uint8_t>(argument1,
+            //                     argument2); }, pybind11::is_operator())
+            //                 .def(
+            //                     "__gt__",
+            //                     [](Scalar const& argument1, Value const& argument2)
+            //                     { return lfr::greater_than<ElementT<Scalar>, std::uint8_t>(argument1,
+            //                     argument2); }, pybind11::is_operator())
+            //
+            //                 // a >= b
+            //                 .def(
+            //                     "__ge__",
+            //                     [](Scalar const& argument1, Scalar const& argument2) {
+            //                         return lfr::greater_than_equal_to<ElementT<Scalar>, std::uint8_t>(
+            //                             argument1, argument2);
+            //                     },
+            //                     pybind11::is_operator())
+            //                 .def(
+            //                     "__ge__",
+            //                     [](Scalar const& argument1, Element const argument2) {
+            //                         return lfr::greater_than_equal_to<ElementT<Scalar>, std::uint8_t>(
+            //                             argument1, argument2);
+            //                     },
+            //                     pybind11::is_operator())
+            //                 .def(
+            //                     "__ge__",
+            //                     [](Scalar const& argument1, Value const& argument2) {
+            //                         return lfr::greater_than_equal_to<ElementT<Scalar>, std::uint8_t>(
+            //                             argument1, argument2);
+            //                     },
+            //                     pybind11::is_operator())
+
+            ;
+
+
+        // a + b, b + a, a += b
+        class_
+            .def(
+                "__add__",
+                [](Scalar const& argument1, Scalar const& argument2)
+                { return lfr::add<ElementT<Scalar>>(argument1, argument2); },
+                pybind11::is_operator())
+            .def(
+                "__add__",
+                [](Scalar const& argument1, Element const argument2)
+                { return lfr::add<ElementT<Scalar>>(argument1, argument2); },
+                pybind11::is_operator())
+            .def(
+                "__add__",
+                [](Scalar const& argument1, Value const& argument2)
+                { return lfr::add<ElementT<Scalar>>(argument1, argument2); },
+                pybind11::is_operator())
+            .def(
+                "__radd__",
+                [](Scalar const& argument2, Element const argument1)
+                { return lfr::add<ElementT<Scalar>>(argument1, argument2); },
+                pybind11::is_operator())
+            .def(
+                "__radd__",
+                [](Scalar const& argument2, Value const& argument1)
+                { return lfr::add<ElementT<Scalar>>(argument1, argument2); },
+                pybind11::is_operator());
+
+        // a - b, b - a, a -= b
+        class_
+            .def(
+                "__sub__",
+                [](Scalar const& argument1, Scalar const& argument2)
+                { return lfr::subtract<ElementT<Scalar>>(argument1, argument2); },
+                pybind11::is_operator())
+            .def(
+                "__sub__",
+                [](Scalar const& argument1, Element const argument2)
+                { return lfr::subtract<ElementT<Scalar>>(argument1, argument2); },
+                pybind11::is_operator())
+            .def(
+                "__sub__",
+                [](Scalar const& argument1, Value const& argument2)
+                { return lfr::subtract<ElementT<Scalar>>(argument1, argument2); },
+                pybind11::is_operator())
+            .def(
+                "__rsub__",
+                [](Scalar const& argument2, Element const argument1)
+                { return lfr::subtract<ElementT<Scalar>>(argument1, argument2); },
+                pybind11::is_operator())
+            .def(
+                "__rsub__",
+                [](Scalar const& argument2, Value const& argument1)
+                { return lfr::subtract<ElementT<Scalar>>(argument1, argument2); },
+                pybind11::is_operator());
+
+
+        //         if constexpr (std::is_signed_v<Element> || std::is_floating_point_v<Element>)
+        //         {
+        //             // abs(a)
+        //             class_.def(
+        //                 "__abs__",
+        //                 [](Scalar const& argument) { return lfr::abs<ElementT<Scalar>>(argument); },
+        //                 pybind11::is_operator());
+        //
+        //             // -a
+        //             class_.def(
+        //                 "__neg__",
+        //                 [](Scalar const& argument) { return lfr::negate<ElementT<Scalar>>(argument); },
+        //                 pybind11::is_operator());
+        //         }
+        //
+        //         if constexpr (std::is_integral_v<Element>)
+        //         {
+        //             // a | b
+        //             class_.def(
+        //                 "__or__",
+        //                 [](Scalar const& argument1, Scalar const& argument2)
+        //                 { return lfr::logical_inclusive_or<ElementT<Scalar>>(argument1, argument2); },
+        //                 pybind11::is_operator());
+        //
+        //             // a ^ b
+        //             class_.def(
+        //                 "__xor__",
+        //                 [](Scalar const& argument1, Scalar const& argument2)
+        //                 { return lfr::logical_exclusive_or<ElementT<Scalar>>(argument1, argument2); },
+        //                 pybind11::is_operator());
+        //
+        //             // a & b
+        //             class_.def(
+        //                 "__and__",
+        //                 [](Scalar const& argument1, Scalar const& argument2)
+        //                 { return lfr::logical_and<ElementT<Scalar>>(argument1, argument2); },
+        //                 pybind11::is_operator());
+        //
+        //             // ~a
+        //             class_.def(
+        //                 "__invert__",
+        //                 [](Scalar const& argument) { return lfr::logical_not<ElementT<Scalar>>(argument);
+        //                 }, pybind11::is_operator());
+        //         }
+
+        if constexpr (std::is_floating_point_v<Element>)
+        {
+            // a * b, b * a, a *= b
+            class_
+                .def(
+                    "__mul__",
+                    [](Scalar const& argument1, Scalar const& argument2)
+                    { return lfr::multiply<ElementT<Scalar>>(argument1, argument2); },
+                    pybind11::is_operator())
+                .def(
+                    "__mul__",
+                    [](Scalar const& argument1, Element const argument2)
+                    { return lfr::multiply<ElementT<Scalar>>(argument1, argument2); },
+                    pybind11::is_operator())
+                .def(
+                    "__mul__",
+                    [](Scalar const& argument1, Value const& argument2)
+                    { return lfr::multiply<ElementT<Scalar>>(argument1, argument2); },
+                    pybind11::is_operator())
+                .def(
+                    "__rmul__",
+                    [](Scalar const& argument2, Element const argument1)
+                    { return lfr::multiply<ElementT<Scalar>>(argument1, argument2); },
+                    pybind11::is_operator())
+                .def(
+                    "__rmul__",
+                    [](Scalar const& argument2, Value const& argument1)
+                    { return lfr::multiply<ElementT<Scalar>>(argument1, argument2); },
+                    pybind11::is_operator());
+
+            // a / b, b / a, a /= b
+            class_
+                .def(
+                    "__truediv__",
+                    [](Scalar const& argument1, Scalar const& argument2)
+                    { return lfr::divide<ElementT<Scalar>>(argument1, argument2); },
+                    pybind11::is_operator())
+                .def(
+                    "__truediv__",
+                    [](Scalar const& argument1, Element const argument2)
+                    { return lfr::divide<ElementT<Scalar>>(argument1, argument2); },
+                    pybind11::is_operator())
+                .def(
+                    "__truediv__",
+                    [](Scalar const& argument1, Value const& argument2)
+                    { return lfr::divide<ElementT<Scalar>>(argument1, argument2); },
+                    pybind11::is_operator())
+                .def(
+                    "__rtruediv__",
+                    [](Scalar const& argument2, Element const argument1)
+                    { return lfr::divide<ElementT<Scalar>>(argument1, argument2); },
+                    pybind11::is_operator())
+                .def(
+                    "__rtruediv__",
+                    [](Scalar const& argument2, Value const& argument1)
+                    { return lfr::divide<ElementT<Scalar>>(argument1, argument2); },
+                    pybind11::is_operator());
+
+            // a ** b, b ** a, a **= b
+            class_
+                .def(
+                    "__pow__",
+                    [](Scalar const& argument1, Scalar const& argument2)
+                    { return lfr::pow<ElementT<Scalar>>(argument1, argument2); },
+                    pybind11::is_operator())
+                .def(
+                    "__pow__",
+                    [](Scalar const& argument1, Element const argument2)
+                    { return lfr::pow<ElementT<Scalar>>(argument1, argument2); },
+                    pybind11::is_operator())
+                .def(
+                    "__pow__",
+                    [](Scalar const& argument1, Value const& argument2)
+                    { return lfr::pow<ElementT<Scalar>>(argument1, argument2); },
+                    pybind11::is_operator())
+                .def(
+                    "__rpow__",
+                    [](Scalar const& argument2, Element const argument1)
+                    { return lfr::pow<ElementT<Scalar>>(argument1, argument2); },
+                    pybind11::is_operator())
+                .def(
+                    "__rpow__",
+                    [](Scalar const& argument2, Value const& argument1)
+                    { return lfr::pow<ElementT<Scalar>>(argument1, argument2); },
+                    pybind11::is_operator());
+        }
+
+        module.def(
+            "create_scalar",
+            create_scalar_py,
+            R"(
+    Create new scalar, with a value
+
+    :param numpy.dtype dtype: Description of the type of the scalar value
+    :param value: Value to initialize scalar with
+)",
+            "dtype"_a,
+            "value"_a);
+    }
+
+}  // namespace lue::framework
diff --git a/source/framework/python/src/algorithm/add.cpp b/source/framework/python/src/algorithm/add.cpp
index 499f9deb4..1c494652e 100644
--- a/source/framework/python/src/algorithm/add.cpp
+++ b/source/framework/python/src/algorithm/add.cpp
@@ -4,24 +4,37 @@
 
 namespace lue::framework {
 
-#define LUE_ADD_OVERLOADS(type, rank)                                                                        \
-    module.def("add", add<type, rank, PartitionedArray<type, rank>, PartitionedArray<type, rank>>);          \
-    module.def("add", add<type, rank, PartitionedArray<type, rank>, type>);                                  \
-    module.def("add", add<type, rank, PartitionedArray<type, rank>, hpx::shared_future<type>>);              \
-    module.def("add", add<type, rank, type, PartitionedArray<type, rank>>);                                  \
-    module.def("add", add<type, rank, hpx::shared_future<type>, PartitionedArray<type, rank>>);
+    namespace {
+
+        template<typename Element>
+        constexpr void define_add_overloads(pybind11::module& module)
+        {
+            Rank const rank{2};
+
+            module.def(
+                "add", add<Element, rank, PartitionedArray<Element, rank>, PartitionedArray<Element, rank>>);
+            module.def("add", add<Element, rank, PartitionedArray<Element, rank>, Scalar<Element>>);
+            module.def("add", add<Element, rank, PartitionedArray<Element, rank>, Element>);
+
+            module.def("add", add<Element, rank, Scalar<Element>, PartitionedArray<Element, rank>>);
+            module.def("add", add<Element, rank, Element, PartitionedArray<Element, rank>>);
+
+            module.def("add", add<Element, Scalar<Element>, Element>);
+            module.def("add", add<Element, Element, Scalar<Element>>);
+        }
+
+    }  // Anonymous namespace
 
 
     void bind_add(pybind11::module& module)
     {
-        // TODO How to document these?
-        LUE_ADD_OVERLOADS(std::uint8_t, 2)
-        LUE_ADD_OVERLOADS(std::uint32_t, 2)
-        LUE_ADD_OVERLOADS(std::uint64_t, 2)
-        LUE_ADD_OVERLOADS(std::int32_t, 2)
-        LUE_ADD_OVERLOADS(std::int64_t, 2)
-        LUE_ADD_OVERLOADS(float, 2)
-        LUE_ADD_OVERLOADS(double, 2)
+        define_add_overloads<std::uint8_t>(module);
+        define_add_overloads<std::uint32_t>(module);
+        define_add_overloads<std::uint64_t>(module);
+        define_add_overloads<std::int32_t>(module);
+        define_add_overloads<std::int64_t>(module);
+        define_add_overloads<float>(module);
+        define_add_overloads<double>(module);
     }
 
 }  // namespace lue::framework
diff --git a/source/framework/python/src/algorithm/global_operation/maximum.cpp b/source/framework/python/src/algorithm/global_operation/maximum.cpp
index e7eb21de3..6ad933c5b 100644
--- a/source/framework/python/src/algorithm/global_operation/maximum.cpp
+++ b/source/framework/python/src/algorithm/global_operation/maximum.cpp
@@ -6,9 +6,9 @@ namespace lue::framework {
     namespace {
 
         template<typename Element, Rank rank>
-        hpx::shared_future<Element> maximum(PartitionedArray<Element, rank> const& array)
+        auto maximum(PartitionedArray<Element, rank> const& array) -> Scalar<Element>
         {
-            return value_policies::maximum(array).share();
+            return value_policies::maximum(array);
         }
 
     }  // Anonymous namespace
diff --git a/source/framework/python/src/algorithm/global_operation/minimum.cpp b/source/framework/python/src/algorithm/global_operation/minimum.cpp
index 4d84ec364..52789a44b 100644
--- a/source/framework/python/src/algorithm/global_operation/minimum.cpp
+++ b/source/framework/python/src/algorithm/global_operation/minimum.cpp
@@ -6,9 +6,9 @@ namespace lue::framework {
     namespace {
 
         template<typename Element, Rank rank>
-        hpx::shared_future<Element> minimum(PartitionedArray<Element, rank> const& array)
+        auto minimum(PartitionedArray<Element, rank> const& array) -> Scalar<Element>
         {
-            return value_policies::minimum(array).share();
+            return value_policies::minimum(array);
         }
 
     }  // Anonymous namespace
diff --git a/source/framework/python/src/algorithm/global_operation/sum.cpp b/source/framework/python/src/algorithm/global_operation/sum.cpp
index 1f3cf68ba..fec1a10ec 100644
--- a/source/framework/python/src/algorithm/global_operation/sum.cpp
+++ b/source/framework/python/src/algorithm/global_operation/sum.cpp
@@ -6,9 +6,9 @@ namespace lue::framework {
     namespace {
 
         template<typename Element, Rank rank>
-        hpx::shared_future<Element> sum(PartitionedArray<Element, rank> const& array)
+        auto sum(PartitionedArray<Element, rank> const& array) -> Scalar<Element>
         {
-            return value_policies::sum(array).share();
+            return value_policies::sum(array);
         }
 
     }  // Anonymous namespace
diff --git a/source/framework/python/src/algorithm/where.cpp b/source/framework/python/src/algorithm/where.cpp
index 11e8c7c86..61d75f164 100644
--- a/source/framework/python/src/algorithm/where.cpp
+++ b/source/framework/python/src/algorithm/where.cpp
@@ -2,274 +2,84 @@
 #include <pybind11/pybind11.h>
 
 
-using namespace pybind11::literals;
-
-
 namespace lue::framework {
     namespace {
 
-        template<typename Condition, Rank rank, typename... Expression>
-        class Where
-        {
-        };
-
-
-        // where(condition_array, true_array)
-        template<typename ConditionElement, Rank rank, typename ExpressionElement>
-        class Where<PartitionedArray<ConditionElement, rank>, rank, PartitionedArray<ExpressionElement, rank>>
-        {
-
-            public:
-
-                using OutputElement = ExpressionElement;
-
-                static PartitionedArray<ExpressionElement, rank> operation(
-                    PartitionedArray<ConditionElement, rank> const& condition_array,
-                    PartitionedArray<ExpressionElement, rank> const& true_array)
-                {
-                    return lue::value_policies::where(condition_array, true_array);
-                }
-        };
-
-
-        // where(condition_array, true_value_f)
-        template<typename ConditionElement, Rank rank, typename ExpressionElement>
-        class Where<PartitionedArray<ConditionElement, rank>, rank, hpx::shared_future<ExpressionElement>>
-        {
-
-            public:
-
-                using OutputElement = ExpressionElement;
-
-                static PartitionedArray<ExpressionElement, rank> operation(
-                    PartitionedArray<ConditionElement, rank> const& condition_array,
-                    hpx::shared_future<ExpressionElement> const& true_value_f)
-                {
-                    return lue::value_policies::where(condition_array, true_value_f);
-                }
-        };
-
-
-        // where(condition_array, true_value)
-        template<typename ConditionElement, Rank rank, typename ExpressionElement>
-        class Where<PartitionedArray<ConditionElement, rank>, rank, ExpressionElement>
+        template<typename Element>
+        constexpr void define_where_overloads(pybind11::module& module)
         {
+            using namespace lue::value_policies;
 
-            public:
-
-                using OutputElement = ExpressionElement;
-
-                static PartitionedArray<ExpressionElement, rank> operation(
-                    PartitionedArray<ConditionElement, rank> const& condition_array,
-                    ExpressionElement const& true_value)
-                {
-                    return lue::value_policies::where(condition_array, true_value);
-                }
-        };
-
-
-        // where(condition_array, true_array, false_array)
-        template<typename ConditionElement, Rank rank, typename ExpressionElement>
-        class Where<
-            PartitionedArray<ConditionElement, rank>,
-            rank,
-            PartitionedArray<ExpressionElement, rank>,
-            PartitionedArray<ExpressionElement, rank>>
-        {
-
-            public:
-
-                using OutputElement = ExpressionElement;
-
-                static PartitionedArray<ExpressionElement, rank> operation(
-                    PartitionedArray<ConditionElement, rank> const& condition_array,
-                    PartitionedArray<ExpressionElement, rank> const& true_array,
-                    PartitionedArray<ExpressionElement, rank> const& false_array)
-                {
-                    return lue::value_policies::where(condition_array, true_array, false_array);
-                }
-        };
-
-
-        // where(condition_array, true_array, false_value_f)
-        template<typename ConditionElement, Rank rank, typename ExpressionElement>
-        class Where<
-            PartitionedArray<ConditionElement, rank>,
-            rank,
-            PartitionedArray<ExpressionElement, rank>,
-            hpx::shared_future<ExpressionElement>>
-        {
-
-            public:
-
-                using OutputElement = ExpressionElement;
-
-                static PartitionedArray<ExpressionElement, rank> operation(
-                    PartitionedArray<ConditionElement, rank> const& condition_array,
-                    PartitionedArray<ExpressionElement, rank> const& true_array,
-                    hpx::shared_future<ExpressionElement> const& false_value_f)
-                {
-                    return lue::value_policies::where(condition_array, true_array, false_value_f);
-                }
-        };
-
-
-        // where(condition_array, true_array, false_value)
-        template<typename ConditionElement, Rank rank, typename ExpressionElement>
-        class Where<
-            PartitionedArray<ConditionElement, rank>,
-            rank,
-            PartitionedArray<ExpressionElement, rank>,
-            ExpressionElement>
-        {
+            Rank const rank{2};
 
-            public:
-
-                using OutputElement = ExpressionElement;
-
-                static PartitionedArray<ExpressionElement, rank> operation(
-                    PartitionedArray<ConditionElement, rank> const& condition_array,
-                    PartitionedArray<ExpressionElement, rank> const& true_array,
-                    ExpressionElement const& false_value)
-                {
-                    return lue::value_policies::where(condition_array, true_array, false_value);
-                }
-        };
-
-
-        // where(condition_array, true_value_f, false_array)
-        template<typename ConditionElement, Rank rank, typename ExpressionElement>
-        class Where<
-            PartitionedArray<ConditionElement, rank>,
-            rank,
-            hpx::shared_future<ExpressionElement>,
-            PartitionedArray<ExpressionElement, rank>>
-        {
-
-            public:
-
-                using OutputElement = ExpressionElement;
-
-                static PartitionedArray<ExpressionElement, rank> operation(
-                    PartitionedArray<ConditionElement, rank> const& condition_array,
-                    hpx::shared_future<ExpressionElement> const& true_value_f,
-                    PartitionedArray<ExpressionElement, rank> const& false_array)
-                {
-                    return lue::value_policies::where(condition_array, true_value_f, false_array);
-                }
-        };
-
-
-        // where(condition_array, true_value, false_array)
-        template<typename ConditionElement, Rank rank, typename ExpressionElement>
-        class Where<
-            PartitionedArray<ConditionElement, rank>,
-            rank,
-            ExpressionElement,
-            PartitionedArray<ExpressionElement, rank>>
-        {
-
-            public:
-
-                using OutputElement = ExpressionElement;
-
-                static PartitionedArray<ExpressionElement, rank> operation(
-                    PartitionedArray<ConditionElement, rank> const& condition_array,
-                    ExpressionElement const& true_value,
-                    PartitionedArray<ExpressionElement, rank> const& false_array)
-                {
-                    return lue::value_policies::where(condition_array, true_value, false_array);
-                }
-        };
-
-
-        // where(condition_array, true_value_f, false_value_f)
-        template<typename ConditionElement, Rank rank, typename ExpressionElement>
-        class Where<
-            PartitionedArray<ConditionElement, rank>,
-            rank,
-            hpx::shared_future<ExpressionElement>,
-            hpx::shared_future<ExpressionElement>>
-        {
-
-            public:
-
-                using OutputElement = ExpressionElement;
-
-                static PartitionedArray<ExpressionElement, rank> operation(
-                    PartitionedArray<ConditionElement, rank> const& condition_array,
-                    hpx::shared_future<ExpressionElement> const& true_value_f,
-                    hpx::shared_future<ExpressionElement> const& false_value_f)
-                {
-                    return lue::value_policies::where(condition_array, true_value_f, false_value_f);
-                }
-        };
-
-
-        // where(condition_array, true_value, false_value)
-        template<typename ConditionElement, Rank rank, typename ExpressionElement>
-        class Where<PartitionedArray<ConditionElement, rank>, rank, ExpressionElement, ExpressionElement>
-        {
-
-            public:
-
-                using OutputElement = ExpressionElement;
-
-                static PartitionedArray<ExpressionElement, rank> operation(
-                    PartitionedArray<ConditionElement, rank> const& condition_array,
-                    ExpressionElement const& true_value,
-                    ExpressionElement const& false_value)
-                {
-                    return lue::value_policies::where(condition_array, true_value, false_value);
-                }
-        };
-
-
-        template<typename ConditionElement, Rank rank, typename... Expression>
-        PartitionedArray<
-            typename Where<PartitionedArray<ConditionElement, rank>, rank, Expression...>::OutputElement,
-            rank>
-        where(
-            PartitionedArray<ConditionElement, rank> const& condition_array, Expression const&... expression)
-        {
+            using ConditionElement = std::uint8_t;
             using ConditionArray = PartitionedArray<ConditionElement, rank>;
-
-            return Where<ConditionArray, rank, Expression...>::operation(condition_array, expression...);
+            using Array = PartitionedArray<Element, rank>;
+            using Scalar = Scalar<Element>;
+            using Value = Element;
+
+            module.def(
+                "where",
+                [](ConditionArray const& condition_array, Array const& true_array)
+                { return where(condition_array, true_array); });
+            module.def(
+                "where",
+                [](ConditionArray const& condition_array, Scalar const& true_scalar)
+                { return where(condition_array, true_scalar); });
+            module.def(
+                "where",
+                [](ConditionArray const& condition_array, Value const true_value)
+                { return where(condition_array, true_value); });
+
+            module.def(
+                "where",
+                [](ConditionArray const& condition_array, Array const& true_array, Array const& false_array)
+                { return where(condition_array, true_array, false_array); });
+            module.def(
+                "where",
+                [](ConditionArray const& condition_array, Scalar const& true_scalar, Array const& false_array)
+                { return where(condition_array, true_scalar, false_array); });
+            module.def(
+                "where",
+                [](ConditionArray const& condition_array, Value const true_value, Array const& false_array)
+                { return where(condition_array, true_value, false_array); });
+
+            module.def(
+                "where",
+                [](ConditionArray const& condition_array, Array const& true_array, Array const& false_array)
+                { return where(condition_array, true_array, false_array); });
+            module.def(
+                "where",
+                [](ConditionArray const& condition_array, Array const& true_array, Scalar const& false_scalar)
+                { return where(condition_array, true_array, false_scalar); });
+            module.def(
+                "where",
+                [](ConditionArray const& condition_array, Array const& true_array, Value const false_value)
+                { return where(condition_array, true_array, false_value); });
+
+            module.def(
+                "where",
+                [](ConditionArray const& condition_array,
+                   Scalar const& true_scalar,
+                   Scalar const& false_scalar) { return where(condition_array, true_scalar, false_scalar); });
+            module.def(
+                "where",
+                [](ConditionArray const& condition_array, Value const true_value, Value const false_value)
+                { return where(condition_array, true_value, false_value); });
         }
 
     }  // Anonymous namespace
 
 
-    // TODO Add overloads for numpy scalar types
-
-#define WHERE_OVERLOADS(Element, rank)                                                                       \
-    module.def("where", where<std::uint8_t, rank, PartitionedArray<Element, rank>>);                         \
-    module.def("where", where<std::uint8_t, rank, hpx::shared_future<Element>>);                             \
-    module.def("where", where<std::uint8_t, rank, Element>, "condition"_a, "true_expression"_a.noconvert()); \
-    module.def(                                                                                              \
-        "where",                                                                                             \
-        where<std::uint8_t, rank, PartitionedArray<Element, rank>, PartitionedArray<Element, rank>>);        \
-    module.def(                                                                                              \
-        "where", where<std::uint8_t, rank, PartitionedArray<Element, rank>, hpx::shared_future<Element>>);   \
-    module.def("where", where<std::uint8_t, rank, PartitionedArray<Element, rank>, Element>);                \
-    module.def(                                                                                              \
-        "where", where<std::uint8_t, rank, hpx::shared_future<Element>, PartitionedArray<Element, rank>>);   \
-    module.def("where", where<std::uint8_t, rank, Element, PartitionedArray<Element, rank>>);                \
-    module.def(                                                                                              \
-        "where", where<std::uint8_t, rank, hpx::shared_future<Element>, hpx::shared_future<Element>>);       \
-    module.def("where", where<std::uint8_t, rank, Element, Element>);
-
-
     void bind_where(pybind11::module& module)
     {
-        // TODO How to document these?
-        WHERE_OVERLOADS(std::uint8_t, 2);
-        WHERE_OVERLOADS(std::uint32_t, 2);
-        WHERE_OVERLOADS(std::uint64_t, 2);
-        WHERE_OVERLOADS(std::int32_t, 2);
-        WHERE_OVERLOADS(std::int64_t, 2);
-        WHERE_OVERLOADS(float, 2);
-        WHERE_OVERLOADS(double, 2);
+        define_where_overloads<std::uint8_t>(module);
+        define_where_overloads<std::uint32_t>(module);
+        define_where_overloads<std::uint64_t>(module);
+        define_where_overloads<std::int32_t>(module);
+        define_where_overloads<std::int64_t>(module);
+        define_where_overloads<float>(module);
+        define_where_overloads<double>(module);
     }
 
 }  // namespace lue::framework
diff --git a/source/framework/python/src/core/scalar.cpp b/source/framework/python/src/core/scalar.cpp
new file mode 100644
index 000000000..d7dc19caa
--- /dev/null
+++ b/source/framework/python/src/core/scalar.cpp
@@ -0,0 +1,17 @@
+#include "lue/py/framework/core/scalar.hpp"
+
+
+namespace lue::framework {
+
+    void bind_scalar(pybind11::module& module)
+    {
+        bind_scalar<std::uint8_t>(module);
+        bind_scalar<std::uint32_t>(module);
+        bind_scalar<std::uint64_t>(module);
+        bind_scalar<std::int32_t>(module);
+        bind_scalar<std::int64_t>(module);
+        bind_scalar<float>(module);
+        bind_scalar<double>(module);
+    }
+
+}  // namespace lue::framework
diff --git a/source/framework/python/src/submodule.cpp b/source/framework/python/src/submodule.cpp
index 7223e6fae..3f47fe6ec 100644
--- a/source/framework/python/src/submodule.cpp
+++ b/source/framework/python/src/submodule.cpp
@@ -53,6 +53,7 @@ namespace lue::framework {
     void bind_routing_operations(pybind11::module& module);
     void bind_zonal_operations(pybind11::module& module);
     void bind_partitioned_array(pybind11::module& module);
+    void bind_scalar(pybind11::module& module);
     void bind_serial_route(pybind11::module& module);
     void bind_wait_serial_route(pybind11::module& module);
 
@@ -91,6 +92,7 @@ namespace lue::framework {
         bind_hpx(submodule);
 
         // Wrap high-level data structures
+        bind_scalar(submodule);
         bind_partitioned_array(submodule);
         bind_serial_route(submodule);
         bind_wait_serial_route(submodule);


Test patch:
diff --git a/source/framework/algorithm/test/abs_test.cpp b/source/framework/algorithm/test/abs_test.cpp
index cf4c2b346..91537e24c 100644
--- a/source/framework/algorithm/test/abs_test.cpp
+++ b/source/framework/algorithm/test/abs_test.cpp
@@ -27,7 +27,7 @@ namespace detail {
 
         Array array{lue::create_partitioned_array(array_shape, partition_shape, Element{-5})};
 
-        BOOST_CHECK(all(abs(array) == Element{5}).get());
+        BOOST_CHECK(all(abs(array) == Element{5}).future().get());
     }
 
 }  // namespace detail
@@ -64,12 +64,12 @@ BOOST_AUTO_TEST_CASE(out_of_range)
     {
         Array array{lue::create_partitioned_array(
             array_shape, partition_shape, Element{std::numeric_limits<Element>::lowest() + 1})};
-        BOOST_CHECK(all(valid<BooleanElement>(abs(array))).get());
+        BOOST_CHECK(all(valid<BooleanElement>(abs(array))).future().get());
     }
 
     {
         Array array{lue::create_partitioned_array(
             array_shape, partition_shape, Element{std::numeric_limits<Element>::lowest()})};
-        BOOST_CHECK(none(valid<BooleanElement>(abs(array))).get());
+        BOOST_CHECK(none(valid<BooleanElement>(abs(array))).future().get());
     }
 }
diff --git a/source/framework/algorithm/test/acos_test.cpp b/source/framework/algorithm/test/acos_test.cpp
index 7fb728a6b..9ecfb2ef6 100644
--- a/source/framework/algorithm/test/acos_test.cpp
+++ b/source/framework/algorithm/test/acos_test.cpp
@@ -22,7 +22,7 @@ namespace detail {
 
         Array array{lue::create_partitioned_array(array_shape, partition_shape, fill_value)};
 
-        BOOST_CHECK(all(acos(array) == std::acos(fill_value)).get());
+        BOOST_CHECK(all(acos(array) == std::acos(fill_value)).future().get());
     }
 
 }  // namespace detail
diff --git a/source/framework/algorithm/test/add_test.cpp b/source/framework/algorithm/test/add_test.cpp
index d982e63fd..95bd8ed49 100644
--- a/source/framework/algorithm/test/add_test.cpp
+++ b/source/framework/algorithm/test/add_test.cpp
@@ -29,7 +29,7 @@ namespace detail {
 
         Array add = array1 + array2;
 
-        BOOST_CHECK(all(add == fill_value1 + fill_value2).get());
+        BOOST_CHECK(all(add == fill_value1 + fill_value2).future().get());
     }
 
 }  // namespace detail
@@ -74,8 +74,26 @@ BOOST_AUTO_TEST_CASE(out_of_range)
     // Careful. The default no-data value for int32_t is the lowest value. Although max +
     // 1 is undefined for signed integers, this may wrap around to this minimum value. Therefore,
     // we add 2 here, instead of 1. Adding 1 confuses things.
-    BOOST_CHECK(none(valid<std::uint8_t>(2 + array)).get());
-    BOOST_CHECK(none(valid<std::uint8_t>(array + 2)).get());
-    BOOST_CHECK(none(valid<std::uint8_t>(array + array)).get());
-    BOOST_CHECK_EQUAL((valid<std::uint8_t>(Scalar{max} + 2)).value().get(), 0);
+    BOOST_CHECK(none(valid<std::uint8_t>(2 + array)).future().get());
+    BOOST_CHECK(none(valid<std::uint8_t>(array + 2)).future().get());
+    BOOST_CHECK(none(valid<std::uint8_t>(array + array)).future().get());
+    BOOST_CHECK_EQUAL((valid<std::uint8_t>(Scalar{max} + 2)).future().get(), 0);
+}
+
+
+BOOST_AUTO_TEST_CASE(value_icw_scalar)
+{
+    using namespace lue::value_policies;
+
+    using Value = std::int32_t;
+    using Scalar = lue::Scalar<Value>;
+
+    Value const max{std::numeric_limits<Value>::max()};
+
+    Value const value{5};
+    Scalar const scalar{6};
+
+    BOOST_CHECK_EQUAL((value + scalar).future().get(), 11);
+    BOOST_CHECK_EQUAL((scalar + value).future().get(), 11);
+    BOOST_CHECK(!valid<std::uint8_t>(scalar + max).future().get());
 }
diff --git a/source/framework/algorithm/test/all_test.cpp b/source/framework/algorithm/test/all_test.cpp
index 465a06e1b..639c2f01a 100644
--- a/source/framework/algorithm/test/all_test.cpp
+++ b/source/framework/algorithm/test/all_test.cpp
@@ -22,8 +22,8 @@ namespace detail {
         Array array1{lue::create_partitioned_array(array_shape, partition_shape, fill_value1)};
         Array array2{lue::create_partitioned_array(array_shape, partition_shape, fill_value2)};
 
-        BOOST_CHECK_EQUAL(all(array1).get(), Element{1});  // true
-        BOOST_CHECK_EQUAL(all(array2).get(), Element{0});  // false
+        BOOST_CHECK_EQUAL(all(array1).future().get(), Element{1});  // true
+        BOOST_CHECK_EQUAL(all(array2).future().get(), Element{0});  // false
     }
 
 }  // namespace detail
diff --git a/source/framework/algorithm/test/any_test.cpp b/source/framework/algorithm/test/any_test.cpp
index 03fa29b00..47b756688 100644
--- a/source/framework/algorithm/test/any_test.cpp
+++ b/source/framework/algorithm/test/any_test.cpp
@@ -20,8 +20,8 @@ namespace detail {
         Array array1{lue::create_partitioned_array(array_shape, partition_shape, fill_value1)};
         Array array2{lue::create_partitioned_array(array_shape, partition_shape, fill_value2)};
 
-        BOOST_CHECK_EQUAL(lue::any(array1).get(), Element{1});  // true
-        BOOST_CHECK_EQUAL(lue::any(array2).get(), Element{0});  // false
+        BOOST_CHECK_EQUAL(lue::any(array1).future().get(), Element{1});  // true
+        BOOST_CHECK_EQUAL(lue::any(array2).future().get(), Element{0});  // false
     }
 
 }  // namespace detail
diff --git a/source/framework/algorithm/test/array_like_test.cpp b/source/framework/algorithm/test/array_like_test.cpp
index 5e9bd5418..f12e5c80a 100644
--- a/source/framework/algorithm/test/array_like_test.cpp
+++ b/source/framework/algorithm/test/array_like_test.cpp
@@ -25,8 +25,8 @@ namespace detail {
 
         auto output_array = lue::array_like(input_array, fill_value);
 
-        BOOST_CHECK(all(output_array == fill_value).get());
-        BOOST_CHECK(all(lue::locality_id(output_array) == lue::locality_id(input_array)).get());
+        BOOST_CHECK(all(output_array == fill_value).future().get());
+        BOOST_CHECK(all(lue::locality_id(output_array) == lue::locality_id(input_array)).future().get());
     }
 
 }  // namespace detail
diff --git a/source/framework/algorithm/test/array_partition_id_test.cpp b/source/framework/algorithm/test/array_partition_id_test.cpp
index f815868c1..788c9df59 100644
--- a/source/framework/algorithm/test/array_partition_id_test.cpp
+++ b/source/framework/algorithm/test/array_partition_id_test.cpp
@@ -32,6 +32,7 @@ namespace detail {
         {
             BOOST_CHECK(
                 all(localities[p], equal_to(localities[p], partitions[p], static_cast<std::uint64_t>(p)))
+                    .future()
                     .get());
         }
     }
diff --git a/source/framework/algorithm/test/asin_test.cpp b/source/framework/algorithm/test/asin_test.cpp
index cfc498de2..3a22fd2f5 100644
--- a/source/framework/algorithm/test/asin_test.cpp
+++ b/source/framework/algorithm/test/asin_test.cpp
@@ -22,7 +22,7 @@ namespace detail {
 
         Array array{lue::create_partitioned_array(array_shape, partition_shape, fill_value)};
 
-        BOOST_CHECK(all(asin(array) == std::asin(fill_value)).get());
+        BOOST_CHECK(all(asin(array) == std::asin(fill_value)).future().get());
     }
 
 }  // namespace detail
diff --git a/source/framework/algorithm/test/atan2_test.cpp b/source/framework/algorithm/test/atan2_test.cpp
index 6a321c214..e6b49ea5e 100644
--- a/source/framework/algorithm/test/atan2_test.cpp
+++ b/source/framework/algorithm/test/atan2_test.cpp
@@ -24,7 +24,7 @@ namespace detail {
         Array array1{lue::create_partitioned_array(array_shape, partition_shape, fill_value1)};
         Array array2{lue::create_partitioned_array(array_shape, partition_shape, fill_value2)};
 
-        BOOST_CHECK(all(atan2(array1, array2) == std::atan2(fill_value1, fill_value2)).get());
+        BOOST_CHECK(all(atan2(array1, array2) == std::atan2(fill_value1, fill_value2)).future().get());
     }
 
 }  // namespace detail
diff --git a/source/framework/algorithm/test/atan_test.cpp b/source/framework/algorithm/test/atan_test.cpp
index 9c190c076..e8556caf3 100644
--- a/source/framework/algorithm/test/atan_test.cpp
+++ b/source/framework/algorithm/test/atan_test.cpp
@@ -22,7 +22,7 @@ namespace detail {
 
         Array array{lue::create_partitioned_array(array_shape, partition_shape, fill_value)};
 
-        BOOST_CHECK(all(atan(array) == std::atan(fill_value)).get());
+        BOOST_CHECK(all(atan(array) == std::atan(fill_value)).future().get());
     }
 
 }  // namespace detail
diff --git a/source/framework/algorithm/test/cast_test.cpp b/source/framework/algorithm/test/cast_test.cpp
index 2ba9e8bf6..ea334b68b 100644
--- a/source/framework/algorithm/test/cast_test.cpp
+++ b/source/framework/algorithm/test/cast_test.cpp
@@ -33,7 +33,7 @@ namespace detail {
         auto array_we_got = cast<OutputElement>(array);
         auto array_we_want = lue::array_like(array, static_cast<OutputElement>(fill_value));
 
-        BOOST_CHECK(all(array_we_got == array_we_want).get());
+        BOOST_CHECK(all(array_we_got == array_we_want).future().get());
     }
 
 }  // namespace detail
diff --git a/source/framework/algorithm/test/close_to_test.cpp b/source/framework/algorithm/test/close_to_test.cpp
index f79297349..1dcdff64f 100644
--- a/source/framework/algorithm/test/close_to_test.cpp
+++ b/source/framework/algorithm/test/close_to_test.cpp
@@ -26,24 +26,24 @@ namespace detail {
 
         // Compare two arrays with different values
         {
-            BOOST_CHECK(none(close_to(array1, array2)).get());
+            BOOST_CHECK(none(close_to(array1, array2)).future().get());
         }
 
         // Compare two arrays with the same values
         {
-            BOOST_CHECK(all(close_to(array1, array1)).get());
+            BOOST_CHECK(all(close_to(array1, array1)).future().get());
         }
 
         // Compare array with scalar
         // array == scalar
         {
-            BOOST_CHECK(all(close_to(array1, fill_value1)).get());
+            BOOST_CHECK(all(close_to(array1, fill_value1)).future().get());
         }
 
         // Compare array with scalar
         // scalar == array
         {
-            BOOST_CHECK(all(close_to(fill_value1, array1)).get());
+            BOOST_CHECK(all(close_to(fill_value1, array1)).future().get());
         }
 
         // TODO Add tests with close values
diff --git a/source/framework/algorithm/test/copy_test.cpp b/source/framework/algorithm/test/copy_test.cpp
index 569f37c38..3b306c28d 100644
--- a/source/framework/algorithm/test/copy_test.cpp
+++ b/source/framework/algorithm/test/copy_test.cpp
@@ -24,7 +24,7 @@ namespace detail {
 
         auto copy = lue::copy(array);
 
-        BOOST_CHECK(all(copy == array).get());
+        BOOST_CHECK(all(copy == array).future().get());
     }
 
 }  // namespace detail
diff --git a/source/framework/algorithm/test/cos_test.cpp b/source/framework/algorithm/test/cos_test.cpp
index 995ea8d72..a17f95866 100644
--- a/source/framework/algorithm/test/cos_test.cpp
+++ b/source/framework/algorithm/test/cos_test.cpp
@@ -22,7 +22,7 @@ namespace detail {
 
         Array array{lue::create_partitioned_array(array_shape, partition_shape, fill_value)};
 
-        BOOST_CHECK(all(cos(array) == std::cos(fill_value)).get());
+        BOOST_CHECK(all(cos(array) == std::cos(fill_value)).future().get());
     }
 
 }  // namespace detail
diff --git a/source/framework/algorithm/test/create_partitioned_array_test.cpp b/source/framework/algorithm/test/create_partitioned_array_test.cpp
index 8fb5162c5..c2d76655c 100644
--- a/source/framework/algorithm/test/create_partitioned_array_test.cpp
+++ b/source/framework/algorithm/test/create_partitioned_array_test.cpp
@@ -210,7 +210,7 @@ BOOST_AUTO_TEST_CASE(instantiate_partitions_individually)
     // The number of unique values per partition is 1
     // Per partition a single count >= 0
     lue::PartitionedArray<std::int64_t, 2> counts = lue::partition_count_unique(array);
-    BOOST_CHECK(all(equal_to(counts, std::int64_t{1})).get());
+    BOOST_CHECK(all(equal_to(counts, std::int64_t{1})).future().get());
 
     // The number of unique values in the array equals the number of partitions
     std::set<Element> const unique_values = unique(array).get();
@@ -233,7 +233,7 @@ BOOST_AUTO_TEST_CASE(instantiate_partitions_per_locality)
 
     // The number of unique values per partition is 1
     lue::PartitionedArray<std::int64_t, rank> counts = lue::partition_count_unique(array);
-    BOOST_CHECK(all(equal_to(counts, std::int64_t{1})).get());
+    BOOST_CHECK(all(equal_to(counts, std::int64_t{1})).future().get());
 
     // The number of unique values in the array equals the number of localities
     std::set<Element> const unique_values = unique(array).get();
@@ -298,7 +298,7 @@ BOOST_AUTO_TEST_CASE(use_case_1)
 
     Array array = lue::create_partitioned_array(array_shape, partition_shape, fill_value);
 
-    BOOST_CHECK(all(equal_to(array, fill_value)).get());
+    BOOST_CHECK(all(equal_to(array, fill_value)).future().get());
 }
 
 
@@ -448,7 +448,8 @@ BOOST_AUTO_TEST_CASE(use_case_3)
 
     // In each partition we put a no-data value, so the number of no-data values must be equal
     // to the number of partitions.
-    BOOST_CHECK_EQUAL(lue::default_policies::sum(!valid<std::uint8_t>(array)).get(), array.nr_partitions());
+    BOOST_CHECK_EQUAL(
+        lue::default_policies::sum(!valid<std::uint8_t>(array)).future().get(), array.nr_partitions());
 
     // Now test these explicitly. All other values must then be valid, by definition.
     auto const [nr_partitions0, nr_partitions1] = array.partitions().shape();
diff --git a/source/framework/algorithm/test/divide_test.cpp b/source/framework/algorithm/test/divide_test.cpp
index 1d63b19d2..dba0288b7 100644
--- a/source/framework/algorithm/test/divide_test.cpp
+++ b/source/framework/algorithm/test/divide_test.cpp
@@ -28,7 +28,7 @@ namespace detail {
         {
             auto divide = array1 / array2;
 
-            BOOST_CHECK(all(divide == fill_value1 / fill_value2).get());
+            BOOST_CHECK(all(divide == fill_value1 / fill_value2).future().get());
         }
 
         // Divide scalar by array
@@ -36,7 +36,7 @@ namespace detail {
         {
             auto divide = array1 / fill_value1;
 
-            BOOST_CHECK(all(divide == fill_value1 / fill_value1).get());
+            BOOST_CHECK(all(divide == fill_value1 / fill_value1).future().get());
         }
 
         // Divide scalar by array
@@ -44,7 +44,7 @@ namespace detail {
         {
             auto divide = fill_value1 / array1;
 
-            BOOST_CHECK(all(divide == fill_value1 / fill_value1).get());
+            BOOST_CHECK(all(divide == fill_value1 / fill_value1).future().get());
         }
     }
 
diff --git a/source/framework/algorithm/test/equal_to_test.cpp b/source/framework/algorithm/test/equal_to_test.cpp
index db44412d9..3f266fd2c 100644
--- a/source/framework/algorithm/test/equal_to_test.cpp
+++ b/source/framework/algorithm/test/equal_to_test.cpp
@@ -26,24 +26,24 @@ namespace detail {
 
         // Compare two arrays with different values
         {
-            BOOST_CHECK(none(array1 == array2).get());
+            BOOST_CHECK(none(array1 == array2).future().get());
         }
 
         // Compare two arrays with the same values
         {
-            BOOST_CHECK(all(array1 == array1).get());
+            BOOST_CHECK(all(array1 == array1).future().get());
         }
 
         // Compare array with scalar
         // array == scalar
         {
-            BOOST_CHECK(all(array1 == fill_value1).get());
+            BOOST_CHECK(all(array1 == fill_value1).future().get());
         }
 
         // Compare array with scalar
         // scalar == array
         {
-            BOOST_CHECK(all(fill_value1 == array1).get());
+            BOOST_CHECK(all(fill_value1 == array1).future().get());
         }
     }
 
diff --git a/source/framework/algorithm/test/exp_test.cpp b/source/framework/algorithm/test/exp_test.cpp
index e08cd68f7..c4c1236d8 100644
--- a/source/framework/algorithm/test/exp_test.cpp
+++ b/source/framework/algorithm/test/exp_test.cpp
@@ -25,7 +25,7 @@ namespace detail {
 
         Array array{lue::create_partitioned_array(array_shape, partition_shape, fill_value)};
 
-        BOOST_CHECK(all(exp(array) == std::exp(fill_value)).get());
+        BOOST_CHECK(all(exp(array) == std::exp(fill_value)).future().get());
     }
 
 }  // namespace detail
@@ -59,5 +59,5 @@ BOOST_AUTO_TEST_CASE(out_of_range)
 
     Array array{lue::create_partitioned_array(array_shape, partition_shape, fill_value)};
 
-    BOOST_CHECK(none(valid<std::uint8_t>(exp(array))).get());
+    BOOST_CHECK(none(valid<std::uint8_t>(exp(array))).future().get());
 }
diff --git a/source/framework/algorithm/test/fill_test.cpp b/source/framework/algorithm/test/fill_test.cpp
index 69487911d..3c4f8a5db 100644
--- a/source/framework/algorithm/test/fill_test.cpp
+++ b/source/framework/algorithm/test/fill_test.cpp
@@ -22,11 +22,11 @@ namespace detail {
 
         // Fill the array with a value and check whether all values in the
         // array are equal to this value
-        hpx::shared_future<Element> fill_value = hpx::make_ready_future<Element>(5);
+        Element const fill_value{5};
 
         lue::fill(array, fill_value).get();
 
-        BOOST_CHECK(all(array == fill_value).get());
+        BOOST_CHECK(all(array == fill_value).future().get());
     }
 
 }  // namespace detail
diff --git a/source/framework/algorithm/test/greater_than_equal_to_test.cpp b/source/framework/algorithm/test/greater_than_equal_to_test.cpp
index cebf608d7..2176dc7ff 100644
--- a/source/framework/algorithm/test/greater_than_equal_to_test.cpp
+++ b/source/framework/algorithm/test/greater_than_equal_to_test.cpp
@@ -26,27 +26,27 @@ namespace detail {
 
         // Compare two arrays with different values
         {
-            BOOST_CHECK(all(array2 >= array1).get());
-            BOOST_CHECK(none(array1 >= array2).get());
+            BOOST_CHECK(all(array2 >= array1).future().get());
+            BOOST_CHECK(none(array1 >= array2).future().get());
         }
 
         // Compare two arrays with the same values
         {
-            BOOST_CHECK(all(array2 >= array2).get());
+            BOOST_CHECK(all(array2 >= array2).future().get());
         }
 
         // Compare array with scalar
         // array >= scalar
         {
-            BOOST_CHECK(all(array2 >= fill_value2).get());
-            BOOST_CHECK(none(array1 >= fill_value2).get());
+            BOOST_CHECK(all(array2 >= fill_value2).future().get());
+            BOOST_CHECK(none(array1 >= fill_value2).future().get());
         }
 
         // Compare array with scalar
         // scalar >= array
         {
-            BOOST_CHECK(all(fill_value2 >= array2).get());
-            BOOST_CHECK(none(fill_value1 >= array2).get());
+            BOOST_CHECK(all(fill_value2 >= array2).future().get());
+            BOOST_CHECK(none(fill_value1 >= array2).future().get());
         }
     }
 
diff --git a/source/framework/algorithm/test/greater_than_test.cpp b/source/framework/algorithm/test/greater_than_test.cpp
index 2df516d1c..edfa9b94a 100644
--- a/source/framework/algorithm/test/greater_than_test.cpp
+++ b/source/framework/algorithm/test/greater_than_test.cpp
@@ -26,27 +26,27 @@ namespace detail {
 
         // Compare two arrays with different values
         {
-            BOOST_CHECK(none(array1 > array2).get());
-            BOOST_CHECK(all(array2 > array1).get());
+            BOOST_CHECK(none(array1 > array2).future().get());
+            BOOST_CHECK(all(array2 > array1).future().get());
         }
 
         // Compare two arrays with the same values
         {
-            BOOST_CHECK(none(array2 > array2).get());
+            BOOST_CHECK(none(array2 > array2).future().get());
         }
 
         // Compare array with scalar
         // array < scalar
         {
-            BOOST_CHECK(none(array2 > fill_value2).get());
-            BOOST_CHECK(all(array2 > fill_value1).get());
+            BOOST_CHECK(none(array2 > fill_value2).future().get());
+            BOOST_CHECK(all(array2 > fill_value1).future().get());
         }
 
         // Compare array with scalar
         // scalar < array
         {
-            BOOST_CHECK(none(fill_value2 > array2).get());
-            BOOST_CHECK(all(fill_value2 > array1).get());
+            BOOST_CHECK(none(fill_value2 > array2).future().get());
+            BOOST_CHECK(all(fill_value2 > array1).future().get());
         }
     }
 
diff --git a/source/framework/algorithm/test/iterate_per_element_test.cpp b/source/framework/algorithm/test/iterate_per_element_test.cpp
index 48d71bc22..fe0be972b 100644
--- a/source/framework/algorithm/test/iterate_per_element_test.cpp
+++ b/source/framework/algorithm/test/iterate_per_element_test.cpp
@@ -29,7 +29,7 @@ namespace detail {
 
         auto copy = lue::iterate_per_element(array);
 
-        BOOST_CHECK(all(copy == array).get());
+        BOOST_CHECK(all(copy == array).future().get());
     }
 
 }  // namespace detail
diff --git a/source/framework/algorithm/test/kinematic_wave_test.cpp b/source/framework/algorithm/test/kinematic_wave_test.cpp
index 5a00bf4c0..f324ba349 100644
--- a/source/framework/algorithm/test/kinematic_wave_test.cpp
+++ b/source/framework/algorithm/test/kinematic_wave_test.cpp
@@ -112,7 +112,7 @@ BOOST_AUTO_TEST_CASE(non_zero_discharge_and_zero_inflow)
 
     using namespace lue::value_policies;
 
-    BOOST_CHECK(lue::value_policies::all(new_discharge > Element{0}).get());
+    BOOST_CHECK(lue::value_policies::all(new_discharge > Element{0}).future().get());
 }
 
 
@@ -139,7 +139,7 @@ BOOST_AUTO_TEST_CASE(zero_discharge_and_non_zero_inflow)
 
     using namespace lue::value_policies;
 
-    BOOST_CHECK(lue::value_policies::all(new_discharge > Element{0}).get());
+    BOOST_CHECK(lue::value_policies::all(new_discharge > Element{0}).future().get());
 }
 
 
diff --git a/source/framework/algorithm/test/less_than_equal_to_test.cpp b/source/framework/algorithm/test/less_than_equal_to_test.cpp
index 7463c80f5..4ebd7e5bf 100644
--- a/source/framework/algorithm/test/less_than_equal_to_test.cpp
+++ b/source/framework/algorithm/test/less_than_equal_to_test.cpp
@@ -26,27 +26,27 @@ namespace detail {
 
         // Compare two arrays with different values
         {
-            BOOST_CHECK(all(array1 <= array2).get());
-            BOOST_CHECK(none(array2 <= array1).get());
+            BOOST_CHECK(all(array1 <= array2).future().get());
+            BOOST_CHECK(none(array2 <= array1).future().get());
         }
 
         // Compare two arrays with the same values
         {
-            BOOST_CHECK(all(array2 <= array2).get());
+            BOOST_CHECK(all(array2 <= array2).future().get());
         }
 
         // Compare array with scalar
         // array <= scalar
         {
-            BOOST_CHECK(all(array1 <= fill_value2).get());
-            BOOST_CHECK(none(array2 <= fill_value1).get());
+            BOOST_CHECK(all(array1 <= fill_value2).future().get());
+            BOOST_CHECK(none(array2 <= fill_value1).future().get());
         }
 
         // Compare array with scalar
         // scalar <= array
         {
-            BOOST_CHECK(all(fill_value2 <= array2).get());
-            BOOST_CHECK(none(fill_value2 <= array1).get());
+            BOOST_CHECK(all(fill_value2 <= array2).future().get());
+            BOOST_CHECK(none(fill_value2 <= array1).future().get());
         }
     }
 
diff --git a/source/framework/algorithm/test/less_than_test.cpp b/source/framework/algorithm/test/less_than_test.cpp
index c65ebf9c5..b3ff6ec5e 100644
--- a/source/framework/algorithm/test/less_than_test.cpp
+++ b/source/framework/algorithm/test/less_than_test.cpp
@@ -26,27 +26,27 @@ namespace detail {
 
         // Compare two arrays with different values
         {
-            BOOST_CHECK(all(array1 < array2).get());
-            BOOST_CHECK(none(array2 < array1).get());
+            BOOST_CHECK(all(array1 < array2).future().get());
+            BOOST_CHECK(none(array2 < array1).future().get());
         }
 
         // Compare two arrays with the same values
         {
-            BOOST_CHECK(none(array2 < array2).get());
+            BOOST_CHECK(none(array2 < array2).future().get());
         }
 
         // Compare array with scalar
         // array < scalar
         {
-            BOOST_CHECK(none(array2 < fill_value2).get());
-            BOOST_CHECK(all(array1 < fill_value2).get());
+            BOOST_CHECK(none(array2 < fill_value2).future().get());
+            BOOST_CHECK(all(array1 < fill_value2).future().get());
         }
 
         // Compare array with scalar
         // scalar < array
         {
-            BOOST_CHECK(none(fill_value2 < array2).get());
-            BOOST_CHECK(all(fill_value1 < array2).get());
+            BOOST_CHECK(none(fill_value2 < array2).future().get());
+            BOOST_CHECK(all(fill_value1 < array2).future().get());
         }
     }
 
diff --git a/source/framework/algorithm/test/log10_test.cpp b/source/framework/algorithm/test/log10_test.cpp
index 1c81d8690..c3e589f65 100644
--- a/source/framework/algorithm/test/log10_test.cpp
+++ b/source/framework/algorithm/test/log10_test.cpp
@@ -21,7 +21,7 @@ namespace detail {
 
         Array array{lue::create_partitioned_array(array_shape, partition_shape, Element{25})};
 
-        BOOST_CHECK(all(log10(array) == std::log10(Element{25})).get());
+        BOOST_CHECK(all(log10(array) == std::log10(Element{25})).future().get());
     }
 
 }  // namespace detail
diff --git a/source/framework/algorithm/test/log_test.cpp b/source/framework/algorithm/test/log_test.cpp
index f0d1ea5be..f3e6ea951 100644
--- a/source/framework/algorithm/test/log_test.cpp
+++ b/source/framework/algorithm/test/log_test.cpp
@@ -20,7 +20,7 @@ namespace detail {
 
         Array array{lue::create_partitioned_array(array_shape, partition_shape, Element{25})};
 
-        BOOST_CHECK(all(log(array) == std::log(Element{25})).get());
+        BOOST_CHECK(all(log(array) == std::log(Element{25})).future().get());
     }
 
 }  // namespace detail
diff --git a/source/framework/algorithm/test/logical_and_test.cpp b/source/framework/algorithm/test/logical_and_test.cpp
index 70a139a99..4dd7a2791 100644
--- a/source/framework/algorithm/test/logical_and_test.cpp
+++ b/source/framework/algorithm/test/logical_and_test.cpp
@@ -26,21 +26,21 @@ namespace detail {
 
         // array && array
         {
-            BOOST_CHECK(none(array1 && array2).get());  // true && false
-            BOOST_CHECK(all(array1 && array1).get());   // true && true
-            BOOST_CHECK(none(array2 && array2).get());  // false && false
+            BOOST_CHECK(none(array1 && array2).future().get());  // true && false
+            BOOST_CHECK(all(array1 && array1).future().get());   // true && true
+            BOOST_CHECK(none(array2 && array2).future().get());  // false && false
         }
 
         // array && scalar
         {
-            BOOST_CHECK(all(array1 && fill_value1).get());
-            BOOST_CHECK(none(array1 && fill_value2).get());
+            BOOST_CHECK(all(array1 && fill_value1).future().get());
+            BOOST_CHECK(none(array1 && fill_value2).future().get());
         }
 
         // scalar && array
         {
-            BOOST_CHECK(all(fill_value1 && array1).get());
-            BOOST_CHECK(none(fill_value2 && array1).get());
+            BOOST_CHECK(all(fill_value1 && array1).future().get());
+            BOOST_CHECK(none(fill_value2 && array1).future().get());
         }
     }
 
diff --git a/source/framework/algorithm/test/logical_exclusive_or_test.cpp b/source/framework/algorithm/test/logical_exclusive_or_test.cpp
index bd3a2577d..c0a1a83bf 100644
--- a/source/framework/algorithm/test/logical_exclusive_or_test.cpp
+++ b/source/framework/algorithm/test/logical_exclusive_or_test.cpp
@@ -26,21 +26,21 @@ namespace detail {
 
         // array || array
         {
-            BOOST_CHECK(all(logical_exclusive_or(array1, array2)).get());   // true || false
-            BOOST_CHECK(none(logical_exclusive_or(array1, array1)).get());  // true || true
-            BOOST_CHECK(none(logical_exclusive_or(array2, array2)).get());  // false || false
+            BOOST_CHECK(all(logical_exclusive_or(array1, array2)).future().get());   // true || false
+            BOOST_CHECK(none(logical_exclusive_or(array1, array1)).future().get());  // true || true
+            BOOST_CHECK(none(logical_exclusive_or(array2, array2)).future().get());  // false || false
         }
 
         // array || scalar
         {
-            BOOST_CHECK(none(logical_exclusive_or(array1, fill_value1)).get());
-            BOOST_CHECK(all(logical_exclusive_or(array1, fill_value2)).get());
+            BOOST_CHECK(none(logical_exclusive_or(array1, fill_value1)).future().get());
+            BOOST_CHECK(all(logical_exclusive_or(array1, fill_value2)).future().get());
         }
 
         // scalar || array
         {
-            BOOST_CHECK(none(logical_exclusive_or(fill_value1, array1)).get());
-            BOOST_CHECK(all(logical_exclusive_or(fill_value2, array1)).get());
+            BOOST_CHECK(none(logical_exclusive_or(fill_value1, array1)).future().get());
+            BOOST_CHECK(all(logical_exclusive_or(fill_value2, array1)).future().get());
         }
     }
 
diff --git a/source/framework/algorithm/test/logical_inclusive_or_test.cpp b/source/framework/algorithm/test/logical_inclusive_or_test.cpp
index 6708449ab..bd611b092 100644
--- a/source/framework/algorithm/test/logical_inclusive_or_test.cpp
+++ b/source/framework/algorithm/test/logical_inclusive_or_test.cpp
@@ -26,21 +26,21 @@ namespace detail {
 
         // array || array
         {
-            BOOST_CHECK(all(array1 || array2).get());   // true || false
-            BOOST_CHECK(all(array1 || array1).get());   // true || true
-            BOOST_CHECK(none(array2 || array2).get());  // false || false
+            BOOST_CHECK(all(array1 || array2).future().get());   // true || false
+            BOOST_CHECK(all(array1 || array1).future().get());   // true || true
+            BOOST_CHECK(none(array2 || array2).future().get());  // false || false
         }
 
         // array || scalar
         {
-            BOOST_CHECK(all(array1 || fill_value1).get());
-            BOOST_CHECK(all(array1 || fill_value2).get());
+            BOOST_CHECK(all(array1 || fill_value1).future().get());
+            BOOST_CHECK(all(array1 || fill_value2).future().get());
         }
 
         // scalar || array
         {
-            BOOST_CHECK(all(fill_value1 || array1).get());
-            BOOST_CHECK(all(fill_value2 || array1).get());
+            BOOST_CHECK(all(fill_value1 || array1).future().get());
+            BOOST_CHECK(all(fill_value2 || array1).future().get());
         }
     }
 
diff --git a/source/framework/algorithm/test/logical_not_test.cpp b/source/framework/algorithm/test/logical_not_test.cpp
index 5669a7407..da777441d 100644
--- a/source/framework/algorithm/test/logical_not_test.cpp
+++ b/source/framework/algorithm/test/logical_not_test.cpp
@@ -26,8 +26,8 @@ namespace detail {
 
         // !array
         {
-            BOOST_CHECK(none(!array1).get());  // !true
-            BOOST_CHECK(all(!array2).get());   // !false
+            BOOST_CHECK(none(!array1).future().get());  // !true
+            BOOST_CHECK(all(!array2).future().get());   // !false
         }
     }
 
diff --git a/source/framework/algorithm/test/maximum_test.cpp b/source/framework/algorithm/test/maximum_test.cpp
index 873e64d1e..9bc8482d7 100644
--- a/source/framework/algorithm/test/maximum_test.cpp
+++ b/source/framework/algorithm/test/maximum_test.cpp
@@ -21,7 +21,7 @@ namespace detail {
 
         lue::range(array, Element{0}).get();
 
-        BOOST_CHECK_EQUAL(maximum(array).get(), lue::nr_elements(array_shape) - 1);
+        BOOST_CHECK_EQUAL(maximum(array).future().get(), lue::nr_elements(array_shape) - 1);
     }
 
 }  // namespace detail
diff --git a/source/framework/algorithm/test/minimum_test.cpp b/source/framework/algorithm/test/minimum_test.cpp
index 74cad278a..14856920b 100644
--- a/source/framework/algorithm/test/minimum_test.cpp
+++ b/source/framework/algorithm/test/minimum_test.cpp
@@ -21,7 +21,7 @@ namespace detail {
 
         lue::range(array, Element{5}).get();
 
-        BOOST_CHECK_EQUAL(minimum(array).get(), Element{5});
+        BOOST_CHECK_EQUAL(minimum(array).future().get(), Element{5});
     }
 
 }  // namespace detail
diff --git a/source/framework/algorithm/test/multiply_test.cpp b/source/framework/algorithm/test/multiply_test.cpp
index 87f0da89d..c06a7e3d8 100644
--- a/source/framework/algorithm/test/multiply_test.cpp
+++ b/source/framework/algorithm/test/multiply_test.cpp
@@ -32,7 +32,7 @@ namespace detail {
             auto multiply = array1 * array2;
             auto equal_to = multiply == fill_value1 * fill_value2;
 
-            BOOST_CHECK(all(equal_to).get());
+            BOOST_CHECK(all(equal_to).future().get());
         }
 
         // Multiply scalar with array
@@ -41,7 +41,7 @@ namespace detail {
             auto multiply = array1 * fill_value1;
             auto equal_to = multiply == fill_value1 * fill_value1;
 
-            BOOST_CHECK(all(equal_to).get());
+            BOOST_CHECK(all(equal_to).future().get());
         }
 
         // Multiply scalar with array
@@ -50,7 +50,7 @@ namespace detail {
             auto multiply = fill_value1 * array1;
             auto equal_to = multiply == fill_value1 * fill_value1;
 
-            BOOST_CHECK(all(equal_to).get());
+            BOOST_CHECK(all(equal_to).future().get());
         }
     }
 
@@ -92,7 +92,7 @@ BOOST_AUTO_TEST_CASE(out_of_range)
 
     Array array{lue::create_partitioned_array(array_shape, partition_shape, fill_value)};
 
-    BOOST_CHECK(none(valid<std::uint8_t>(2 * array)).get());
-    BOOST_CHECK(none(valid<std::uint8_t>(array * 2)).get());
-    BOOST_CHECK(none(valid<std::uint8_t>(array * array)).get());
+    BOOST_CHECK(none(valid<std::uint8_t>(2 * array)).future().get());
+    BOOST_CHECK(none(valid<std::uint8_t>(array * 2)).future().get());
+    BOOST_CHECK(none(valid<std::uint8_t>(array * array)).future().get());
 }
diff --git a/source/framework/algorithm/test/negate_test.cpp b/source/framework/algorithm/test/negate_test.cpp
index b5f9915eb..78a00fbda 100644
--- a/source/framework/algorithm/test/negate_test.cpp
+++ b/source/framework/algorithm/test/negate_test.cpp
@@ -25,8 +25,8 @@ namespace detail {
 
         Array array{lue::create_partitioned_array(array_shape, partition_shape, Element{-5})};
 
-        BOOST_CHECK(all(negate(array) == Element{5}).get());
-        BOOST_CHECK(all(negate(negate(array)) == Element{-5}).get());
+        BOOST_CHECK(all(negate(array) == Element{5}).future().get());
+        BOOST_CHECK(all(negate(negate(array)) == Element{-5}).future().get());
     }
 
 }  // namespace detail
diff --git a/source/framework/algorithm/test/none_test.cpp b/source/framework/algorithm/test/none_test.cpp
index 90aa5cf5d..978a0123f 100644
--- a/source/framework/algorithm/test/none_test.cpp
+++ b/source/framework/algorithm/test/none_test.cpp
@@ -22,8 +22,8 @@ namespace detail {
         Array array1{lue::create_partitioned_array(array_shape, partition_shape, fill_value1)};
         Array array2{lue::create_partitioned_array(array_shape, partition_shape, fill_value2)};
 
-        BOOST_CHECK_EQUAL(none(array1).get(), Element{0});  // false
-        BOOST_CHECK_EQUAL(none(array2).get(), Element{1});  // true
+        BOOST_CHECK_EQUAL(none(array1).future().get(), Element{0});  // false
+        BOOST_CHECK_EQUAL(none(array2).future().get(), Element{1});  // true
     }
 
 }  // namespace detail
diff --git a/source/framework/algorithm/test/normal_test.cpp b/source/framework/algorithm/test/normal_test.cpp
index 014df89f2..7fc7df4ba 100644
--- a/source/framework/algorithm/test/normal_test.cpp
+++ b/source/framework/algorithm/test/normal_test.cpp
@@ -32,8 +32,8 @@ namespace detail {
 
         array = normal(array, mean, stddev);
 
-        BOOST_CHECK(all(array > mean - (10 * stddev)).get());
-        BOOST_CHECK(all(array < mean + (10 * stddev)).get());
+        BOOST_CHECK(all(array > mean - (10 * stddev)).future().get());
+        BOOST_CHECK(all(array < mean + (10 * stddev)).future().get());
     }
 
 }  // namespace detail
@@ -85,6 +85,6 @@ BOOST_AUTO_TEST_CASE(use_case_1)
 
     Array array = normal(array_shape, partition_shape, mean, stddev);
 
-    BOOST_CHECK(all(array > mean - (10 * stddev)).get());
-    BOOST_CHECK(all(array < mean + (10 * stddev)).get());
+    BOOST_CHECK(all(array > mean - (10 * stddev)).future().get());
+    BOOST_CHECK(all(array < mean + (10 * stddev)).future().get());
 }
diff --git a/source/framework/algorithm/test/not_equal_to_test.cpp b/source/framework/algorithm/test/not_equal_to_test.cpp
index ee45c6193..6a3478bc1 100644
--- a/source/framework/algorithm/test/not_equal_to_test.cpp
+++ b/source/framework/algorithm/test/not_equal_to_test.cpp
@@ -26,24 +26,24 @@ namespace detail {
 
         // Compare two arrays with different values
         {
-            BOOST_CHECK(all(array1 != array2).get());
+            BOOST_CHECK(all(array1 != array2).future().get());
         }
 
         // Compare two arrays with the same values
         {
-            BOOST_CHECK(none(array1 != array1).get());
+            BOOST_CHECK(none(array1 != array1).future().get());
         }
 
         // Compare array with scalar
         // array != scalar
         {
-            BOOST_CHECK(all(array1 != fill_value2).get());
+            BOOST_CHECK(all(array1 != fill_value2).future().get());
         }
 
         // Compare array with scalar
         // scalar != array
         {
-            BOOST_CHECK(all(fill_value2 != array1).get());
+            BOOST_CHECK(all(fill_value2 != array1).future().get());
         }
     }
 
diff --git a/source/framework/algorithm/test/pow_test.cpp b/source/framework/algorithm/test/pow_test.cpp
index ddd0d4fd4..65ac37e92 100644
--- a/source/framework/algorithm/test/pow_test.cpp
+++ b/source/framework/algorithm/test/pow_test.cpp
@@ -23,9 +23,9 @@ namespace detail {
 
         Array array{lue::create_partitioned_array(array_shape, partition_shape, fill_value)};
 
-        auto pow = lue::pow(array, exponent);
+        auto pow = lue::default_policies::pow(array, exponent);
 
-        BOOST_CHECK(all(pow == std::pow(fill_value, exponent)).get());
+        BOOST_CHECK(all(pow == std::pow(fill_value, exponent)).future().get());
     }
 
 }  // namespace detail
diff --git a/source/framework/algorithm/test/scalar_test.cpp b/source/framework/algorithm/test/scalar_test.cpp
index afd9c1223..c9342c9d3 100644
--- a/source/framework/algorithm/test/scalar_test.cpp
+++ b/source/framework/algorithm/test/scalar_test.cpp
@@ -9,27 +9,27 @@ BOOST_AUTO_TEST_CASE(default_construct)
         using Element = std::uint8_t;
 
         lue::Scalar<Element> scalar{};
-        BOOST_CHECK(scalar.value().valid());
-        BOOST_CHECK(scalar.value().is_ready());
-        BOOST_CHECK_EQUAL(scalar.value().get(), Element{0});
+        BOOST_CHECK(scalar.future().valid());
+        BOOST_CHECK(scalar.future().is_ready());
+        BOOST_CHECK_EQUAL(scalar.future().get(), Element{0});
     }
 
     {
         using Element = float;
 
         lue::Scalar<Element> scalar{};
-        BOOST_CHECK(scalar.value().valid());
-        BOOST_CHECK(scalar.value().is_ready());
-        BOOST_CHECK_EQUAL(scalar.value().get(), Element{0});
+        BOOST_CHECK(scalar.future().valid());
+        BOOST_CHECK(scalar.future().is_ready());
+        BOOST_CHECK_EQUAL(scalar.future().get(), Element{0});
     }
 
     {
         using Element = std::string;
 
         lue::Scalar<Element> scalar{};
-        BOOST_CHECK(scalar.value().valid());
-        BOOST_CHECK(scalar.value().is_ready());
-        BOOST_CHECK_EQUAL(scalar.value().get(), "");
+        BOOST_CHECK(scalar.future().valid());
+        BOOST_CHECK(scalar.future().is_ready());
+        BOOST_CHECK_EQUAL(scalar.future().get(), "");
     }
 }
 
@@ -42,13 +42,13 @@ BOOST_AUTO_TEST_CASE(copy_construct)
         lue::Scalar<Element> scalar_from{5};
         lue::Scalar<Element> scalar_to{scalar_from};
 
-        BOOST_CHECK(scalar_to.value().valid());
-        BOOST_CHECK(scalar_to.value().is_ready());
-        BOOST_CHECK_EQUAL(scalar_to.value().get(), Element{5});
+        BOOST_CHECK(scalar_to.future().valid());
+        BOOST_CHECK(scalar_to.future().is_ready());
+        BOOST_CHECK_EQUAL(scalar_to.future().get(), Element{5});
 
-        BOOST_CHECK(scalar_from.value().valid());
-        BOOST_CHECK(scalar_from.value().is_ready());
-        BOOST_CHECK_EQUAL(scalar_from.value().get(), Element{5});
+        BOOST_CHECK(scalar_from.future().valid());
+        BOOST_CHECK(scalar_from.future().is_ready());
+        BOOST_CHECK_EQUAL(scalar_from.future().get(), Element{5});
     }
 
     {
@@ -57,13 +57,13 @@ BOOST_AUTO_TEST_CASE(copy_construct)
         lue::Scalar<Element> scalar_from{5};
         lue::Scalar<Element> scalar_to{scalar_from};
 
-        BOOST_CHECK(scalar_to.value().valid());
-        BOOST_CHECK(scalar_to.value().is_ready());
-        BOOST_CHECK_EQUAL(scalar_to.value().get(), Element{5});
+        BOOST_CHECK(scalar_to.future().valid());
+        BOOST_CHECK(scalar_to.future().is_ready());
+        BOOST_CHECK_EQUAL(scalar_to.future().get(), Element{5});
 
-        BOOST_CHECK(scalar_from.value().valid());
-        BOOST_CHECK(scalar_from.value().is_ready());
-        BOOST_CHECK_EQUAL(scalar_from.value().get(), Element{5});
+        BOOST_CHECK(scalar_from.future().valid());
+        BOOST_CHECK(scalar_from.future().is_ready());
+        BOOST_CHECK_EQUAL(scalar_from.future().get(), Element{5});
     }
 
     {
@@ -72,13 +72,13 @@ BOOST_AUTO_TEST_CASE(copy_construct)
         lue::Scalar<Element> scalar_from{"5"};
         lue::Scalar<Element> scalar_to{scalar_from};
 
-        BOOST_CHECK(scalar_to.value().valid());
-        BOOST_CHECK(scalar_to.value().is_ready());
-        BOOST_CHECK_EQUAL(scalar_to.value().get(), "5");
+        BOOST_CHECK(scalar_to.future().valid());
+        BOOST_CHECK(scalar_to.future().is_ready());
+        BOOST_CHECK_EQUAL(scalar_to.future().get(), "5");
 
-        BOOST_CHECK(scalar_from.value().valid());
-        BOOST_CHECK(scalar_from.value().is_ready());
-        BOOST_CHECK_EQUAL(scalar_from.value().get(), "5");
+        BOOST_CHECK(scalar_from.future().valid());
+        BOOST_CHECK(scalar_from.future().is_ready());
+        BOOST_CHECK_EQUAL(scalar_from.future().get(), "5");
     }
 }
 
@@ -91,11 +91,11 @@ BOOST_AUTO_TEST_CASE(move_construct)
         lue::Scalar<Element> scalar_from{5};
         lue::Scalar<Element> scalar_to{std::move(scalar_from)};
 
-        BOOST_CHECK(scalar_to.value().valid());
-        BOOST_CHECK(scalar_to.value().is_ready());
-        BOOST_CHECK_EQUAL(scalar_to.value().get(), Element{5});
+        BOOST_CHECK(scalar_to.future().valid());
+        BOOST_CHECK(scalar_to.future().is_ready());
+        BOOST_CHECK_EQUAL(scalar_to.future().get(), Element{5});
 
-        BOOST_CHECK(!scalar_from.value().valid());
+        BOOST_CHECK(!scalar_from.future().valid());
     }
 
     {
@@ -104,11 +104,11 @@ BOOST_AUTO_TEST_CASE(move_construct)
         lue::Scalar<Element> scalar_from{5};
         lue::Scalar<Element> scalar_to{std::move(scalar_from)};
 
-        BOOST_CHECK(scalar_to.value().valid());
-        BOOST_CHECK(scalar_to.value().is_ready());
-        BOOST_CHECK_EQUAL(scalar_to.value().get(), Element{5});
+        BOOST_CHECK(scalar_to.future().valid());
+        BOOST_CHECK(scalar_to.future().is_ready());
+        BOOST_CHECK_EQUAL(scalar_to.future().get(), Element{5});
 
-        BOOST_CHECK(!scalar_from.value().valid());
+        BOOST_CHECK(!scalar_from.future().valid());
     }
 
     {
@@ -117,11 +117,11 @@ BOOST_AUTO_TEST_CASE(move_construct)
         lue::Scalar<Element> scalar_from{"5"};
         lue::Scalar<Element> scalar_to{std::move(scalar_from)};
 
-        BOOST_CHECK(scalar_to.value().valid());
-        BOOST_CHECK(scalar_to.value().is_ready());
-        BOOST_CHECK_EQUAL(scalar_to.value().get(), "5");
+        BOOST_CHECK(scalar_to.future().valid());
+        BOOST_CHECK(scalar_to.future().is_ready());
+        BOOST_CHECK_EQUAL(scalar_to.future().get(), "5");
 
-        BOOST_CHECK(!scalar_from.value().valid());
+        BOOST_CHECK(!scalar_from.future().valid());
     }
 }
 
@@ -133,9 +133,9 @@ BOOST_AUTO_TEST_CASE(convert_construct)
 
         lue::Scalar<Element> scalar{5};
 
-        BOOST_CHECK(scalar.value().valid());
-        BOOST_CHECK(scalar.value().is_ready());
-        BOOST_CHECK_EQUAL(scalar.value().get(), Element{5});
+        BOOST_CHECK(scalar.future().valid());
+        BOOST_CHECK(scalar.future().is_ready());
+        BOOST_CHECK_EQUAL(scalar.future().get(), Element{5});
     }
 
     {
@@ -143,9 +143,9 @@ BOOST_AUTO_TEST_CASE(convert_construct)
 
         lue::Scalar<Element> scalar{5};
 
-        BOOST_CHECK(scalar.value().valid());
-        BOOST_CHECK(scalar.value().is_ready());
-        BOOST_CHECK_EQUAL(scalar.value().get(), Element{5});
+        BOOST_CHECK(scalar.future().valid());
+        BOOST_CHECK(scalar.future().is_ready());
+        BOOST_CHECK_EQUAL(scalar.future().get(), Element{5});
     }
 
     {
@@ -153,9 +153,9 @@ BOOST_AUTO_TEST_CASE(convert_construct)
 
         lue::Scalar<Element> scalar{"5"};
 
-        BOOST_CHECK(scalar.value().valid());
-        BOOST_CHECK(scalar.value().is_ready());
-        BOOST_CHECK_EQUAL(scalar.value().get(), "5");
+        BOOST_CHECK(scalar.future().valid());
+        BOOST_CHECK(scalar.future().is_ready());
+        BOOST_CHECK_EQUAL(scalar.future().get(), "5");
     }
 }
 
@@ -169,13 +169,13 @@ BOOST_AUTO_TEST_CASE(copy_assign)
         lue::Scalar<Element> scalar_to{};
         scalar_to = scalar_from;
 
-        BOOST_CHECK(scalar_to.value().valid());
-        BOOST_CHECK(scalar_to.value().is_ready());
-        BOOST_CHECK_EQUAL(scalar_to.value().get(), Element{5});
+        BOOST_CHECK(scalar_to.future().valid());
+        BOOST_CHECK(scalar_to.future().is_ready());
+        BOOST_CHECK_EQUAL(scalar_to.future().get(), Element{5});
 
-        BOOST_CHECK(scalar_from.value().valid());
-        BOOST_CHECK(scalar_from.value().is_ready());
-        BOOST_CHECK_EQUAL(scalar_from.value().get(), Element{5});
+        BOOST_CHECK(scalar_from.future().valid());
+        BOOST_CHECK(scalar_from.future().is_ready());
+        BOOST_CHECK_EQUAL(scalar_from.future().get(), Element{5});
     }
 
     {
@@ -185,13 +185,13 @@ BOOST_AUTO_TEST_CASE(copy_assign)
         lue::Scalar<Element> scalar_to{};
         scalar_to = scalar_from;
 
-        BOOST_CHECK(scalar_to.value().valid());
-        BOOST_CHECK(scalar_to.value().is_ready());
-        BOOST_CHECK_EQUAL(scalar_to.value().get(), Element{5});
+        BOOST_CHECK(scalar_to.future().valid());
+        BOOST_CHECK(scalar_to.future().is_ready());
+        BOOST_CHECK_EQUAL(scalar_to.future().get(), Element{5});
 
-        BOOST_CHECK(scalar_from.value().valid());
-        BOOST_CHECK(scalar_from.value().is_ready());
-        BOOST_CHECK_EQUAL(scalar_from.value().get(), Element{5});
+        BOOST_CHECK(scalar_from.future().valid());
+        BOOST_CHECK(scalar_from.future().is_ready());
+        BOOST_CHECK_EQUAL(scalar_from.future().get(), Element{5});
     }
 
     {
@@ -201,13 +201,13 @@ BOOST_AUTO_TEST_CASE(copy_assign)
         lue::Scalar<Element> scalar_to{};
         scalar_to = scalar_from;
 
-        BOOST_CHECK(scalar_to.value().valid());
-        BOOST_CHECK(scalar_to.value().is_ready());
-        BOOST_CHECK_EQUAL(scalar_to.value().get(), "5");
+        BOOST_CHECK(scalar_to.future().valid());
+        BOOST_CHECK(scalar_to.future().is_ready());
+        BOOST_CHECK_EQUAL(scalar_to.future().get(), "5");
 
-        BOOST_CHECK(scalar_from.value().valid());
-        BOOST_CHECK(scalar_from.value().is_ready());
-        BOOST_CHECK_EQUAL(scalar_from.value().get(), "5");
+        BOOST_CHECK(scalar_from.future().valid());
+        BOOST_CHECK(scalar_from.future().is_ready());
+        BOOST_CHECK_EQUAL(scalar_from.future().get(), "5");
     }
 }
 
@@ -221,11 +221,11 @@ BOOST_AUTO_TEST_CASE(move_assign)
         lue::Scalar<Element> scalar_to{};
         scalar_to = std::move(scalar_from);
 
-        BOOST_CHECK(scalar_to.value().valid());
-        BOOST_CHECK(scalar_to.value().is_ready());
-        BOOST_CHECK_EQUAL(scalar_to.value().get(), Element{5});
+        BOOST_CHECK(scalar_to.future().valid());
+        BOOST_CHECK(scalar_to.future().is_ready());
+        BOOST_CHECK_EQUAL(scalar_to.future().get(), Element{5});
 
-        BOOST_CHECK(!scalar_from.value().valid());
+        BOOST_CHECK(!scalar_from.future().valid());
     }
 
     {
@@ -235,11 +235,11 @@ BOOST_AUTO_TEST_CASE(move_assign)
         lue::Scalar<Element> scalar_to{};
         scalar_to = std::move(scalar_from);
 
-        BOOST_CHECK(scalar_to.value().valid());
-        BOOST_CHECK(scalar_to.value().is_ready());
-        BOOST_CHECK_EQUAL(scalar_to.value().get(), Element{5});
+        BOOST_CHECK(scalar_to.future().valid());
+        BOOST_CHECK(scalar_to.future().is_ready());
+        BOOST_CHECK_EQUAL(scalar_to.future().get(), Element{5});
 
-        BOOST_CHECK(!scalar_from.value().valid());
+        BOOST_CHECK(!scalar_from.future().valid());
     }
 
     {
@@ -249,11 +249,11 @@ BOOST_AUTO_TEST_CASE(move_assign)
         lue::Scalar<Element> scalar_to{};
         scalar_to = std::move(scalar_from);
 
-        BOOST_CHECK(scalar_to.value().valid());
-        BOOST_CHECK(scalar_to.value().is_ready());
-        BOOST_CHECK_EQUAL(scalar_to.value().get(), "5");
+        BOOST_CHECK(scalar_to.future().valid());
+        BOOST_CHECK(scalar_to.future().is_ready());
+        BOOST_CHECK_EQUAL(scalar_to.future().get(), "5");
 
-        BOOST_CHECK(!scalar_from.value().valid());
+        BOOST_CHECK(!scalar_from.future().valid());
     }
 }
 
@@ -264,7 +264,7 @@ BOOST_AUTO_TEST_CASE(continuation)
 
     lue::Scalar<Element> greating1{"Hello"};
     lue::Scalar<Element> greating2 =
-        greating1.value().then([](auto const& value) -> Element { return value.get() + " " + "World!"; });
+        greating1.future().then([](auto const& value) -> Element { return value.get() + " " + "World!"; });
 
     // Make the layered value (a shared future) go out of scope (not necessary for the
     // test). Shared futures can be copied. greating1's future is copied into the continuation,
@@ -272,7 +272,7 @@ BOOST_AUTO_TEST_CASE(continuation)
     // a different one.
     greating1 = lue::Scalar<Element>{};
 
-    BOOST_CHECK_EQUAL(greating2.value().get(), Element{"Hello World!"});
+    BOOST_CHECK_EQUAL(greating2.future().get(), Element{"Hello World!"});
 }
 
 
diff --git a/source/framework/algorithm/test/sin_test.cpp b/source/framework/algorithm/test/sin_test.cpp
index 76a177e28..4572f04e0 100644
--- a/source/framework/algorithm/test/sin_test.cpp
+++ b/source/framework/algorithm/test/sin_test.cpp
@@ -22,7 +22,7 @@ namespace detail {
 
         Array array{lue::create_partitioned_array(array_shape, partition_shape, fill_value)};
 
-        BOOST_CHECK(all(sin(array) == std::sin(fill_value)).get());
+        BOOST_CHECK(all(sin(array) == std::sin(fill_value)).future().get());
     }
 
 }  // namespace detail
diff --git a/source/framework/algorithm/test/sqrt_test.cpp b/source/framework/algorithm/test/sqrt_test.cpp
index 988f76f38..e5224fa14 100644
--- a/source/framework/algorithm/test/sqrt_test.cpp
+++ b/source/framework/algorithm/test/sqrt_test.cpp
@@ -22,7 +22,7 @@ namespace detail {
 
         // FIXME Test by taking a diff from known values and asserting that
         //     the difference is small enough
-        BOOST_CHECK(all(sqrt(array) == Element{5}).get());
+        BOOST_CHECK(all(sqrt(array) == Element{5}).future().get());
     }
 
 }  // namespace detail
diff --git a/source/framework/algorithm/test/subtract_test.cpp b/source/framework/algorithm/test/subtract_test.cpp
index 2429fa9e3..8ffc1dc1a 100644
--- a/source/framework/algorithm/test/subtract_test.cpp
+++ b/source/framework/algorithm/test/subtract_test.cpp
@@ -29,7 +29,7 @@ namespace detail {
 
         auto subtract = array1 - array2;
 
-        BOOST_CHECK(all(subtract == fill_value1 - fill_value2).get());
+        BOOST_CHECK(all(subtract == fill_value1 - fill_value2).future().get());
     }
 
 }  // namespace detail
@@ -71,7 +71,8 @@ BOOST_AUTO_TEST_CASE(out_of_range)
     Array array{lue::create_partitioned_array(array_shape, partition_shape, fill_value)};
 
     // Careful. The default no-data value for int32_t is the lowest value.
-    BOOST_CHECK(none(valid<std::uint8_t>(-2 - array)).get());
-    BOOST_CHECK(none(valid<std::uint8_t>((0 - array) - 2)).get());      // For lack of unary min ATM...
-    BOOST_CHECK(none(valid<std::uint8_t>((0 - array) - array)).get());  // For lack of unary min ATM...
+    BOOST_CHECK(none(valid<std::uint8_t>(-2 - array)).future().get());
+    BOOST_CHECK(none(valid<std::uint8_t>((0 - array) - 2)).future().get());  // For lack of unary min ATM...
+    BOOST_CHECK(
+        none(valid<std::uint8_t>((0 - array) - array)).future().get());  // For lack of unary min ATM...
 }
diff --git a/source/framework/algorithm/test/sum_test.cpp b/source/framework/algorithm/test/sum_test.cpp
index 10e25942f..fe18fc8f8 100644
--- a/source/framework/algorithm/test/sum_test.cpp
+++ b/source/framework/algorithm/test/sum_test.cpp
@@ -10,6 +10,7 @@ namespace detail {
     void test_array()
     {
         using Array = lue::PartitionedArray<Element, rank>;
+        using Scalar = lue::Scalar<ResultElement>;
 
         auto const array_shape{lue::Test<Array>::shape()};
         auto const partition_shape{lue::Test<Array>::partition_shape()};
@@ -21,10 +22,11 @@ namespace detail {
         auto sum = lue::value_policies::sum<ResultElement>(array);
 
         using TypeWeGot = decltype(sum);
-        using TypeWeWant = hpx::future<ResultElement>;
+        using TypeWeWant = Scalar;
         static_assert(std::is_same_v<TypeWeGot, TypeWeWant>);
 
-        BOOST_CHECK_EQUAL(sum.get(), static_cast<Element>(lue::nr_elements(array_shape) * fill_value));
+        BOOST_CHECK_EQUAL(
+            sum.future().get(), static_cast<Element>(lue::nr_elements(array_shape) * fill_value));
     }
 
 
diff --git a/source/framework/algorithm/test/tan_test.cpp b/source/framework/algorithm/test/tan_test.cpp
index 26f565d08..b80842f48 100644
--- a/source/framework/algorithm/test/tan_test.cpp
+++ b/source/framework/algorithm/test/tan_test.cpp
@@ -22,7 +22,7 @@ namespace detail {
 
         Array array{lue::create_partitioned_array(array_shape, partition_shape, fill_value)};
 
-        BOOST_CHECK(all(tan(array) == std::tan(fill_value)).get());
+        BOOST_CHECK(all(tan(array) == std::tan(fill_value)).future().get());
     }
 
 }  // namespace detail
diff --git a/source/framework/algorithm/test/uniform_test.cpp b/source/framework/algorithm/test/uniform_test.cpp
index 8cf3da51b..1b6c568f2 100644
--- a/source/framework/algorithm/test/uniform_test.cpp
+++ b/source/framework/algorithm/test/uniform_test.cpp
@@ -35,15 +35,15 @@ namespace detail {
             array1 = uniform(array1, min_value, max_value);
 
             // min_value <= array1 < max_value
-            BOOST_CHECK(all(array1 >= min_value).get());
+            BOOST_CHECK(all(array1 >= min_value).future().get());
 
             if constexpr (std::is_floating_point_v<Element>)
             {
-                BOOST_CHECK(all(array1 < max_value).get());
+                BOOST_CHECK(all(array1 < max_value).future().get());
             }
             else if constexpr (std::is_integral_v<Element>)
             {
-                BOOST_CHECK(all(array1 <= max_value).get());
+                BOOST_CHECK(all(array1 <= max_value).future().get());
             }
         }
 
@@ -51,15 +51,15 @@ namespace detail {
             array2 = uniform(array2, min_value, max_value);
 
             // min_value <= array2 < max_value
-            BOOST_CHECK(all(array2 >= min_value).get());
+            BOOST_CHECK(all(array2 >= min_value).future().get());
 
             if constexpr (std::is_floating_point_v<Element>)
             {
-                BOOST_CHECK(all(array2 < max_value).get());
+                BOOST_CHECK(all(array2 < max_value).future().get());
             }
             else if constexpr (std::is_integral_v<Element>)
             {
-                BOOST_CHECK(all(array2 <= max_value).get());
+                BOOST_CHECK(all(array2 <= max_value).future().get());
             }
         }
 
@@ -67,15 +67,15 @@ namespace detail {
             auto result = uniform(array1, min_value, max_value);
 
             // min_value <= result < max_value
-            BOOST_CHECK(all(result >= min_value).get());
+            BOOST_CHECK(all(result >= min_value).future().get());
 
             if constexpr (std::is_floating_point_v<Element>)
             {
-                BOOST_CHECK(all(result < max_value).get());
+                BOOST_CHECK(all(result < max_value).future().get());
             }
             else if constexpr (std::is_integral_v<Element>)
             {
-                BOOST_CHECK(all(result <= max_value).get());
+                BOOST_CHECK(all(result <= max_value).future().get());
             }
         }
     }
@@ -135,5 +135,6 @@ BOOST_AUTO_TEST_CASE(use_case_1)
 
     BOOST_CHECK(
         all(logical_and(greater_than_equal_to(array, min_value), less_than_equal_to(array, max_value)))
+            .future()
             .get());
 }
diff --git a/source/framework/algorithm/test/valid_test.cpp b/source/framework/algorithm/test/valid_test.cpp
index beb7de6b2..126d7de5c 100644
--- a/source/framework/algorithm/test/valid_test.cpp
+++ b/source/framework/algorithm/test/valid_test.cpp
@@ -38,21 +38,21 @@ BOOST_AUTO_TEST_CASE(default_policies)
         Element const fill_value{0};
         Array array{lue::create_partitioned_array(array_shape, partition_shape, fill_value)};
         BooleanArray result = valid<BooleanElement>(array);
-        BOOST_CHECK(all(result == BooleanElement{1}).get());
+        BOOST_CHECK(all(result == BooleanElement{1}).future().get());
     }
 
     {
         Element const fill_value{-1};
         Array array{lue::create_partitioned_array(array_shape, partition_shape, fill_value)};
         BooleanArray result = valid<BooleanElement>(array);
-        BOOST_CHECK(all(result == BooleanElement{1}).get());
+        BOOST_CHECK(all(result == BooleanElement{1}).future().get());
     }
 
     {
         Element const fill_value{1};
         Array array{lue::create_partitioned_array(array_shape, partition_shape, fill_value)};
         BooleanArray result = valid<BooleanElement>(array);
-        BOOST_CHECK(all(result == BooleanElement{1}).get());
+        BOOST_CHECK(all(result == BooleanElement{1}).future().get());
     }
 }
 
@@ -72,7 +72,7 @@ BOOST_AUTO_TEST_CASE(default_value_policies)
         Array array{lue::create_partitioned_array(array_shape, partition_shape, fill_value)};
         array = lue::where<WherePolicies, BooleanElement>(WherePolicies{}, array == fill_value, array);
         BooleanArray result = valid<BooleanElement>(array);
-        BOOST_CHECK(all(result == BooleanElement{1}).get());
+        BOOST_CHECK(all(result == BooleanElement{1}).future().get());
     }
 
     {
@@ -81,6 +81,6 @@ BOOST_AUTO_TEST_CASE(default_value_policies)
         Array array{lue::create_partitioned_array(array_shape, partition_shape, fill_value)};
         array = lue::where<WherePolicies, BooleanElement>(WherePolicies{}, array != fill_value, array);
         BooleanArray result = valid<BooleanElement>(array);
-        BOOST_CHECK(all(result == BooleanElement{0}).get());
+        BOOST_CHECK(all(result == BooleanElement{0}).future().get());
     }
 }
diff --git a/source/framework/algorithm/test/where_test.cpp b/source/framework/algorithm/test/where_test.cpp
index 458034c7b..cb5d1c754 100644
--- a/source/framework/algorithm/test/where_test.cpp
+++ b/source/framework/algorithm/test/where_test.cpp
@@ -226,7 +226,7 @@ BOOST_AUTO_TEST_CASE(use_case_1)
         }};
     Array<std::uint8_t, rank> condition{lue::create_partitioned_array<std::uint8_t>(shape, shape)};
     condition.partitions()(0, 0).wait();
-    condition.partitions()(0, 0).set_data(std::move(condition_data)).wait();
+    condition.partitions()(0, 0).set_data(condition_data).wait();
 
     PartitionData<Element, rank> true_data{
         shape,
@@ -240,7 +240,7 @@ BOOST_AUTO_TEST_CASE(use_case_1)
         }};
     Array<Element, rank> true_array{lue::create_partitioned_array<Element>(shape, shape)};
     true_array.partitions()(0, 0).wait();
-    true_array.partitions()(0, 0).set_data(std::move(true_data)).wait();
+    true_array.partitions()(0, 0).set_data(true_data).wait();
 
     Element const false_value{9};
 
@@ -258,7 +258,7 @@ BOOST_AUTO_TEST_CASE(use_case_1)
         }};
     Array<Element, rank> result_we_want{lue::create_partitioned_array<Element>(shape, shape)};
     result_we_want.partitions()(0, 0).wait();
-    result_we_want.partitions()(0, 0).set_data(std::move(result_we_want_data)).wait();
+    result_we_want.partitions()(0, 0).set_data(result_we_want_data).wait();
 
     lue::test::check_arrays_are_equal(result_we_got, result_we_want);
 }
@@ -284,9 +284,9 @@ BOOST_AUTO_TEST_CASE(use_case_2)
     using Element = std::int32_t;
     lue::Rank const rank{2};
 
-    ConditionElement ind1;
-    Element ind2;
-    Element ond;
+    ConditionElement ind1{};
+    Element ind2{};
+    Element ond{};
 
     {
         using ONDP1 = lue::policy::DefaultOutputNoDataPolicy<ConditionElement>;
@@ -315,7 +315,7 @@ BOOST_AUTO_TEST_CASE(use_case_2)
         }};
     Array<ConditionElement, rank> condition{lue::create_partitioned_array<ConditionElement>(shape, shape)};
     condition.partitions()(0, 0).wait();
-    condition.partitions()(0, 0).set_data(std::move(condition_data)).wait();
+    condition.partitions()(0, 0).set_data(condition_data).wait();
 
     PartitionData<Element, rank> true_data{
         shape,
@@ -329,7 +329,7 @@ BOOST_AUTO_TEST_CASE(use_case_2)
         }};
     Array<Element, rank> true_array{lue::create_partitioned_array<Element>(shape, shape)};
     true_array.partitions()(0, 0).wait();
-    true_array.partitions()(0, 0).set_data(std::move(true_data)).wait();
+    true_array.partitions()(0, 0).set_data(true_data).wait();
 
     auto result_we_got = lue::value_policies::where(condition, true_array);
 
@@ -345,7 +345,7 @@ BOOST_AUTO_TEST_CASE(use_case_2)
         }};
     Array<Element, rank> result_we_want{lue::create_partitioned_array<Element>(shape, shape)};
     result_we_want.partitions()(0, 0).wait();
-    result_we_want.partitions()(0, 0).set_data(std::move(result_we_want_data)).wait();
+    result_we_want.partitions()(0, 0).set_data(result_we_want_data).wait();
 
     lue::test::check_arrays_are_equal(result_we_got, result_we_want);
 }
diff --git a/source/framework/algorithm/test/zonal_normal_test.cpp b/source/framework/algorithm/test/zonal_normal_test.cpp
index 9f9a3ce5f..e01dc4ee5 100644
--- a/source/framework/algorithm/test/zonal_normal_test.cpp
+++ b/source/framework/algorithm/test/zonal_normal_test.cpp
@@ -28,6 +28,6 @@ BOOST_AUTO_TEST_CASE(use_case_01)
     using namespace lue::value_policies;
 
     // Very unlikely that values outside (-10, 10) are drawn
-    BOOST_CHECK(all(zonal_normal > Element{-10}).get());
-    BOOST_CHECK(all(zonal_normal < Element{+10}).get());
+    BOOST_CHECK(all(zonal_normal > Element{-10}).future().get());
+    BOOST_CHECK(all(zonal_normal < Element{+10}).future().get());
 }
diff --git a/source/framework/algorithm/test/zonal_uniform_test.cpp b/source/framework/algorithm/test/zonal_uniform_test.cpp
index 0e1627b5d..2b487be88 100644
--- a/source/framework/algorithm/test/zonal_uniform_test.cpp
+++ b/source/framework/algorithm/test/zonal_uniform_test.cpp
@@ -27,6 +27,6 @@ BOOST_AUTO_TEST_CASE(use_case_01)
 
     using namespace lue::value_policies;
 
-    BOOST_CHECK(all(zonal_uniform >= Element{0}).get());
-    BOOST_CHECK(all(zonal_uniform < Element{1}).get());
+    BOOST_CHECK(all(zonal_uniform >= Element{0}).future().get());
+    BOOST_CHECK(all(zonal_uniform < Element{1}).future().get());
 }
diff --git a/source/framework/python/test/algorithm/local_operation/add_test.py b/source/framework/python/test/algorithm/local_operation/add_test.py
new file mode 100644
index 000000000..b2131c819
--- /dev/null
+++ b/source/framework/python/test/algorithm/local_operation/add_test.py
@@ -0,0 +1,37 @@
+import numpy as np
+
+import lue.framework as lfr
+import lue_test
+
+from ..operation_test import OperationTest, setUpModule, tearDownModule
+
+
+class AddTest(OperationTest):
+    @lue_test.framework_test_case
+    def test_overloads(self):
+
+        for type_ in self.numeric_types:
+            value = self.value[type_]
+            scalar = self.scalar[type_]
+            array = self.array[type_]
+
+            # value icw scalar
+            _ = lfr.add(value, scalar)
+            _ = lfr.add(scalar, value)
+
+            _ = value + scalar
+            _ = scalar + value
+
+            # value icw array
+            _ = lfr.add(value, array)
+            _ = lfr.add(array, value)
+
+            _ = value + array
+            _ = array + value
+
+            # scalar icw array
+            _ = lfr.add(scalar, array)
+            _ = lfr.add(array, scalar)
+
+            _ = scalar + array
+            _ = array + scalar
diff --git a/source/framework/python/test/algorithm/operation_test.py b/source/framework/python/test/algorithm/operation_test.py
new file mode 100644
index 000000000..a394fe617
--- /dev/null
+++ b/source/framework/python/test/algorithm/operation_test.py
@@ -0,0 +1,54 @@
+import numpy as np
+
+import lue.framework as lfr
+import lue_test
+
+
+def setUpModule():
+    lue_test.start_hpx_runtime()
+
+
+def tearDownModule():
+    lue_test.stop_hpx_runtime()
+
+
+class OperationTest(lue_test.TestCase):
+    @classmethod
+    @lue_test.framework_test_case
+    def setUpClass(cls):
+        cls.array_shape = (60, 40)
+        cls.partition_shape = (10, 10)
+
+        cls.numeric_types = [
+            np.uint8,
+            # np.int8,
+            np.uint32,
+            np.uint64,
+            np.int32,
+            np.int64,
+            np.float32,
+            np.float64,
+        ]
+
+        cls.value = {
+            np.uint8: np.uint8(8),
+            # np.int8: np.int8(-8),
+            np.uint32: np.uint32(32),
+            np.uint64: np.uint32(64),
+            np.int32: np.int64(-32),
+            np.int64: np.int64(-64),
+            np.float32: np.float32(3.2),
+            np.float64: np.float64(6.4),
+        }
+
+        cls.array = {
+            type_: lfr.create_array(
+                cls.array_shape,
+                type_,
+                fill_value=value,
+                partition_shape=cls.partition_shape,
+            )
+            for type_, value in cls.value.items()
+        }
+
+        cls.scalar = {type_: lfr.maximum(array) for type_, array in cls.array.items()}
diff --git a/source/framework/python/test/algorithm/valid_test.py b/source/framework/python/test/algorithm/valid_test.py
index 9df89ee35..eb1fee41d 100644
--- a/source/framework/python/test/algorithm/valid_test.py
+++ b/source/framework/python/test/algorithm/valid_test.py
@@ -22,7 +22,7 @@ def test_all_valid(self):
 
         result = lfr.valid(array)
 
-        self.assertTrue(lfr.all(result == 1).get())
+        self.assertTrue(lfr.all(result == 1).future.get())
 
     @lue_test.framework_test_case
     def test_all_invalid(self):
@@ -36,4 +36,4 @@ def test_all_invalid(self):
 
         result = lfr.valid(array)
 
-        self.assertTrue(lfr.all(result == 0).get())
+        self.assertTrue(lfr.all(result == 0).future.get())
diff --git a/source/framework/python/test/algorithm/where_test.py b/source/framework/python/test/algorithm/where_test.py
index 7e8064543..bc76003e0 100644
--- a/source/framework/python/test/algorithm/where_test.py
+++ b/source/framework/python/test/algorithm/where_test.py
@@ -27,15 +27,15 @@ def test_binary_where_overloads(self):
 
         # where(array, true_array)
         result = lfr.where(condition_array, expression_array - 1)
-        self.assertTrue(lfr.all(result == 4).get())
+        self.assertTrue(lfr.all(result == 4).future.get())
 
         # where(array, true_value_f)
         result = lfr.where(condition_array, lfr.maximum(expression_array - 1))
-        self.assertTrue(lfr.all(result == 4).get())
+        self.assertTrue(lfr.all(result == 4).future.get())
 
         # where(array, true_value)
         result = lfr.where(condition_array, 4)
-        self.assertTrue(lfr.all(result == 4).get())
+        self.assertTrue(lfr.all(result == 4).future.get())
 
     @lue_test.framework_test_case
     def test_ternary_where_overloads(self):
@@ -53,27 +53,27 @@ def test_ternary_where_overloads(self):
 
         # where(array, true_array, false_array)
         result = lfr.where(condition_array, expression_array1 - 1, expression_array2)
-        self.assertTrue(lfr.all(result == 4).get())
+        self.assertTrue(lfr.all(result == 4).future.get())
 
         # where(array, true_array, false_value_f)
         result = lfr.where(
             condition_array, expression_array1 - 1, lfr.maximum(expression_array2)
         )
-        self.assertTrue(lfr.all(result == 4).get())
+        self.assertTrue(lfr.all(result == 4).future.get())
 
         # where(array, true_array, false_value)
         result = lfr.where(condition_array, expression_array1 - 1, fill_value2)
-        self.assertTrue(lfr.all(result == 4).get())
+        self.assertTrue(lfr.all(result == 4).future.get())
 
         # where(array, true_value_f, false_array)
         result = lfr.where(
             condition_array, lfr.maximum(expression_array1 - 1), expression_array2
         )
-        self.assertTrue(lfr.all(result == 4).get())
+        self.assertTrue(lfr.all(result == 4).future.get())
 
         # where(array, true_value, false_array)
         result = lfr.where(condition_array, 4, expression_array2)
-        self.assertTrue(lfr.all(result == 4).get())
+        self.assertTrue(lfr.all(result == 4).future.get())
 
         # where(array, true_value_f, false_value_f)
         result = lfr.where(
@@ -81,8 +81,8 @@ def test_ternary_where_overloads(self):
             lfr.maximum(expression_array1 - 1),
             lfr.maximum(expression_array2),
         )
-        self.assertTrue(lfr.all(result == 4).get())
+        self.assertTrue(lfr.all(result == 4).future.get())
 
         # where(array, true_value, false_value)
         result = lfr.where(condition_array, 4, 5)
-        self.assertTrue(lfr.all(result == 4).get())
+        self.assertTrue(lfr.all(result == 4).future.get())
diff --git a/source/framework/python/test/core/scalar_test.py b/source/framework/python/test/core/scalar_test.py
new file mode 100644
index 000000000..6fb282c44
--- /dev/null
+++ b/source/framework/python/test/core/scalar_test.py
@@ -0,0 +1,127 @@
+from collections.abc import ValuesView
+
+import numpy as np
+
+import lue.framework as lfr
+import lue_test
+
+
+def setUpModule():
+    lue_test.start_hpx_runtime()
+
+
+def tearDownModule():
+    lue_test.stop_hpx_runtime()
+
+
+class ScalarTest(lue_test.TestCase):
+    @classmethod
+    @lue_test.framework_test_case
+    def setUpClass(cls):
+        cls.signed_integral_types = [
+            # np.int8,
+            np.int32,
+            np.int64,
+        ]
+        cls.unsigned_integral_types = [
+            np.uint8,
+            np.uint32,
+            np.uint64,
+        ]
+        cls.integral_types = cls.signed_integral_types + cls.unsigned_integral_types
+        cls.floating_point_types = [
+            np.float32,
+            np.float64,
+        ]
+
+        cls.numeric_types = cls.integral_types + cls.floating_point_types
+
+        cls.value_by_type = {
+            np.uint8: np.uint8(8),
+            # np.int8: np.int8(-8),
+            np.uint32: np.uint32(32),
+            np.uint64: np.uint32(64),
+            np.int32: np.int64(-32),
+            np.int64: np.int64(-64),
+            np.float32: np.float32(3.2),
+            np.float64: np.float64(6.4),
+        }
+
+        cls.dtype_by_floating_point_type = {
+            type_: np.dtype(type_) for type_ in cls.floating_point_types
+        }
+
+        cls.dtype_by_type = {type_: np.dtype(type_) for type_ in cls.numeric_types}
+
+        cls.scalar_by_dtype = {
+            cls.dtype_by_type[type_]: lfr.create_scalar(
+                cls.dtype_by_type[type_], cls.value_by_type[type_]
+            )
+            for type_ in cls.numeric_types
+        }
+
+    @lue_test.framework_test_case
+    def test_dtype(self):
+        for dtype, scalar in self.scalar_by_dtype.items():
+            self.assertEqual(scalar.dtype, dtype)
+
+    @lue_test.framework_test_case
+    def test_operator_add_overloads(self):
+        for type_, dtype in self.dtype_by_type.items():
+            value = self.value_by_type[type_]
+            scalar = lfr.create_scalar(dtype, value)
+
+            _ = scalar + value
+            _ = value + scalar
+            scalar += value
+            value += scalar
+
+    @lue_test.framework_test_case
+    def test_operator_bool(self):
+        for _, scalar in self.scalar_by_dtype.items():
+            with self.assertRaises(ValueError):
+                _ = bool(scalar)
+
+    @lue_test.framework_test_case
+    def test_operator_divide_overloads(self):
+        for type_, dtype in self.dtype_by_floating_point_type.items():
+            value = self.value_by_type[type_]
+            scalar = lfr.create_scalar(dtype, value)
+
+            _ = scalar / value
+            _ = value / scalar
+            scalar /= value
+            value /= scalar
+
+    @lue_test.framework_test_case
+    def test_operator_multiply_overloads(self):
+        for type_, dtype in self.dtype_by_floating_point_type.items():
+            value = self.value_by_type[type_]
+            scalar = lfr.create_scalar(dtype, value)
+
+            _ = scalar * value
+            _ = value * scalar
+            scalar *= value
+            value *= scalar
+
+    @lue_test.framework_test_case
+    def test_operator_pow_overloads(self):
+        for type_, dtype in self.dtype_by_floating_point_type.items():
+            value = self.value_by_type[type_]
+            scalar = lfr.create_scalar(dtype, value)
+
+            _ = scalar**value
+            _ = value**scalar
+            scalar **= value
+            value **= scalar
+
+    @lue_test.framework_test_case
+    def test_operator_subtract_overloads(self):
+        for type_, dtype in self.dtype_by_type.items():
+            value = self.value_by_type[type_]
+            scalar = lfr.create_scalar(dtype, value)
+
+            _ = scalar - value
+            _ = value - scalar
+            scalar -= value
+            value -= scalar
diff --git a/source/framework/python/test/create_array_test.py b/source/framework/python/test/create_array_test.py
index 76092acde..4be55d57f 100644
--- a/source/framework/python/test/create_array_test.py
+++ b/source/framework/python/test/create_array_test.py
@@ -27,7 +27,7 @@ def test_create_array01(self):
 
         self.assertEqual(array.dtype, dtype)
         self.assertEqual(array.shape, array_shape)
-        self.assertTrue(lfr.all(array == fill_value).get())
+        self.assertTrue(lfr.all(array == fill_value).future.get())
 
     @lue_test.framework_test_case
     def test_create_array02(self):
@@ -40,4 +40,4 @@ def test_create_array02(self):
 
         self.assertEqual(array.dtype, dtype)
         # self.assertEqual(array.shape, (?, ?))
-        self.assertTrue(lfr.all(array == fill_value).get())
+        self.assertTrue(lfr.all(array == fill_value).future.get())
diff --git a/source/framework/python/test/from_numpy_test.py b/source/framework/python/test/from_numpy_test.py
index 93569c774..e3fcb744d 100644
--- a/source/framework/python/test/from_numpy_test.py
+++ b/source/framework/python/test/from_numpy_test.py
@@ -29,8 +29,8 @@ class FromNumPyTest(lue_test.TestCase):
 
     #     self.assertEqual(lue_array.dtype, dtype)
     #     self.assertEqual(lue_array.shape, array_shape)
-    #     self.assertEqual(lfr.minimum(lue_array).get(), 0)
-    #     self.assertEqual(lfr.maximum(lue_array).get(), nr_cells - 1)
+    #     self.assertEqual(lfr.minimum(lue_array).future.get(), 0)
+    #     self.assertEqual(lfr.maximum(lue_array).future.get(), nr_cells - 1)
 
     # @lue_test.framework_test_case
     # def test_mark_no_data(self):
@@ -47,8 +47,8 @@ class FromNumPyTest(lue_test.TestCase):
     #         numpy_array, partition_shape=partition_shape, no_data_value=999
     #     )
 
-    #     self.assertEqual(lfr.minimum(lue_array).get(), 5)
-    #     self.assertEqual(lfr.maximum(lue_array).get(), 5)
+    #     self.assertEqual(lfr.minimum(lue_array).future.get(), 5)
+    #     self.assertEqual(lfr.maximum(lue_array).future.get(), 5)
 
     #     # TODO Verify that the array contains three no-data elements
 
@@ -64,8 +64,8 @@ class FromNumPyTest(lue_test.TestCase):
 
     #     self.assertEqual(lue_array.dtype, dtype)
     #     self.assertEqual(lue_array.shape, array_shape)
-    #     self.assertEqual(lfr.minimum(lue_array).get(), 0)
-    #     self.assertEqual(lfr.maximum(lue_array).get(), 0)
+    #     self.assertEqual(lfr.minimum(lue_array).future.get(), 0)
+    #     self.assertEqual(lfr.maximum(lue_array).future.get(), 0)
 
     # @lue_test.framework_test_case
     # def test_dtype(self):
diff --git a/source/framework/python/test/gdal_test.py b/source/framework/python/test/gdal_test.py
index c3ab3580f..28a36788e 100644
--- a/source/framework/python/test/gdal_test.py
+++ b/source/framework/python/test/gdal_test.py
@@ -31,7 +31,7 @@ def test_round_trip1(self):
 
         self.assertEqual(array_read.dtype, array_written.dtype)
         self.assertEqual(array_read.shape, array_written.shape)
-        self.assertTrue(lfr.all(array_read == array_written).get())
+        self.assertTrue(lfr.all(array_read == array_written).future.get())
 
     @lue_test.framework_test_case
     def test_round_trip2(self):
@@ -54,4 +54,4 @@ def test_round_trip2(self):
 
         self.assertEqual(array_read.dtype, array_written.dtype)
         self.assertEqual(array_read.shape, array_written.shape)
-        self.assertTrue(lfr.all(array_read == array_written).get())
+        self.assertTrue(lfr.all(array_read == array_written).future.get())
diff --git a/source/framework/python/test/read_array_test.py b/source/framework/python/test/read_array_test.py
index 51519bbb7..7b17aa335 100644
--- a/source/framework/python/test/read_array_test.py
+++ b/source/framework/python/test/read_array_test.py
@@ -45,7 +45,7 @@ def test_read_constant_array(self):
 
         self.assertEqual(array.dtype, dtype)
         self.assertEqual(array.shape, array_shape)
-        self.assertTrue(lfr.all(array == fill_value).get())
+        self.assertTrue(lfr.all(array == fill_value).future.get())
 
     @lue_test.framework_test_case
     def test_read_variable_array(self):
@@ -98,7 +98,7 @@ def test_read_variable_array(self):
 
         self.assertEqual(array.dtype, dtype)
         self.assertEqual(array.shape, array_shape)
-        self.assertTrue(lfr.all(array == fill_value).get())
+        self.assertTrue(lfr.all(array == fill_value).future.get())
 
     @lue_test.framework_test_case
     def test_read_array_subset(self):
diff --git a/source/framework/python/test/write_array_test.py b/source/framework/python/test/write_array_test.py
index 67f79df91..f1e86b2cf 100644
--- a/source/framework/python/test/write_array_test.py
+++ b/source/framework/python/test/write_array_test.py
@@ -54,7 +54,7 @@ def test_write_constant_array(self):
 
         array_read = lfr.read_array(array_pathname, partition_shape=partition_shape)
 
-        self.assertTrue(lfr.all(array_read == array).get())
+        self.assertTrue(lfr.all(array_read == array).future.get())
 
     @lue_test.framework_test_case
     def test_write_variable_array(self):
@@ -120,4 +120,4 @@ def test_write_variable_array(self):
                 array_pathname, t, partition_shape=partition_shape
             )
 
-            self.assertTrue(lfr.all(array_read == arrays[t]).get())
+            self.assertTrue(lfr.all(array_read == arrays[t]).future.get())