ericniebler/stl2

Is join the best name for what it does?

ericniebler opened this issue · 5 comments

The join_view flattens a range of ranges. "Join" is a term of art in async programming; think, thread.join(). We ultimately hope to extend ranges in the direction of asynchronous ranges, at which point the name "join" may prove misleading.

Another data point is that there is a related operation in the range-v3 library that we may ultimately propose for the standard: concat. Concat taken N ranges and concatenates them. So renaming "join" to "concat" creates a problem.

Another consideration: we have a "split" view, and "split" and "join" have a nice duality, terminology-wise.

Possible replacement names for join:

  • concat
  • flatten

Possible replacement name for concat:

  • append

There is precedent for using the name append for what concat does in range-v3. See the append member of the standard containers.

Ruby's way might be interesting. It has

  • flatten: flattens (all levels of) nested ranges.
  • flatten(level): flattens nested ranges (up to the specified level).
  • join(delimiter): similar to range-v3's | join(delimiter) (though specialized for strings).
  • concat(...): concatenates multiple ranges.

I think that

  • if we also consider flattening of multiply nested ranges, flatten would be better; flatten(level) is more intuitive than concatenate(level) and join(level).
  • it makes sense to use different names for range-v3's | join and range-v3's | join(delimiter).

Interesting. I have never needed to flatten more than one level, and certainly not an arbitrary number of levels. My gut says that we don't really need that. But my gut is not infallible.

flatten(level) feels unimplementable in a statically typed language. flatten<level>, sure, but with a runtime level how would you specify the associated types of the result range?

I have never needed to flatten more than one level, and certainly not an arbitrary number of levels. My gut says that we don't really need that.

Agreed. Flatten-one-level would be more useful than flatten-all-level. Well, both of these behaviors are used in meta-programming libraries and dynamically typed languages:

  • Fusion, brigand and Ruby do flatten-all-level.
  • Hana, metal and JavaScript do flatten-one-level.

I think one reason of adopting flatten-all-level is that ranges with different levels of nesting (e.g. [1, 2, [3, 4], [[5, [6]], 7]]) are not "unnatural" constructs in meta-programming libraries and dynamically typed languages.

But C++ doesn't have ranges with different levels of nesting (unless we treat any/optional/variant element types specially, e.g. treating a value of optional<Array> as [[...]] or [])). This would make flatten-all-level less useful in C++.

but with a runtime level how would you specify the associated types of the result range?

Ah, good point! Its value_type gets inpractical.
Thanks.