220 32544 <795341bd-d042-49c9-9eba-6b8ac6ca8a5e@isocpp.org> article
Path: news.gmane.org!.POSTED!not-for-mail
From: Mingxin Wang <wmx16835vv@163.com>
Newsgroups: gmane.comp.lang.c++.isocpp.proposals
Subject: Re: relaxing rules for ternary operator. Allow
 incompatible types.
Date: Sun, 21 May 2017 06:00:03 -0700 (PDT)
Lines: 237
Approved: news@gmane.org
Message-ID: <795341bd-d042-49c9-9eba-6b8ac6ca8a5e@isocpp.org>
References: <1b5ee8eb-53df-4e98-af2f-829c7bc2e5b2@isocpp.org>
 <9064929.QEV8q21eIZ@tjmaciei-mobl1>
 <99350a9e-0c6b-468d-9761-f2b2b052275e@isocpp.org>
Reply-To: std-proposals@isocpp.org
NNTP-Posting-Host: blaine.gmane.org
Mime-Version: 1.0
Content-Type: multipart/mixed; 
	boundary="----=_Part_2126_688443543.1495371603183"
X-Trace: blaine.gmane.org 1495371612 25687 195.159.176.226 (21 May 2017 13:00:12 GMT)
X-Complaints-To: usenet@blaine.gmane.org
NNTP-Posting-Date: Sun, 21 May 2017 13:00:12 +0000 (UTC)
Cc: ma.kalbfuss@web.de
To: ISO C++ Standard - Future Proposals <std-proposals@isocpp.org>
Original-X-From: std-proposals+bncBDNMBNHJWIGBBU46Q3EQKGQE4OB6ZGI@isocpp.org Sun May 21 15:00:06 2017
Return-path: <std-proposals+bncBDNMBNHJWIGBBU46Q3EQKGQE4OB6ZGI@isocpp.org>
Envelope-to: gclcip-std-proposals@m.gmane.org
Original-Received: from mail-oi0-f71.google.com ([209.85.218.71])
	by blaine.gmane.org with esmtp (Exim 4.84_2)
	(envelope-from <std-proposals+bncBDNMBNHJWIGBBU46Q3EQKGQE4OB6ZGI@isocpp.org>)
	id 1dCQSq-0006PW-Dh
	for gclcip-std-proposals@m.gmane.org; Sun, 21 May 2017 15:00:04 +0200
Original-Received: by mail-oi0-f71.google.com with SMTP id o65sf135173567oif.15
        for <gclcip-std-proposals@m.gmane.org>; Sun, 21 May 2017 06:00:05 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=isocpp-org.20150623.gappssmtp.com; s=20150623;
        h=date:from:to:cc:message-id:in-reply-to:references:subject
         :mime-version:x-original-sender:reply-to:precedence:mailing-list
         :list-id:x-spam-checked-in-group:list-post:list-help:list-archive
         :list-subscribe:list-unsubscribe;
        bh=j5dMZEGA0DvnvBt+FRMF+MTSDgcEac5xMhwNFUfmd6E=;
        b=czQ0+qtQq6TvcW0C0lxGYBl68RIm201Jv36TDJzyFsmtfjnaDPUwxEhfW7qYNH9NAU
         jdGLUzYUUCWgWRN04UKGu3cVKoYXMpJH1nOSwvOOhL9ZdtFfJ/4eDPjuADDLkdRF/N5B
         BzxHO3UHPO//1n95gjEuNneUWl7AW06ItwGQfWbAUPRhrIdpDB1iLhHuOI1t6OdHF+zI
         VWlZF/zqhy2UFMe4Nro9+c6YedUkV2YZvptspMxsugR1SedDauEvRed7eyJB+hJB4hPR
         IKVaxC3Y+tyU671+7+FX8+aMa1c01irTzZgJnW6wTIdyV1E0s3yM35qtGSpycyTf2khQ
         xkpw==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=1e100.net; s=20161025;
        h=x-gm-message-state:date:from:to:cc:message-id:in-reply-to
         :references:subject:mime-version:x-original-sender:reply-to
         :precedence:mailing-list:list-id:x-spam-checked-in-group:list-post
         :list-help:list-archive:list-subscribe:list-unsubscribe;
        bh=j5dMZEGA0DvnvBt+FRMF+MTSDgcEac5xMhwNFUfmd6E=;
        b=eVFb2BzWm8eXXMVvumjq0E/T/jf2yLyZGFwXDLHzDN0OLQbWagbKsZjcu3yc2Z9gCt
         etXyjf0cjyWaLjXOORR4ou5qcF2Q38RHaRJQdWNGFFRUYDaNlKcm4rkATqdzpS8r4KMu
         CD3WsDXdg9M3NEw24Ji/ghiOG+sjvCIde1aQJvKRRkl9hDrQxHPgOZezfYeau0cbmP3b
         AZsClWHt+HqGcIcrNSuAf40tGa3FIK9Po4U4HKXZZtseMjucX6QG8TNUKtV1qO/RUbmi
         2EJTVI/vz4zpcyp/PBwzfnfEMAllV8OTgqAhs2OjxKOwcxguq2kTxV6QcruXreI6elVR
         to4g==
