<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
        "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
	<title>Undo the rename of views::move and views::as_const</title>

	<style>
	p {text-align:justify}
	li {text-align:justify}
	blockquote.note
	{
		background-color:#E0E0E0;
		padding-left: 15px;
		padding-right: 15px;
		padding-top: 1px;
		padding-bottom: 1px;
	}
	ins {color:#00A000}
	del {color:#A00000}
	</style>
</head>
<body>

<address align=right>
Document number: P2501R0
<br/>
Audience: LEWG
<br/>
<br/>
<a href="mailto:ville.voutilainen@gmail.com">Ville Voutilainen</a><br/>
2021-12-09<br/>
</address>
<hr/>
<h1 align=center>Undo the rename of views::move and views::as_const</h1>

<h2>Abstract</h2>

<p>
  This paper seeks to undo the rename of views::move to views::all_move,
  and the rename of views::as_const to views::all_const. The renames
  make no sense, and are based on an unsubstantiated knee-jerk reaction,
  creating a situation where the new names are inconsistent and incorrect,
  and don't fit into the design intent of our range views.
</p>

<h2>The alleged confusion</h2>

<p>
  The suggested rationale for the rename was that it's confusing to have
  a views::move and a std::move (two of them), and a views::as_const
  and a std::as_const. It was even suggested that that's confusing
  for "everybody".
</p>
<p>A further explanation was that it's allegedly confusing whether
  a views::move or a views::as_const applies to the range or view provided
  as the argument, or to the elements.</p>

<h3>There is no confusion, or there at least shouldn't be</h3>

<p>
  Both of these suggested confusions are non-sensical. First of all,
  <ol>
    <li>views are (lazy) algorithms.</li>
    <li>those algorithms, like all other algorithms, always apply to
      the elements.</li>
  </ol>
</p>
<p>This includes algorithms that look like they apply to a range or view;
  an example is join (or join_with). Some might claim that it joins
  ranges. But it doesnt, it joins the elements of the ranges. It merely
  creates an algorithm that allows viewing the elements as a flattened
  view. Whether it somewhere internally somehow does that by joining
  ranges or views is an implementation detail, not the API-level conceptual
  functionality provided by the view.</p>
<p>And you can see that the joining of the inner things is an implementation
  detail; all that is exposition-only. What join gives you is the joined
  view of the elements. It joins elements.</p>
<p>There was a suggestion that filter is somehow another view that
  filters a range. Sure, it does - by filtering elements. The range
  is there just as a vessel for the elements, and the filtering algorithm
  applies to them, not to the range. The range is there only as an exposition-only implementation detail, and the predicate applies to an element.</p>
<p>It's the same thing for views::move and views::as_const. The first one
  gives you a view of the elements cast to rvalue references, i.e. a view
  of the moved elements. Like applying std::move on each element. The second
  one gives you a view of the elements with as_const applied to each element.
</p>
<p>
  And that's why views::move and views::as_const are the *CORRECT* names for
  these views. They say what the view does on the tin. They are views
  that apply a std::move or a std::as_const to their elements. *Of course*
  they are named views::move and views::as_const, the similarity of those
  names is 100% intentional, because those are the operations that the views
  apply!
</p>
<p>As it's explained in <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2278r1.html#naming">p2278r1.html#naming</a>, "The advantage of views::as_const is that it is a mirror of std::as_const and so sharing a name seems reasonable."</p>
<p>That's more than just reasonable. It's the right name. Yes, the paper
  admits that it's possible to manage to misuse std::as_const where you want
  to use std::ranges::views::as_const. But such possible misuses don't change
  the _fact_ that the view mirrors std::as_const, and applies effectively std::as_const
to every element. The same goes for views::move; it applies std::move to every element.</p>

<p>
  All of this is intentional. The name of the lazy algorithm tells its users
  what operation (transformation) it applies to the elements it lazily operates
  on.
</p>

<p>
  The suggested alternatives, views::all_move and views::all_const don't
  do that. They are themselves confusing, in a far worse way than the correct
  names are. "What do you mean 'all'? The view applies to all of the elements
  already, why are you saying 'all', that makes no sense." And they don't
  communicate what transform they apply on the elements. They're now lazy
  algorithms with completely weird, inconsistent, and inexplicable names.
  The only explanation for their names would be "we wanted to make them
  different from the operations they perform, because.. uh.. yeah." I can't
  explain that. The original names are perfectly explicable, this is how
  range views work, this is what they do. The renamed names require an
  out-of-the-blue explanation that doesn't ride on the design principles
  of our range views, they're completely hacked names, renamed on a whim,
  with no real field usage behind them. That makes them design-wise inconsistent
  names, and they should not be.
</p>

<h2>The solution</h2>

<p>
  This is simple: undo the rename, and ship views::move as views::move,
  and ship views::as_const as views::as_const.</p>
</body>
</html>
