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/