X-Gm-Message-State: AODbwcCT0417+iZPySX7tZAoab+KDUb9aLPWVTkt35OSY56fA+4v5N0y
	xjEJMOh1PSkSMNuf
X-Received: by 10.157.10.86 with SMTP id 80mr7870170otg.9.1495371604559;
        Sun, 21 May 2017 06:00:04 -0700 (PDT)
X-BeenThere: std-proposals@isocpp.org
Original-Received: by 10.157.27.130 with SMTP id z2ls1823620otd.45.gmail; Sun, 21 May
 2017 06:00:03 -0700 (PDT)
X-Received: by 10.157.14.91 with SMTP id n27mr386945otd.8.1495371603780;
        Sun, 21 May 2017 06:00:03 -0700 (PDT)
In-Reply-To: <99350a9e-0c6b-468d-9761-f2b2b052275e@isocpp.org>
X-Original-Sender: wmx16835vv@163.com
Precedence: list
Mailing-list: list std-proposals@isocpp.org; contact std-proposals+owners@isocpp.org
List-ID: <std-proposals.isocpp.org>
X-Google-Group-Id: 399137483710
List-Post: <https://groups.google.com/a/isocpp.org/group/std-proposals/post>, <mailto:std-proposals@isocpp.org>
List-Help: <https://support.google.com/a/isocpp.org/bin/topic.py?topic=25838>, <mailto:std-proposals+help@isocpp.org>
List-Archive: <https://groups.google.com/a/isocpp.org/group/std-proposals/>
List-Subscribe: <https://groups.google.com/a/isocpp.org/group/std-proposals/subscribe>,
 <mailto:std-proposals+subscribe@isocpp.org>
List-Unsubscribe: <mailto:googlegroups-manage+399137483710+unsubscribe@googlegroups.com>,
 <https://groups.google.com/a/isocpp.org/group/std-proposals/subscribe>
Xref: news.gmane.org gmane.comp.lang.c++.isocpp.proposals:32544
Archived-At: <http://permalink.gmane.org/gmane.comp.lang.c++.isocpp.proposals/32544>

------=_Part_2126_688443543.1495371603183
Content-Type: multipart/alternative; 
	boundary="----=_Part_2127_711408470.1495371603183"

------=_Part_2127_711408470.1495371603183
Content-Type: text/plain; charset="UTF-8"

You may as well consider the following situations:

*Loops*

It is difficult for compilers to generate code for loops with the feature 
you proposed, e.g.:

void foo(int n) {
  /* A: Do something before the loop */
  for (int i = 0; i < n; ++i) {
    /* B: Do something */
    auto x = runtime_condition() ? A{} : B{};
    /* C: Do some other things with x */
  }
  /* D: Do something after the loop */
}
*Code Snippet 1*

