Re: Multi Mini-Review Begins Today

Rainer Deyke via Boost <[email protected]>
Newsgroups gmane.comp.lib.boost.devel
Message-ID <[email protected]>
On 8/7/26 14:00, Matt Borland via Boost wrote:
> Hello,
> 
> Today begins the mini-review of Multi, authored by Alfredo Correa. Multi is a modern C++ library that provides manipulation and access of data in multidimensional arrays for both CPU and GPU memory. The review will run through Wednesday 12 August.
> 
> You can find the library and documentation links below:
> - https://github.com/correaa/boost-multi
> - https://correaa.github.io/boost-multi/multi/intro.html
> 
> The review earlier this year raised a number of issues that primarily revolved around the state of the documentation, not the library itself. I have labeled all of the issues related to conditions found in last review, and many have notes or resolution from Alfredo:
> 
> https://github.com/correaa/boost-multi/issues?q=is%3Aissue%20state%3Aopen%20label%3A%22Boost%20review%22
> 
> To this end the review will revolve around the current state of the documentation on the branch "boost_review". In your review please explicitly state if you recommend REJECT, ACCEPT, or a conditional acceptance along with the acceptance conditions.

Looking at the reference documentation 
(https://correaa.github.io/boost-multi/multi/reference/index.html), it's 
obviously incomplete.  About half of the namespace-level symbols don't 
even have a short one-sentence description in the description column. 
Actually clicking on the specific symbols yields some additional 
information if you read between the lines, but not enough.  It's also 
quite difficult to read, lacking cross-links and spreading minimal 
information across a maximal number of unique pages.

I'll try to go through the namespace-level non-deprecated symbols one by 
one and document the main problems I find.  I will be very specific 
because apparently my previous feedback was too vague.

boost::multi::array 
(https://correaa.github.io/boost-multi/multi/reference/boost/multi/array-0ad.html) 
is relatively well-documented, i.e. most members have at least a 
one-line description.  Not all, mind you.  Specific concerns:
   - A lot of basic usage information on this type is found elsewhere in 
the documentation, 
https://correaa.github.io/boost-multi/multi/reference.html#ref_types. 
This is not wrong per se, but there should be a link from the reference 
page to the page containing the information.  Better still would be to 
make the API reference complete in itself.
   - There are typos.  "multidimensionally" is misspelled as 
"mutidimensioally" several times.  "associated" is misspelled 
"associalted".  "yields" is misspelled "yeilds".
   - The following non-deprecated public symbols are not documented at 
all: flatted, flattened,  is_flattable.
   - Protected symbols are included symbols are included in the 
documentation.  Why?  Are they part of the public API?  Are users 
supposed to create classes that derive from `array`?
   - Some symbols have "<symbol_name> overloads" as their short 
description.  Surely these overloads have enough in common to share a 
single description that's actually descriptive?
   - The documentations for operators [] and () is particularly bad. 
Logically speaking, these are not overloaded sets but single functions 
with a variable number of arguments.  I don't need a list of which 
overloads were used to implement them.  I need a description of what 
kinds of arguments they accept (single indices and ranges) and what they 
return (subarray view or reference to element).
   - Function that return a type defined anywhere in the library, or 
accept an argument of a type defined anywhere in the library, should 
link to the documentation of that type.
   - Type aliases that alias a type defined elsewhere in the library 
should link to the documentation of that type.
   - What does "yields a view in which indices are unordered (generally 
to optimize access)" mean?  Indices can be reordered, arbitrarily so, 
but they cannot be unordered.  Indices are always in an order.
   - Operators are split between member functions and non-member 
functions, which makes it difficult to see which operators exist at a 
glance.
   - I don't care about friendship relations between types.  That's an 
implementation detail that does not need to be documented.

boost::multi::array_ref 
(https://correaa.github.io/boost-multi/multi/reference/boost/multi/array_ref-0c.html): 
pretty much the same concerns as for boost::multi::array.  In addition:
   - `iterator` has no description.
   - `layout_type` has no description.
   - `value_type` has no description.
   - `base` has no description.
   - `begin` has no description.
   - `data_elements` has no description.
   - `dropped` has no description.
   - `end` has no description.
   - `swap` has no description.  This is particularly bad because there 
are three possible interpretations of what this function can do:
     - It could swap which underlying arrays two array_refs point to, 
leaving the underlying arrays unchanged, in violation of the guarantee 
that array_refs cannot be rebound.
     - It could cheaply swap the data stores of the underlying arrays.
     - It could not-so-cheaply swap every corresponding element of the 
underlying arrays.

boost::multi::array_types 
(https://correaa.github.io/boost-multi/multi/reference/boost/multi/array_types.html): 
this class looks like an implementation detail which exists in order to 
support its derived class, const_subarray.  If so, it should be removed 
from the documentation entirely.

boost::multi::bind_category 
(https://correaa.github.io/boost-multi/multi/reference/boost/multi/bind_category-0e.html): 
again, no description.  Document properly if part of the public API, 
else remove.

boost::multi::bind_front_t 
(https://correaa.github.io/boost-multi/multi/reference/boost/multi/bind_front_t.html): 
I can't make out the purpose of this class.  There is no description, 
and the description of its only member function is useless.  If this is 
another implementation detail, it should be removed from the 
documentation.  If it's part of the public API, it should be documented 
properly.

boost::multi::bind_transposed_t 
(https://correaa.github.io/boost-multi/multi/reference/boost/multi/bind_transposed_t.html): 
see boost::multi::bind_front_t.

boost::multi::const_subarray 
(https://correaa.github.io/boost-multi/multi/reference/boost/multi/const_subarray-0ba.html): 
similar issues to boost::multi::array_ref.  I also noticed that some of 
the type aliases, e.g. move_iterator, are not used by any member 
function and make no sense for this type.  Can they be removed from the 
documentation?

boost::multi::cursor_t 
(https://correaa.github.io/boost-multi/multi/reference/boost/multi/cursor_t.html):
   - The class itself has no description.
   - The documentation on strides (symbols `StridesType`, 
`strides_type`, `strides`, and `stride`) is missing entirely.  Not even 
a short description.  `StridesType` is passed in as a template 
parameter, but I have no idea what concrete type(s) would typically be 
passed in, where they are defined, or what their interface is.
   - The return type of operator[] is undocumented.
   - None of the type aliases have a description.
   - `base` has no description, although I think I can make out its 
purpose from its return type.

boost::multi::dynamic_array 
(https://correaa.github.io/boost-multi/multi/reference/boost/multi/dynamic_array-00.html): 
similar issues to `boost::multi::array`.  Also poorly named.  Maybe 
`fixed_size_array`?

boost::multi::elements_iterator_t 
(https://correaa.github.io/boost-multi/multi/reference/boost/multi/elements_iterator_t.html): 
it's a random access iterator that works like every other random access 
iterator, so I can excuse a certain sparseness in the documentation. 
That does not apply to the members that aren't part of the random access 
iterator interface, namely `base`, `current`, and `layout`.

boost::multi::elements_range_t 
(https://correaa.github.io/boost-multi/multi/reference/boost/multi/elements_range_t.html): 
judging from its name, I would expect this to function as a non-owning 
range, roughly equivalent to 
`std::ranges::subrange<boost::multi::element_iterator_t>`.  However, the 
exact semantics of the type are not documented.  Specific concerns:
   - The constructor and operator= are marked as deleted on the main 
page.  This is misleading: while the default implementations of these 
functions are deleted, there are other overloads available, including 
templated overloads that take the place of the deleted functions.
   - The semantics of operator= are ambiguous.  Does it rebind the range 
or copy the contents of the right hand side?

boost::multi::initializer_array 
(https://correaa.github.io/boost-multi/multi/reference/boost/multi/initializer_array.html): 
the purpose and semantics of this class are a mystery.  Document it 
properly if it's part of the public API; remove it if not.

boost::multi::invoke_result_from_tuple 
(https://correaa.github.io/boost-multi/multi/reference/boost/multi/invoke_result_from_tuple-01.html): 
I can guess it's purpose by clicking on the specialization 
(https://correaa.github.io/boost-multi/multi/reference/boost/multi/invoke_result_from_tuple-06.html) 
and then clicking on the `type` member 
(https://correaa.github.io/boost-multi/multi/reference/boost/multi/invoke_result_from_tuple-06/type.html). 
  I shouldn't have to click twice to get this information.

boost::multi::move_subarray 
(https://correaa.github.io/boost-multi/multi/reference/boost/multi/move_subarray.html): 
looking at the name, I guess this is a helper type for implementing move 
semantics for elements, possibly the return type of 
boost::multi::subarray::element_moved (although this is not documented). 
  I shouldn't have to guess.

boost::multi::restriction 
(https://correaa.github.io/boost-multi/multi/reference/boost/multi/restriction-02c.html): 
almost completely undocumented.  I'm guessing this is the return type of 
boost::multi::restrict, which is also undocumented.  Yes, these members 
are mostly the same as those of every other array type.  That doesn't 
excuse them being undocumented here.

boost::multi::restriction_elements_iterator 
(https://correaa.github.io/boost-multi/multi/reference/boost/multi/restriction_elements_iterator.html): 
similar concerns to boost::multi::elements_iterator_t above.  In 
addition, there is a `system` type alias that not only has no 
description, but has a reference to the completely undocumented type 
`detail::function_system` in its documentation.  There should be no 
references at all to the `detail` namespace in the documentation.

boost::multi::restriction_elements_t 
(https://correaa.github.io/boost-multi/multi/reference/boost/multi/restriction_elements_t.html): 
is this the restriction equivalent of boost::multi::elements_range_t? 
If so, why is it so much sparser than boost::multi::elements_range_t? 
Does it have any automatically generated functions (e.g. copy 
constructor or operator=), and if so, what are their semantics?

boost::multi::restriction_iterator 
(https://correaa.github.io/boost-multi/multi/reference/boost/multi/restriction_iterator.html): 
it looks like a random access iterator.  I can't tell if it actually is 
a random access iterator, i.e. if it meets the requirements of 
std::random_access_iterator.  It looks like operator[] returns by value, 
although the actual return type is undocumented, and I can't make out 
what the `reference` type alias actually refers to.

boost::multi::subarray 
(https://correaa.github.io/boost-multi/multi/reference/boost/multi/subarray.html): 
pretty much the same concerns as boost::multi::array_ref.

boost::multi::subarray_ptr 
(https://correaa.github.io/boost-multi/multi/reference/boost/multi/subarray_ptr.html): 
with some hard competition, this type manages to be the worst documented 
type in the documentation.  Congratulations!  Here the documentation is 
limited to the types of the template arguments.  It doesn't even have 
names for the template arguments, much less descriptions of what the 
template arguments are for, much less any members.  Maybe this is a tag 
type without members?  I wouldn't know; there's no description 
whatsoever of what this type is used for.

boost::multi::unique_array 
(https://correaa.github.io/boost-multi/multi/reference/boost/multi/unique_array.html): 
this class seems to sit in the hierarchy between 
boost::multi::dynamic_array and boost::multi::array.  It's not mentioned 
at all on 
https://correaa.github.io/boost-multi/multi/reference.html#ref_types, 
which makes me think that it may be an internal type not intended for 
public use.  In which case, why document it at all?

boost::multi::array_const_view 
(https://correaa.github.io/boost-multi/multi/reference/boost/multi/array_const_view.html): 
minimal documentation, but the synopsis says all that needs to be said. 
All that's missing is turning the text `array_ref` in the synopsis into 
a link.  Wait, why is this a reference type?  I don't know how this type 
is used internally in boost::multi or how users are intended to use it, 
but making it a reference without making this explicit in the type name 
seems very dangerous.  Tracing dangling reference bugs is not fun.

boost::multi::array_cref 
(https://correaa.github.io/boost-multi/multi/reference/boost/multi/array_cref.html): 
similar to array_const_view, but the use of std::pointer_traits and 
std::decay_t makes it less pleasant to read.  A short description would 
be appreciated.

boost::multi::array_mref 
(https://correaa.github.io/boost-multi/multi/reference/boost/multi/array_mref.html): 
see boost::multi::array_cref.

boost::multi::array_view 
(https://correaa.github.io/boost-multi/multi/reference/boost/multi/array_view.html): 
see boost::multi::array_const_view above.

boost::multi::const_subarray_ptr 
(https://correaa.github.io/boost-multi/multi/reference/boost/multi/const_subarray_ptr.html): 
I found the missing template parameter names for boost::multi::subarray_ptr!

boost::multi::inplace_array 
(https://correaa.github.io/boost-multi/multi/reference/boost/multi/inplace_array.html): 
it's a type alias to an undocumented type in a `detail` namespace.  It 
must be documented as it it were a class, not a type alias.  But at 
least the template parameter is documented.

boost::multi::restriction_idl 
(https://correaa.github.io/boost-multi/multi/reference/boost/multi/restriction_idl.html). 
  No idea what 'idl' stands for, or what this type is used for, or if it 
should be a public type at all.

boost::multi::apply_ 
(https://correaa.github.io/boost-multi/multi/reference/boost/multi/apply_.html): 
undocumented.  Looks kind of like `std::apply`, expect it that it takes 
a parameter pack instead of a tuple as arguments, which makes me wonder 
who it even exists.  Seriously, why does this exist?  What does it do? 
Why does its name end with an underscore?

boost::multi::base 
(https://correaa.github.io/boost-multi/multi/reference/boost/multi/base-0b.html): 
I can guess what it does, but I don't like having to guess.  Isn't there 
already a member function with the same name and the same functionality? 
  Why the free function?

boost::multi::begin 
(https://correaa.github.io/boost-multi/multi/reference/boost/multi/begin.html): 
again, why the free function, and why not use std:begin instead?  This 
is a serious question that I want the documentation to answer.

boost::multi::cbegin 
(https://correaa.github.io/boost-multi/multi/reference/boost/multi/cbegin.html): 
see boost::multi::begin above.

boost::multi::cend 
(https://correaa.github.io/boost-multi/multi/reference/boost/multi/cend.html): 
see boost::multi::begin above.

boost::multi::data_elements 
(https://correaa.github.io/boost-multi/multi/reference/boost/multi/data_elements-08.html): 
not sure what this does.  Oh wait, I think it just calls 
.elements().data() on its argument.  Except that it's .elements().base() 
instead, because boost::multi::elements_range_t doesn't have a `data` 
member function but it does have a `base` member function with 
(apparently) the semantics of `std::vector::data()`.  Did I guess right?

boost::multi::decay 
(https://correaa.github.io/boost-multi/multi/reference/boost/multi/decay-00.html): 
on the surface, this looks like another one of those free functions that 
just forward to the corresponding member functions.  But why does it 
have two overloads that both take a `const_subarray const&` as argument, 
and where is the supposed return type, `decay_type`, documented?

boost::multi::diagonal 
(https://correaa.github.io/boost-multi/multi/reference/boost/multi/diagonal.html): 
another free function that forwards to a member function, or is it the 
member function that forwards to the free function?

boost::multi::end 
(https://correaa.github.io/boost-multi/multi/reference/boost/multi/end.html): 
see boost::multi::begin above.

boost::multi::extent 
(https://correaa.github.io/boost-multi/multi/reference/boost/multi/extent.html): 
just to be perfectly clear, the fact that I can guess that this just 
forwards to the corresponding member function in no way excuses the lack 
of description for this or any other function.  I also want to see links 
to the actual member functions that this function calls.

boost::multi::get_allocator 
(https://correaa.github.io/boost-multi/multi/reference/boost/multi/get_allocator-08.html): 
this one is surprising, because one of the overloads takes a 
boost::multi::subarray, and I didn't think subarrays had allocators. 
Going back to the subarray documentation, I see that they have no 
allocator type alias, but they do have a `get_allocator` member function 
that returns a `default_allocator_type`, whatever that is.  Looking 
further, `default_allocator_type` appears to be defined in the 
`boost::multi::const_subarray<T, 1, ElementPtr, 
Layout>::default_allocator_type` specialization, but not in any other 
subarray or const_subarray.  So many questions.  How can 
`boost::multi::subarray::get_allocator` compile if its return type 
doesn't exist?  Why does a subarray, a non-allocating type, need an 
allocator?  Why the free function?

boost::multi::lexicographical_compare 
(https://correaa.github.io/boost-multi/multi/reference/boost/multi/lexicographical_compare.html): 
the name more or less describes what the function presumably does, but 
not the edge cases.  In what order are elements compared?  What happens 
if the two arrays being compared have different numbers of elements? 
The same number of elements but different shapes?  Different rank?  Can 
I use this function with restrictions?  Does it use operator< or 
std::less, in case these differ?  Is the function an alias to operator< 
itself?

boost::multi::make_array_ref 
(https://correaa.github.io/boost-multi/multi/reference/boost/multi/make_array_ref-09.html): 
the overloads taking a specific (non-template-parameter) number of 
extents don't need to be documented separately.  I'm not sure they need 
to exist at all.  More to the point, I don't know what this function 
actually does.  If I were to guess, I would guess that it creates an 
array_ref of the given extents, pointing to previous allocated memory. 
The `P` template parameter could stand for "pointer", so the `data` 
variable could be a pointer to the raw data, with the type of the data 
being `decltype(*data)`.  But that's just a guess.  None of this is 
clear from the documentation.  I shouldn't have to guess.

boost::multi::move 
(https://correaa.github.io/boost-multi/multi/reference/boost/multi/move-041.html): 
why does this exist at all, when we already have std::move?  Or does it 
do something confusingly different from std::move, without documenting 
the difference anywhere?

boost::multi::operator+ 
(https://correaa.github.io/boost-multi/multi/reference/boost/multi/operator_plus-04.html): 
yes, random access iterators require `operator+`.  That information 
belongs with the actual iterator types.  There is no need to include 
`operator+`, or most of the other operators, in the list of free functions.

boost::multi::operator- 
(https://correaa.github.io/boost-multi/multi/reference/boost/multi/operator_minus-004.html): 
see boost::multi::operator+.

How is the list of free functions sorted anyway?  It looks alphabetical, 
but some operators are under 'o' and others are at the very end of the list.

boost::multi::operator->* 
(https://correaa.github.io/boost-multi/multi/reference/boost/multi/operator_ptrmem.html): 
this is an interesting function.  It may even deserve a place among the 
free functions.  It definitely deserves actual documentation.

Speaking of `extents_t`, it doesn't seem to be defined anywhere.  It's 
not included among the namespace-level symbols. 
`boost::multi::array::extents_type` points be to 
`layout_type::extents_type` (but without an actual link). 
`boost::multi::array::layout_type` points me to `array_ref<T, D, 
multi::allocator_traits<allocator_type>::pointer>::layout_type` (again 
without link).  `boost::multi::array_ref::layout_type` points me to 
`subarray_base::layout_type`.  `subarray_base` is not documented 
anywhere, but `boost::multi::subarray::layout` points to the `Layout` 
template parameter, which in turn defaults to `layout_t<D, 
std::pointer_traits<ElementPtr>::difference_type>>`.  `layout_t`, in 
turn, is also not defined anywhere.

boost::multi::operator/ 
(https://correaa.github.io/boost-multi/multi/reference/boost/multi/operator_slash.html): 
well, the synopsis at least confirms that `multi::extents_t` exists. 
Unfortunately it tells me nothing what this function actually does. 
What does it mean to divide an iterator by an `extents_t`?

boost::multi::operator^ 
(https://correaa.github.io/boost-multi/multi/reference/boost/multi/operator_xor.html): 
the actual documentation is here: 
https://correaa.github.io/boost-multi/multi/tutorial.html#tutorial_restrictions. 
  Link to that page, or copy the relevant information from it.  Or 
better yet, do both.

boost::multi::operator~ 
(https://correaa.github.io/boost-multi/multi/reference/boost/multi/operator_bitnot-0a.html): 
despite the insistence of the documentation that this is a bitwise 
negation operator, I have my doubts.  Why does an array need a bitwise 
negation operator, and supposing it does, why is it not in the 
`elementwise` namespace?

boost::multi::origin 
(https://correaa.github.io/boost-multi/multi/reference/boost/multi/origin-05.html): 
why create a non-deprecated free function to forward to a deprecated 
member function?  Or does this function do something different?

boost::multi::ref 
(https://correaa.github.io/boost-multi/multi/reference/boost/multi/ref-050.html): 
I don't know why this exists or what it does.

boost::multi::restricted 
(https://correaa.github.io/boost-multi/multi/reference/boost/multi/restricted.html): 
no documentation aside from the parameter list, not even a return type. 
See operator^ above.

boost::multi::rotated 
(https://correaa.github.io/boost-multi/multi/reference/boost/multi/rotated-06.html): 
so the reason this exists as a free function is to allow nested C-style 
array as arguments.  It still needs to document its return type and 
semantics.

boost::multi::size 
(https://correaa.github.io/boost-multi/multi/reference/boost/multi/size-0fc.html): 
does this do anything different from std::size?  Why does it exist?

boost::multi::sizes 
(https://correaa.github.io/boost-multi/multi/reference/boost/multi/sizes-00.html): 
returns const_subarray::sizes_type, which is missing from the 
documentation entirely.  Does `const_subarray::sizes_type` exist?  How 
is it distinct from `boost::multi::extents_t`?  How are either of them 
distinct from `std::array<size_type>`?  Or is `sizes` not a plural at 
all, but short for `size signed`?

boost::multi::static_array_cast 
(https://correaa.github.io/boost-multi/multi/reference/boost/multi/static_array_cast-073.html): 
I have no idea what this does.  It's a cast, but it takes multiple 
arguments?  What does that even mean?

boost::multi::stride 
(https://correaa.github.io/boost-multi/multi/reference/boost/multi/stride.html): 
it looks like another one of those free functions that forward to member 
functions, but to which member function?  Which class in `boost::multi` 
has a `stride` member function?  Is it `boost::multi::cursor_t`?  Come 
to think of it, I have no idea what `boost::multi::cursor_t::stride` 
even does.  I don't even know its return type, all I know is that it is 
const and doesn't take any arguments.

boost::multi::swap 
(https://correaa.github.io/boost-multi/multi/reference/boost/multi/swap-059.html): 
swap semantics between owning arrays are clear, swap semantics between 
array views less so.

boost::multi::transposed 
(https://correaa.github.io/boost-multi/multi/reference/boost/multi/transposed.html): 
there is really only one thing this function can do, so the only thing 
missing from the documentation is the return type.

boost::multi::uninitialized_copy 
(https://correaa.github.io/boost-multi/multi/reference/boost/multi/uninitialized_copy.html): 
typo in the synopsis (which makes me wonder how this library even 
compiles; isn't the synopsis taken directly from the source code?). 
Also reference to the `detail` namespace in the synopsis.  Also I don't 
know what this actually does.  Copy into uninitialized memory, I guess, 
because it makes no sense to copy out from uninitialized memory.  What 
does it do that `std::uninitialized_copy` can't do?

boost::multi::unrotated 
(https://correaa.github.io/boost-multi/multi/reference/boost/multi/unrotated-03.html): 
see boost::multi::rotated, except this one for some reason doesn't work 
with C-style nested array?  Why not?

boost::multi::operator<< 
(https://correaa.github.io/boost-multi/multi/reference/boost/multi/operator_lshift-06.html): 
OK, it prints the array as text, but what does the result actually look 
like?

boost::multi::operator== 
(https://correaa.github.io/boost-multi/multi/reference/boost/multi/operator_eq-06.html): 
wait, no comparison between distinct array types (e.g. restriction and 
inplace_array)?

boost::multi::operator!= 
(https://correaa.github.io/boost-multi/multi/reference/boost/multi/operator_not_eq-0313.html): 
see boost::multi::operator==.

boost::multi::operator< 
(https://correaa.github.io/boost-multi/multi/reference/boost/multi/operator_lt-02.html): 
ordering between arrays is not clearly defined; see 
boost::multi::lexicographical_compare.

boost::multi::operator<= 
(https://correaa.github.io/boost-multi/multi/reference/boost/multi/operator_le-041.html): 
see boost::multi::operator<.

boost::multi::operator> 
(https://correaa.github.io/boost-multi/multi/reference/boost/multi/operator_gt-03.html): 
see boost::multi::operator<.

boost::multi::operator>= 
(https://correaa.github.io/boost-multi/multi/reference/boost/multi/operator_ge-01a.html): 
see boost::multi::operator<.

boost::multi::force_element_trivial 
(https://correaa.github.io/boost-multi/multi/reference/boost/multi/force_element_trivial.html): 
I have no objections to the documentation here.

boost::multi::force_element_trivial_default_construction 
(https://correaa.github.io/boost-multi/multi/reference/boost/multi/force_element_trivial_default_construction.html): 
see boost::multi::force_element_trivial.

boost::multi::force_element_trivial_destruction 
(https://correaa.github.io/boost-multi/multi/reference/boost/multi/force_element_trivial_destruction.html): 
see boost::multi::force_element_trivial.

boost::multi::serialization_array_version 
(https://correaa.github.io/boost-multi/multi/reference/boost/multi/serialization_array_version.html): 
the user doesn't need to know the actual value of the variable, but a 
sentence or two on its purpose and a link to 
https://correaa.github.io/boost-multi/multi/interop.html#interop_serialization 
would be nice.

boost::multi::elementwise::apply_bind_t 
(https://correaa.github.io/boost-multi/multi/reference/boost/multi/elementwise/apply_bind_t-0b.html): 
undocumented.  No idea what it does.  Probably the return type of a 
similiarly undocumented function.

boost::multi::elementwise::default_zero_f 
(https://correaa.github.io/boost-multi/multi/reference/boost/multi/elementwise/default_zero_f.html): 
see boost::multi::elementwise::apply_bind_t.

boost::multi::elementwise::identity_bind 
(https://correaa.github.io/boost-multi/multi/reference/boost/multi/elementwise/identity_bind.html): 
  see boost::multi::elementwise::apply_bind_t.

boost::multi::elementwise::abs 
(https://correaa.github.io/boost-multi/multi/reference/boost/multi/elementwise/abs-0b.html): 
this one is relatively well-documented, missing only the specific return 
type (which is probably something ugly that you'd never want to type out 
anyway, so no great loss).  The problem is that the function is 
described to return an "array", and "array" is a sloppy concept.  The 
library defines a whole bunch of "array" types which share a bunch of 
members, but which of these members are part of the "array" concept and 
which are specific to a particular concrete array type is never 
explicitly specified.  There is also the name confusion between 
`boost::multi::array` the concrete type and the more general "array" 
concept.  In practice, what boost::multi::elementwise::abs probably 
returns is a `boost::multi::restriction`, which a lot more specific and 
useful (the utter lack of documentation for `boost::multi::restriction` 
notwithstanding).

boost::multi::elementwise::apply 
(https://correaa.github.io/boost-multi/multi/reference/boost/multi/elementwise/apply.html): 
I don't know what this does.  I guess it's an elementwise version of 
std::apply.  I guess it takes the function arguments from arrays of the 
same extents, creates another array of the same extents return the 
return values, and returns that array.  I also guess that the function 
itself is not taken from an array, but passed directly.  Is the returned 
array lazy or eager?  Does it accept C-style arrays and std::array or 
just boost::multi arrays?  Can I mix direct arguments with array arguments?

On the good news, I think I may have solved the mystery of the 
underscore at the end of boost::multi::apply_.  It's so that 
boost::multi::elementwise::apply can call it without namespace specifier 
and without recursively calling itself.  I think.  Maybe.

boost::multi::elementwise::apply_front 
(https://correaa.github.io/boost-multi/multi/reference/boost/multi/elementwise/apply_front.html): 
another variety of elementwise std::apply.  I have literally no idea 
what it does differently than boost::multi::elementwise::apply.  What 
does "front" mean in this context?

boost::multi::elementwise::exp 
(https://correaa.github.io/boost-multi/multi/reference/boost/multi/elementwise/exp.html): 
see boost::multi::elementwise::abs.

boost::multi::elementwise::eye 
(https://correaa.github.io/boost-multi/multi/reference/boost/multi/elementwise/eye-0c.html): 
I literally have no idea what this function does.  An eye is a part of 
animal anatomy.  I have never heard the word used in the context of a 
mathematical function.

boost::multi::elementwise::log 
(https://correaa.github.io/boost-multi/multi/reference/boost/multi/elementwise/log.html): 
see boost::multi::elementwise::abs.

boost::multi::elementwise::map 
(https://correaa.github.io/boost-multi/multi/reference/boost/multi/elementwise/map.html): 
I have, in fact heard of mapping a function over a (sequence of) 
array(s).  It's what the Python `map` function (technically class) does. 
  But Python's `map` takes an arbitrary sequence of arrays and 
boost::multi::elementwise::map takes exactly two.  I'm confused.  Does 
boost::multi::elementwise::map, in fact, do something completely different?

boost::multi::elementwise::operator&& 
(https://correaa.github.io/boost-multi/multi/reference/boost/multi/elementwise/operator_and.html): 
I don't know what this does.  Does it return an array of pairwise values,
each with a value of `(a && b)`, where `a` and `b` come from 
corresponding input arrays?  Lazily maybe?  Or does it reduce all of 
these values to a single boolean?

boost::multi::elementwise::operator* 
(https://correaa.github.io/boost-multi/multi/reference/boost/multi/elementwise/operator_star.html): 
fair enough, but see boost::multi::elementwise::abs for concerns about 
the return value.

boost::multi::elementwise::operator+ 
(https://correaa.github.io/boost-multi/multi/reference/boost/multi/elementwise/operator_plus.html): 
see boost::multi::elementwise::operator*.

boost::multi::elementwise::operator- 
(https://correaa.github.io/boost-multi/multi/reference/boost/multi/elementwise/operator_minus-0ee.html): 
see boost::multi::elementwise::operator*.

boost::multi::elementwise::operator/ 
(https://correaa.github.io/boost-multi/multi/reference/boost/multi/elementwise/operator_slash.html): 
see boost::multi::elementwise::operator*.

boost::multi::elementwise::operator| 
(https://correaa.github.io/boost-multi/multi/reference/boost/multi/elementwise/operator_bitor-02.html): 
I would have expected this to continue the pattern set by 
boost::multi::elementwise::operator*, but instead of taking two arrays, 
it takes an array and a function.  So what does it do?  The description, 
"Bitwise disjunction operators", does not help.

boost::multi::elementwise::operator|| 
(https://correaa.github.io/boost-multi/multi/reference/boost/multi/elementwise/operator_or.html): 
see boost::multi::elementwise::operator&&.

boost::multi::elementwise::zeros 
(https://correaa.github.io/boost-multi/multi/reference/boost/multi/elementwise/zeros-0c.html): 
Let me guess, this creates a lazy array of zeros?  On second though, 
don't let me guess.  Tell me.

boost::multi::pmr::array 
(https://correaa.github.io/boost-multi/multi/reference/boost/multi/pmr/array.html) 
and boost::multi::pmr::dynamic_array 
(https://correaa.github.io/boost-multi/multi/reference/boost/multi/pmr/dynamic_array.html): 
no complaints.

Non-documentation issues:

Deleting the address-of operator for boost::multi::array and using 
operator& as a conversion operator instead is not acceptable.

`taked` is still not a word in the English language.  Use `taken` instead.

If array::operator~ does the documentation says it does, why is it not 
in namespace elementwise?  (The documentation says "Bitwise negation 
operators".)

Why does boost::multi::cursor_t::operator[] not accept multiple 
arguments like boost::multi::array::operator[]?

Why do operators [] and () not accept tuple-likes as arguments?

I notice that the set of elementwise operators is rather small.  Bitwise 
operators are missing.  Unary minus is missing.  Comparison operators 
are missing.  Some of these would cause conflict with other operators in 
the library, others would not.


Verdict: I would like to see a better multidimensional array library in 
Boost.  I would even like to see *this* multidimensional array library 
in boost, if it were properly documented with some of the rough edges 
filed off.  But I can barely see an improvement on the state of the 
documentation since the last review.  I feel like I spent more time and 
effort on this review than the submitter did on the documentation.  I 
also feel that I have barely scratched the surface in this review.  I 
didn't even notice that major components (layout_t and extents_t) were 
missing from the documentation until halfway through.

I don't want to outright reject a library that is already conditionally 
accepted, especially a library that meets a need I have, but I don't 
think the library substantially closer to ready for inclusion in Boost 
than the last time I saw it.  I therefore vote to CONDITIONALLY ACCEPT 
the library, on the condition that every single one of my complaints is 
addressed, followed by another review.

A summary of my most important requirements for the documentation:
   - If it's part of the public interface, it needs to be documented.
   - If it's not part of the public interface, it should not be documented.
   - Documentation must not refer to types that are not documented. 
That's effectively a broken link in the documentation, which is 
unacceptable.
   - If it's documented, it needs a human-written description in 
addition to the machine-generated synopsis.
   - Every parameter must be documented.
     - If it's of a concrete type that the library defines, it should 
link to the documentation of that type.
     - If it's a template type parameter, then the requirements of that 
type must be documented.
     - In addition to type, the semantic meaning of the parameter must 
be documented.
   - Every return value must be documented.
     - If it's of a concrete type that the library defines, it should 
link to that type.
     - If it's of an unspecified type that models a concept, the concept 
must be documented.
     - In addition to type, the semantic meaning of the return value 
must be documented.

But read the full long list, because it contains a lot of specifics that 
I also feel are important.


-- 
Rainer Deyke - [email protected]

_______________________________________________
Boost mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://lists.boost.org/mailman3/lists/boost.lists.boost.org/
Archived at: https://lists.boost.org/archives/list/[email protected]/message/PGKUVK46MHDRFSM37Y6ELV4GTNZNSUQ6/
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.