<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
        "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
	<title>"Changing scope for lambda trailing-return-type" (P2036) should not be a DR</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: P2598R0
<br/>
Audience: EWG, CWG
<br/>
<br/>
<a href="mailto:ville.voutilainen@gmail.com">Ville Voutilainen</a><br/>
2022-05-29<br/>
</address>
<hr/>
<h1 align=center>"Changing scope for lambda trailing-return-type" (P2036) should not be a DR</h1>

<h2>Abstract</h2>

<p>
  This paper explains why changing the lambda trailing-return-type scope
  and the other name lookup changes for lambdas should not be retroactively
  applied, i.e. why the changes should not be applied as DRs. Those changes
  silently change the meaning of valid code, with possibly breaking results,
  and it's irresponsible to make such a change even with the mitigation
  strategies proposed in P2579, due to the silent nature of the change.
  P2036 and P2579 are arguably fine as sanity improvements, but they should
  not be applied where nobody expects them, and making them DRs doesn't
  really serve anybody, because existing compilers will not magically
  gain those DR implementations.
</p>

<h2>The problem with the DR suggestion</h2>

<p>In the unfortunate event that P2036+P2579 still end up breaking
  code (with init-captures, or by changing something that wasn't const
  into const), we have a many-fold problem:
  <ul>
    <li>An implementation might just not implement the DR, and we can't
      force them to.</li>
    <li>An implementation might implement the DR so that you still need
      to opt in, via -fnew-lambda-name-lookup or some such.</li>
    <li>Perfectly valid code that has been valid since C++11 or C++14
      changes meaning, in possibly surprising ways.</li>
    <li>Some users may be stuck with specific older compiler versions but
      also need to use newer ones or newer standard modes, so they would need
      to cope with multiple different meanings of the same code, across
      multiple compilers.</li>
  </ul>
</p>
<p>This isn't helping anyone. None of that is stable and portable. 
  Those who wish to have the same improved
  semantics won't get them, and those who wish to avoid uninvited breakage
  of their code won't get that either. While we could entertain a
  feature-testing macro for this change, it's just more straightforward
  to leave the pre-C++23 semantics alone, and enable this silent breaking
  change in C++23 mode and onwards, but not otherwise.
</p>

<h2>"But you can write code that avoids the problems, so that the semantics
  are the same in every conformance mode on every implementation, DR or
  not"</h2>
<p>
  Sure, I can. If I'm aware of having to do so when I already wrote
  100% well-formed, valid, and works-as-intended code until WG21 decided
  to change its meaning. Vice versa, it's possible to write C++20 or C++11
  code that avoids the problems depicted in P2036, and both of these
  are arguments towards "if you know what you're doing, all's well ends well".
  P2036 may make such an argument, but the existing code came first. And we
  don't and can't know how much of possibly problematic code exists, and where.
</p>
<p>While it's not very nice to make such a silent change in meaning
  to begin with, it's far worse to maybe or maybe not apply it retroactively.
  That leaves unaware users without any mitigation strategy, they need
  to become aware and change their existing code, which they thought
  to be valid. By not making this change a DR, they at least have a simple
  solution of not bumping the standard version they use. With the DR, they
  have no such simple solution, all they have is chaos that requires immediate
  action, as opposed to being able to choose when to act.
</p>

<h2>The solution</h2>

<p>
  The solution is simple, do what we always do, when considering breaking
  changes, especially silent ones: do not apply them retroactively, don't
  make these changes a DR. That gives users an escape hatch, allowing them
  to keep their code in a working state without changing it. And since
  it's a change across standard versions, it gives them the ability to
  decide when to deal with the possible breakage, and trust not having to do
  so prior to that.
</p>

</body>
</html>