As far as I am concerned, here is the equivalent of the code that the 
compiler would automatically generate for the code above (with your method):

template <class T>
void bar(int i, int n, T x) {
  /* C: Do some other things with x */
  ++i;
  if (i < n) {
    /* B: Do something */
    if (runtime_condition()) {
      bar(i, n, A{});
    } else {
      bar(i, n, B{});
    }
  }
}

void foo(int n) {
  /* A: Do something before the loop */
  if (0 < n) {
    /* B: Do something */
    if (runtime_condition()) {
      bar(1, n, A{});
    } else {
      bar(1, n, B{});
    }
  }
  /* D: Do something after the loop */
}
*Code Snippet 2*

It is too complicated! Moreover, as the recursive call of the "function 
template bar" is not able to be optimized, it will possibly increase the 
runtime overhead.

*Size*

Compilers may generate a lot of redundant code when the feature is used 
extensively, e.g.:

auto x0 = runtime_condition_0() ? A0{} : B0{};
auto x1 = runtime_condition_1() ? A1{} : B1{};
// ...
auto xn = runtime_condition_n() ? An{} : Bn{};
*Code Snippet 3*

As you introduced, the compiler is supposed to generate code for every 
path! For the code above, it requires O(2^n) size for code generation, 
which is NOT acceptable in most cases.

In fact, the challenges above can be solved gracefully with the "proxies" 
and the "wrappers".

As the condition is determined at runtime, the concrete type cannot be 
deduced at compile time. The only reason for us to save the returned value 
is that *they have similar expressions and semantics*. We can simply 
extract the common expressions of the types which are used in the context 
to a "proxy", and save the returned value with a "wrapper", e.g. Code 
Snippet 1 can be reconstructed as is shown below (with better performance 
and smaller size):

/* Declares the common expressions required in the context */
proxy P {
  void f_0();
  double f_1(int, int);
};

void foo(int n) {
  /* A: Do something before the loop */
  for (int i = 0; i < n; ++i) {
    /* B: Do something */
    Wrapper<P> x(runtime_condition() ? Wrapper<P>(A{}) : Wrapper<P>(B{}));
    P p = x.get_proxy();
    /* C: Do some other things with p */
  }
  /* D: Do something after the loop */
}
*Code Snippet 4*

Mingxin Wang

-- 
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/795341bd-d042-49c9-9eba-6b8ac6ca8a5e%40isocpp.org.

------=_Part_2127_711408470.1495371603183
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div><font face=3D"georgia, serif">You may as well conside=
r the following situations:<br></font></div><div><font face=3D"georgia, ser=
if"><br></font></div><div><div style=3D"font-family: georgia, serif;"><b><f=
ont size=3D"4">Loops</font></b></div><div style=3D"font-family: georgia, se=
rif;"><br></div><div style=3D"font-family: georgia, serif;">It is difficult=
 for compilers to generate code for loops with the feature you proposed, e.=
g.:</div><div style=3D"font-family: georgia, serif;"><br></div><div style=
=3D"font-family: georgia, serif;"><div class=3D"prettyprint" style=3D"borde=
r: 1px solid rgb(187, 187, 187); word-wrap: break-word; background-color: r=
gb(250, 250, 250);"><code class=3D"prettyprint"><div class=3D"subprettyprin=
t"><div class=3D"subprettyprint">void foo(int n) {</div><div class=3D"subpr=
ettyprint">=C2=A0 /* A: Do something before the loop */</div><div class=3D"=
subprettyprint">=C2=A0 for (int i =3D 0; i &lt; n; ++i) {</div><div class=
=3D"subprettyprint">=C2=A0 =C2=A0 /* B: Do something */</div><div class=3D"=
subprettyprint">=C2=A0 =C2=A0 auto x =3D runtime_condition() ? A{} : B{};</=
div><div class=3D"subprettyprint">=C2=A0 =C2=A0 /* C: Do some other things =
with x */</div><div class=3D"subprettyprint">=C2=A0 }</div><div class=3D"su=
bprettyprint">=C2=A0 /* D: Do something after the loop */</div><div class=
=3D"subprettyprint">}</div></div></code></div><div style=3D"text-align: cen=
ter;"><b>Code Snippet 1</b></div></div><div style=3D"font-family: georgia, =
serif;"><br></div><div style=3D"font-family: georgia, serif;">As far as I a=
m concerned, here is the equivalent of the code that the compiler would aut=
omatically generate for the code above (with your method):<br></div><div st=
yle=3D"font-family: georgia, serif;"><br></div><div><div class=3D"prettypri=
nt" style=3D"border: 1px solid rgb(187, 187, 187); word-wrap: break-word; b=
ackground-color: rgb(250, 250, 250);"><code class=3D"prettyprint"><div clas=
s=3D"subprettyprint"><font color=3D"#660066"><div class=3D"subprettyprint">=
template &lt;class T&gt;</div><div class=3D"subprettyprint">void bar(int i,=
 int n, T x) {</div><div class=3D"subprettyprint">=C2=A0 /* C: Do some othe=
r things with x */</div><div class=3D"subprettyprint">=C2=A0 ++i;</div><div=
 class=3D"subprettyprint">=C2=A0 if (i &lt; n) {</div><div class=3D"subpret=
typrint">=C2=A0 =C2=A0 /* B: Do something */</div><div class=3D"subprettypr=
int">=C2=A0 =C2=A0 if (runtime_condition()) {</div><div class=3D"subprettyp=
rint">=C2=A0 =C2=A0 =C2=A0 bar(i, n, A{});</div><div class=3D"subprettyprin=
t">=C2=A0 =C2=A0 } else {</div><div class=3D"subprettyprint">=C2=A0 =C2=A0 =
=C2=A0 bar(i, n, B{});</div><div class=3D"subprettyprint">=C2=A0 =C2=A0 }</=
div><div class=3D"subprettyprint">=C2=A0 }</div><div class=3D"subprettyprin=
t">}</div><div class=3D"subprettyprint"><br></div><div class=3D"subprettypr=
int">void foo(int n) {</div><div class=3D"subprettyprint">=C2=A0 /* A: Do s=
omething before the loop */</div><div class=3D"subprettyprint">=C2=A0 if (0=
 &lt; n) {</div><div class=3D"subprettyprint">=C2=A0 =C2=A0 /* B: Do someth=
ing */</div><div class=3D"subprettyprint">=C2=A0 =C2=A0 if (runtime_conditi=
on()) {</div><div class=3D"subprettyprint">=C2=A0 =C2=A0 =C2=A0 bar(1, n, A=
{});</div><div class=3D"subprettyprint">=C2=A0 =C2=A0 } else {</div><div cl=
ass=3D"subprettyprint">=C2=A0 =C2=A0 =C2=A0 bar(1, n, B{});</div><div class=
=3D"subprettyprint">=C2=A0 =C2=A0 }</div><div class=3D"subprettyprint">=C2=
=A0 }</div><div class=3D"subprettyprint">=C2=A0 /* D: Do something after th=
e loop */</div><div class=3D"subprettyprint">}</div></font></div></code></d=
iv><div style=3D"text-align: center; "><font face=3D"georgia, serif"><b>Cod=
e Snippet 2</b></font></div><div><font face=3D"georgia, serif"><br></font><=
/div><div><font face=3D"georgia, serif">It is too complicated! Moreover, as=
 the recursive call of the &quot;function template bar&quot; is not able to=
 be optimized, it will possibly increase the runtime overhead.</font></div>=
<div><font face=3D"georgia, serif"><br></font></div><div><font face=3D"geor=
gia, serif" size=3D"4"><b>Size</b></font></div><div><font face=3D"georgia, =
serif"><br></font></div><div><font face=3D"georgia, serif">Compilers may ge=
nerate a lot of redundant code when the feature is used extensively, e.g.:<=
/font></div></div><div><font face=3D"georgia, serif"><br></font></div><div>=
<font face=3D"georgia, serif"><div class=3D"prettyprint" style=3D"border: 1=
px solid rgb(187, 187, 187); word-wrap: break-word; background-color: rgb(2=
50, 250, 250);"><code class=3D"prettyprint"><div class=3D"subprettyprint"><=
div class=3D"subprettyprint">auto x0 =3D runtime_condition_0() ? A0{} : B0{=
};</div><div class=3D"subprettyprint">auto x1 =3D runtime_condition_1() ? A=
1{} : B1{};</div><div class=3D"subprettyprint">// ...</div><div class=3D"su=
bprettyprint">auto xn =3D runtime_condition_n() ? An{} : Bn{};</div></div><=
/code></div><div style=3D"text-align: center; "><b>Code Snippet 3</b></div>=
<div><br></div><div>As you introduced, the compiler is supposed to generate=
 code for every path! For the code above, it requires O(2^n) size for code =
generation, which is NOT acceptable in most cases.</div><div><br></div><div=
>In fact, the challenges above can be solved gracefully with the &quot;prox=
ies&quot; and the &quot;wrappers&quot;.</div><div><br></div><div>As the con=
dition is determined at runtime, the concrete type cannot be deduced at com=
pile time. The only reason for us to save the returned value is that <b>the=
y have similar expressions and semantics</b>. We can simply extract the com=
mon expressions of the types which are used in the context to a &quot;proxy=
&quot;, and save the returned value with a &quot;wrapper&quot;, e.g. Code S=
nippet 1 can be reconstructed as is shown below (with better performance an=
d smaller size):</div></font></div><div><font face=3D"georgia, serif"><br><=
/font></div></div><div><div class=3D"prettyprint" style=3D"border: 1px soli=
d rgb(187, 187, 187); word-wrap: break-word; background-color: rgb(250, 250=
, 250);"><code class=3D"prettyprint"><div class=3D"subprettyprint"><font co=
lor=3D"#660066"><div class=3D"subprettyprint">/* Declares the common expres=
sions required in the context */</div><div class=3D"subprettyprint">proxy P=
 {</div><div class=3D"subprettyprint">=C2=A0 void f_0();</div><div class=3D=
"subprettyprint">=C2=A0 double f_1(int, int);</div><div class=3D"subprettyp=
rint">};</div><div class=3D"subprettyprint"><br></div><div class=3D"subpret=
typrint">void foo(int n) {</div><div class=3D"subprettyprint">=C2=A0 /* A: =
Do something before the loop */</div><div class=3D"subprettyprint">=C2=A0 f=
or (int i =3D 0; i &lt; n; ++i) {</div><div class=3D"subprettyprint">=C2=A0=
 =C2=A0 /* B: Do something */</div><div class=3D"subprettyprint">=C2=A0 =C2=
=A0 Wrapper&lt;P&gt; x(runtime_condition() ? Wrapper&lt;P&gt;(A{}) : Wrappe=
r&lt;P&gt;(B{}));</div><div class=3D"subprettyprint">=C2=A0 =C2=A0 P p =3D =
x.get_proxy();</div><div class=3D"subprettyprint">=C2=A0 =C2=A0 /* C: Do so=
me other things with p */</div><div class=3D"subprettyprint">=C2=A0 }</div>=
<div class=3D"subprettyprint">=C2=A0 /* D: Do something after the loop */</=
div><div class=3D"subprettyprint">}</div></font></div></code></div><div sty=
le=3D"text-align: center;"><font face=3D"georgia, serif"><b>Code Snippet 4<=
/b></font></div></div><div style=3D"text-align: left;"><font face=3D"georgi=
a, serif"><br></font></div><div style=3D"text-align: left;"><font face=3D"g=
eorgia, serif">Mingxin Wang</font></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/795341bd-d042-49c9-9eba-6b8ac6ca8a5e%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/795341bd-d042-49c9-9eba-6b8ac6ca8a5e=
%40isocpp.org</a>.<br />

------=_Part_2127_711408470.1495371603183--

------=_Part_2126_688443543.1495371603183--

.
