Topic: Parameters evaluated on use


Author: Douglas Boffey <douglas.boffey@gmail.com>
Date: Sat, 20 Dec 2014 07:18:13 -0800 (PST)
Raw View
------=_Part_1390_792138159.1419088693755
Content-Type: multipart/alternative;
 boundary="----=_Part_1391_1214910560.1419088693755"

------=_Part_1391_1214910560.1419088693755
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

Three inbuilt operators cannot be encapsulated in functions.  They are:

bool operator||(bool, bool) const noexcept;

bool operator&&(bool, bool) const noexcept;

template <typename T>
T operator?:(bool, T, T) const noexcept; // I know this isn=E2=80=99t legal=
, but=20
I=E2=80=99m sure you get my meaning ;)



the problem being that some arguments need not be evaluated.

There could be other functions that need to be written (for example,=20
selection on an enum).

Currently, the only way to simulate this is with macro functions, which is=
=20
fraught with problems.

My suggestion is that, should a formal parameter be preceded by =E2=80=98in=
line=E2=80=99,=20
the program only evaluates the parameter when used.

This would allow the above operators to be written thus:

bool operator||(bool a, inline bool b) const /* cannot say noexcept, as an=
=20
exception might be thrown in evaluating b, see below */ {
  if (a)
    return true;
  return b; // b only gets evaluated here!
}



And similarly for operator && and the (non-legal) operator?:.

Because evaluating an inline parameter might throw an exception, the=20
parameter should be followed by an exception specification.  (I=E2=80=99m n=
ot sure=20
about this one=E2=80=A6 it seems wrong that the callee should impose restri=
ctions=20
on the caller).

This could be easily implemented, by:

if the function is inline, replacing the parameter with the AST creating=20
the parameter, and if the function is out of line, passing a thunk to the=
=20
function, which the function would call.

--=20

---=20
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 e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

------=_Part_1391_1214910560.1419088693755
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Three inbuilt operators cannot be encapsulated in function=
s.&nbsp; They are:<br><br><div class=3D"prettyprint" style=3D"background-co=
lor: rgb(250, 250, 250); border-color: rgb(187, 187, 187); border-style: so=
lid; border-width: 1px; word-wrap: break-word;"><code class=3D"prettyprint"=
><div class=3D"subprettyprint"><span style=3D"color: #008;" class=3D"styled=
-by-prettify">bool</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">o=
perator</span><span style=3D"color: #660;" class=3D"styled-by-prettify">||(=
</span><span style=3D"color: #008;" class=3D"styled-by-prettify">bool</span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"co=
lor: #008;" class=3D"styled-by-prettify">bool</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">)</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"sty=
led-by-prettify">const</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"> noexcept</span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">;</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"><br><br></span><span style=3D"color: #008;" class=3D"styled-by-prettify">=
bool</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </spa=
n><span style=3D"color: #008;" class=3D"styled-by-prettify">operator</span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">&amp;&amp;(</span=
><span style=3D"color: #008;" class=3D"styled-by-prettify">bool</span><span=
 style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #=
008;" class=3D"styled-by-prettify">bool</span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">)</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by=
-prettify">const</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> noexcept</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=
<br></span><span style=3D"color: #008;" class=3D"styled-by-prettify">templa=
te</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><span =
style=3D"color: #008;" class=3D"styled-by-prettify">typename</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> T</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">&gt;</span><span style=3D"color: =
#000;" class=3D"styled-by-prettify"><br>T </span><span style=3D"color: #008=
;" class=3D"styled-by-prettify">operator</span><span style=3D"color: #660;"=
 class=3D"styled-by-prettify">?:(</span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">bool</span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"> T</span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> T</span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">)</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"co=
lor: #008;" class=3D"styled-by-prettify">const</span><span style=3D"color: =
#000;" class=3D"styled-by-prettify"> noexcept</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">;</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> </span><span style=3D"color: #800;" class=3D"sty=
led-by-prettify">// I know this isn=E2=80=99t legal, but I=E2=80=99m sure y=
ou get my meaning ;)</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"><br><br></span></div></code></div><br><br>the problem being that =
some arguments need not be evaluated.<br><br>There could be other functions=
 that need to be written (for example, selection on an enum).<br><br>Curren=
tly, the only way to simulate this is with macro functions, which is fraugh=
t with problems.<br><br>My suggestion is that, should a formal parameter be=
 preceded by =E2=80=98inline=E2=80=99, the program only evaluates the param=
eter when used.<br><br>This would allow the above operators to be written t=
hus:<br><br><div class=3D"prettyprint" style=3D"background-color: rgb(250, =
250, 250); border-color: rgb(187, 187, 187); border-style: solid; border-wi=
dth: 1px; word-wrap: break-word;"><code class=3D"prettyprint"><div class=3D=
"subprettyprint"><span style=3D"color: #008;" class=3D"styled-by-prettify">=
bool</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </spa=
n><span style=3D"color: #008;" class=3D"styled-by-prettify">operator</span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">||(</span><span s=
tyle=3D"color: #008;" class=3D"styled-by-prettify">bool</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> a</span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #000;"=
 class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=3D=
"styled-by-prettify">inline</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-pr=
ettify">bool</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"> b</span><span style=3D"color: #660;" class=3D"styled-by-prettify">)</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span s=
tyle=3D"color: #008;" class=3D"styled-by-prettify">const</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: #800;" class=3D"styled-by-prettify">/* cannot say noexcept, as an excepti=
on might be thrown in evaluating b, see below */</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"><br>&nbsp; </span><span style=3D"color: #008;" class=3D=
"styled-by-prettify">if</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">a</sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">)</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"><br>&nbsp; &nbsp; </spa=
n><span style=3D"color: #008;" class=3D"styled-by-prettify">return</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">true</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">;</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify"><br>&nbsp; </span><span style=3D"color: #00=
8;" class=3D"styled-by-prettify">return</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> b</span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">;</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"> </span><span style=3D"color: #800;" class=3D"styled-by-prettif=
y">// b only gets evaluated here!</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br></span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">}</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"><br><br></span></div></code></div><br><br>And similarly for operat=
or &amp;&amp; and the (non-legal) operator?:.<br><br>Because evaluating an =
inline parameter might throw an exception, the parameter should be followed=
 by an exception specification.&nbsp; (I=E2=80=99m not sure about this one=
=E2=80=A6 it seems wrong that the callee should impose restrictions on the =
caller).<br><br>This could be easily implemented, by:<br><br>if the functio=
n is inline, replacing the parameter with the AST creating the parameter, a=
nd if the function is out of line, passing a thunk to the function, which t=
he function would call.<br></div>

<p></p>

-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_1391_1214910560.1419088693755--
------=_Part_1390_792138159.1419088693755--

.


Author: David Krauss <potswa@gmail.com>
Date: Sun, 21 Dec 2014 11:05:22 +0800
Raw View
--Apple-Mail=_11794F8F-EEA6-41B5-98D7-792A9E9E1326
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=UTF-8

It=E2=80=99s helpful to mention previous discussion when it exists=E2=80=A6

https://groups.google.com/a/isocpp.org/d/topic/std-proposals/kwDmEOQL7oE/di=
scussion <https://groups.google.com/a/isocpp.org/d/topic/std-proposals/kwDm=
EOQL7oE/discussion>
https://groups.google.com/a/isocpp.org/d/topic/std-proposals/DnxRfo_uQl8/di=
scussion <https://groups.google.com/a/isocpp.org/d/topic/std-proposals/DnxR=
fo_uQl8/discussion>

The obvious questions are:

1. How does the ABI handle it? Does the thunk wrap an indirect call (std::f=
unction-like) or is each thunk a distinct type (lambda-like)? It sounds lik=
e you=E2=80=99ve left it to the ABI, with indirect thunks.
2. How many times is the argument evaluated? Once (cache-like) or per use (=
conversion-like)?


> On 2014=E2=80=9312=E2=80=9320, at 11:18 PM, Douglas Boffey <douglas.boffe=
y@gmail.com> wrote:
>=20
> if the function is inline, replacing the parameter with the AST creating =
the parameter, and if the function is out of line, passing a thunk to the f=
unction, which the function would call.

--=20

---=20
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 e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

--Apple-Mail=_11794F8F-EEA6-41B5-98D7-792A9E9E1326
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=UTF-8

<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html charset=
=3Dutf-8"></head><body style=3D"word-wrap: break-word; -webkit-nbsp-mode: s=
pace; -webkit-line-break: after-white-space;" class=3D""><div class=3D"">It=
=E2=80=99s helpful to mention previous discussion when it exists=E2=80=A6</=
div><div class=3D""><br class=3D""></div><div class=3D""></div><div class=
=3D""><a href=3D"https://groups.google.com/a/isocpp.org/d/topic/std-proposa=
ls/kwDmEOQL7oE/discussion" class=3D"">https://groups.google.com/a/isocpp.or=
g/d/topic/std-proposals/kwDmEOQL7oE/discussion</a></div><div class=3D""><a =
href=3D"https://groups.google.com/a/isocpp.org/d/topic/std-proposals/DnxRfo=
_uQl8/discussion" class=3D"">https://groups.google.com/a/isocpp.org/d/topic=
/std-proposals/DnxRfo_uQl8/discussion</a></div><div class=3D""><br class=3D=
""></div><div class=3D"">The obvious questions are:</div><div class=3D""><b=
r class=3D""></div><div class=3D"">1. How does the ABI handle it? Does the =
thunk wrap an indirect call (std::function-like) or is each thunk a distinc=
t type (lambda-like)? It sounds like you=E2=80=99ve left it to the ABI, wit=
h indirect thunks.</div><div class=3D"">2. How many times is the argument e=
valuated? Once (cache-like) or per use (conversion-like)?</div><div class=
=3D""><br class=3D""></div><br class=3D""><div><blockquote type=3D"cite" cl=
ass=3D""><div class=3D"">On 2014=E2=80=9312=E2=80=9320, at 11:18 PM, Dougla=
s Boffey &lt;<a href=3D"mailto:douglas.boffey@gmail.com" class=3D"">douglas=
..boffey@gmail.com</a>&gt; wrote:</div><br class=3D"Apple-interchange-newlin=
e"><div class=3D""><div dir=3D"ltr" class=3D"">if the function is inline, r=
eplacing the parameter with the AST creating the parameter, and if the func=
tion is out of line, passing a thunk to the function, which the function wo=
uld call.</div></div></blockquote></div></body></html>

<p></p>

-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--Apple-Mail=_11794F8F-EEA6-41B5-98D7-792A9E9E1326--

.


Author: masse.nicolas@gmail.com
Date: Sun, 21 Dec 2014 09:52:12 -0800 (PST)
Raw View
------=_Part_2247_1894660084.1419184332676
Content-Type: multipart/alternative;
 boundary="----=_Part_2248_664514072.1419184332676"

------=_Part_2248_664514072.1419184332676
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

A solution is to use std::function for that. For example

bool operator || (std::function<bool()> a, std::function<bool()> b)
{
    bool result =3D a();
    if(!result)
        return b();
    return true;
}



Le samedi 20 d=C3=A9cembre 2014 16:18:13 UTC+1, Douglas Boffey a =C3=A9crit=
 :
>
> Three inbuilt operators cannot be encapsulated in functions.  They are:
>
> bool operator||(bool, bool) const noexcept;
>
> bool operator&&(bool, bool) const noexcept;
>
> template <typename T>
> T operator?:(bool, T, T) const noexcept; // I know this isn=E2=80=99t leg=
al, but=20
> I=E2=80=99m sure you get my meaning ;)
>
>
>
> the problem being that some arguments need not be evaluated.
>
> There could be other functions that need to be written (for example,=20
> selection on an enum).
>
> Currently, the only way to simulate this is with macro functions, which i=
s=20
> fraught with problems.
>
> My suggestion is that, should a formal parameter be preceded by =E2=80=98=
inline=E2=80=99,=20
> the program only evaluates the parameter when used.
>
> This would allow the above operators to be written thus:
>
> bool operator||(bool a, inline bool b) const /* cannot say noexcept, as=
=20
> an exception might be thrown in evaluating b, see below */ {
>   if (a)
>     return true;
>   return b; // b only gets evaluated here!
> }
>
>
>
> And similarly for operator && and the (non-legal) operator?:.
>
> Because evaluating an inline parameter might throw an exception, the=20
> parameter should be followed by an exception specification.  (I=E2=80=99m=
 not sure=20
> about this one=E2=80=A6 it seems wrong that the callee should impose rest=
rictions=20
> on the caller).
>
> This could be easily implemented, by:
>
> if the function is inline, replacing the parameter with the AST creating=
=20
> the parameter, and if the function is out of line, passing a thunk to the=
=20
> function, which the function would call.
>

--=20

---=20
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 e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

------=_Part_2248_664514072.1419184332676
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div>A solution is to use std::function for that<span styl=
e=3D"color: #000;" class=3D"styled-by-prettify">. For example<br><br></span=
><div style=3D"background-color: #FAFAFA; border-color: #BBB; border-style:=
 solid; border-width: 1px; word-wrap: break-word;" class=3D"prettyprint"><c=
ode class=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"colo=
r: #008;" class=3D"styled-by-prettify">bool</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">operator</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">||</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">(<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify">std</span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">::</span><span sty=
le=3D"color: #008;" class=3D"styled-by-prettify">function</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><span style=3D"co=
lor: #008;" class=3D"styled-by-prettify">bool</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">()&gt;</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"> a</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> std</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">::</span><span style=3D"color: #008;" class=3D"styled-by-prettify"=
>function</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&=
lt;</span><span style=3D"color: #008;" class=3D"styled-by-prettify">bool</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">()&gt;</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"> b</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">)</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">{</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"><br>&nbsp; &nbsp; </span><span style=3D"color: #0=
08;" class=3D"styled-by-prettify">bool</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"> result </span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"> a</span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">();</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"><br>&nbsp; &nbsp; </span><span style=3D"color: #008;" class=3D"styled-b=
y-prettify">if</span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">(!</span><span style=3D"color: #000;" class=3D"styled-by-prettify">resu=
lt</span><span style=3D"color: #660;" class=3D"styled-by-prettify">)</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"><br>&nbsp; &nbsp;=
 &nbsp; &nbsp; </span><span style=3D"color: #008;" class=3D"styled-by-prett=
ify">return</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
> b</span><span style=3D"color: #660;" class=3D"styled-by-prettify">();</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>&nbsp; &nb=
sp; </span><span style=3D"color: #008;" class=3D"styled-by-prettify">return=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><s=
pan style=3D"color: #008;" class=3D"styled-by-prettify">true</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">;</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">}</span></div></code></div><span style=
=3D"color: #660;" class=3D"styled-by-prettify"><br></span></div><div><br></=
div><br>Le samedi 20 d=C3=A9cembre 2014 16:18:13 UTC+1, Douglas Boffey a =
=C3=A9crit&nbsp;:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margi=
n-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"l=
tr">Three inbuilt operators cannot be encapsulated in functions.&nbsp; They=
 are:<br><br><div style=3D"background-color:rgb(250,250,250);border-color:r=
gb(187,187,187);border-style:solid;border-width:1px;word-wrap:break-word"><=
code><div><span style=3D"color:#008">bool</span><span style=3D"color:#000">=
 </span><span style=3D"color:#008">operator</span><span style=3D"color:#660=
">||(</span><span style=3D"color:#008">bool</span><span style=3D"color:#660=
">,</span><span style=3D"color:#000"> </span><span style=3D"color:#008">boo=
l</span><span style=3D"color:#660">)</span><span style=3D"color:#000"> </sp=
an><span style=3D"color:#008">const</span><span style=3D"color:#000"> noexc=
ept</span><span style=3D"color:#660">;</span><span style=3D"color:#000"><br=
><br></span><span style=3D"color:#008">bool</span><span style=3D"color:#000=
"> </span><span style=3D"color:#008">operator</span><span style=3D"color:#6=
60">&amp;&amp;(</span><span style=3D"color:#008">bool</span><span style=3D"=
color:#660">,</span><span style=3D"color:#000"> </span><span style=3D"color=
:#008">bool</span><span style=3D"color:#660">)</span><span style=3D"color:#=
000"> </span><span style=3D"color:#008">const</span><span style=3D"color:#0=
00"> noexcept</span><span style=3D"color:#660">;</span><span style=3D"color=
:#000"><br><br></span><span style=3D"color:#008">template</span><span style=
=3D"color:#000"> </span><span style=3D"color:#660">&lt;</span><span style=
=3D"color:#008">typename</span><span style=3D"color:#000"> T</span><span st=
yle=3D"color:#660">&gt;</span><span style=3D"color:#000"><br>T </span><span=
 style=3D"color:#008">operator</span><span style=3D"color:#660">?:(</span><=
span style=3D"color:#008">bool</span><span style=3D"color:#660">,</span><sp=
an style=3D"color:#000"> T</span><span style=3D"color:#660">,</span><span s=
tyle=3D"color:#000"> T</span><span style=3D"color:#660">)</span><span style=
=3D"color:#000"> </span><span style=3D"color:#008">const</span><span style=
=3D"color:#000"> noexcept</span><span style=3D"color:#660">;</span><span st=
yle=3D"color:#000"> </span><span style=3D"color:#800">// I know this isn=E2=
=80=99t legal, but I=E2=80=99m sure you get my meaning ;)</span><span style=
=3D"color:#000"><br><br></span></div></code></div><br><br>the problem being=
 that some arguments need not be evaluated.<br><br>There could be other fun=
ctions that need to be written (for example, selection on an enum).<br><br>=
Currently, the only way to simulate this is with macro functions, which is =
fraught with problems.<br><br>My suggestion is that, should a formal parame=
ter be preceded by =E2=80=98inline=E2=80=99, the program only evaluates the=
 parameter when used.<br><br>This would allow the above operators to be wri=
tten thus:<br><br><div style=3D"background-color:rgb(250,250,250);border-co=
lor:rgb(187,187,187);border-style:solid;border-width:1px;word-wrap:break-wo=
rd"><code><div><span style=3D"color:#008">bool</span><span style=3D"color:#=
000"> </span><span style=3D"color:#008">operator</span><span style=3D"color=
:#660">||(</span><span style=3D"color:#008">bool</span><span style=3D"color=
:#000"> a</span><span style=3D"color:#660">,</span><span style=3D"color:#00=
0"> </span><span style=3D"color:#008">inline</span><span style=3D"color:#00=
0"> </span><span style=3D"color:#008">bool</span><span style=3D"color:#000"=
> b</span><span style=3D"color:#660">)</span><span style=3D"color:#000"> </=
span><span style=3D"color:#008">const</span><span style=3D"color:#000"> </s=
pan><span style=3D"color:#800">/* cannot say noexcept, as an exception migh=
t be thrown in evaluating b, see below */</span><span style=3D"color:#000">=
 </span><span style=3D"color:#660">{</span><span style=3D"color:#000"><br>&=
nbsp; </span><span style=3D"color:#008">if</span><span style=3D"color:#000"=
> </span><span style=3D"color:#660">(</span><span style=3D"color:#000">a</s=
pan><span style=3D"color:#660">)</span><span style=3D"color:#000"><br>&nbsp=
; &nbsp; </span><span style=3D"color:#008">return</span><span style=3D"colo=
r:#000"> </span><span style=3D"color:#008">true</span><span style=3D"color:=
#660">;</span><span style=3D"color:#000"><br>&nbsp; </span><span style=3D"c=
olor:#008">return</span><span style=3D"color:#000"> b</span><span style=3D"=
color:#660">;</span><span style=3D"color:#000"> </span><span style=3D"color=
:#800">// b only gets evaluated here!</span><span style=3D"color:#000"><br>=
</span><span style=3D"color:#660">}</span><span style=3D"color:#000"><br><b=
r></span></div></code></div><br><br>And similarly for operator &amp;&amp; a=
nd the (non-legal) operator?:.<br><br>Because evaluating an inline paramete=
r might throw an exception, the parameter should be followed by an exceptio=
n specification.&nbsp; (I=E2=80=99m not sure about this one=E2=80=A6 it see=
ms wrong that the callee should impose restrictions on the caller).<br><br>=
This could be easily implemented, by:<br><br>if the function is inline, rep=
lacing the parameter with the AST creating the parameter, and if the functi=
on is out of line, passing a thunk to the function, which the function woul=
d call.<br></div></blockquote></div>

<p></p>

-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_2248_664514072.1419184332676--
------=_Part_2247_1894660084.1419184332676--

.


Author: Douglas Boffey <douglas.boffey@gmail.com>
Date: Mon, 22 Dec 2014 02:57:52 -0800 (PST)
Raw View
------=_Part_777_1913667212.1419245872252
Content-Type: multipart/alternative;
 boundary="----=_Part_778_142250965.1419245872252"

------=_Part_778_142250965.1419245872252
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

On Sunday, 21 December 2014 03:05:38 UTC, David Krauss wrote:=20

>  It=E2=80=99s helpful to mention previous discussion when it exists=E2=80=
=A6
>  =20
> =20
> https://groups.google.com/a/isocpp.org/d/topic/std-proposals/kwDmEOQL7oE/=
discussion
>
> https://groups.google.com/a/isocpp.org/d/topic/std-proposals/DnxRfo_uQl8/=
discussion
>  =20
>
Thanks for those links.
=20

>  The obvious questions are:
>  =20
> 1. How does the ABI handle it? Does the thunk wrap an indirect call=20
> (std::function-like) or is each thunk a distinct type (lambda-like)? It=
=20
> sounds like you=E2=80=99ve left it to the ABI, with indirect thunks.
>
=20
I would imagine that the thunk was an indirect call, as I cannot see what=
=20
else one would reasonably want to do with it.
=20

>  2. How many times is the argument evaluated? Once (cache-like) or per=20
> use (conversion-like)?
>  =20
>
Good question.  The original suggestion implied once per use, but on=20
reflection, once only (cache-like) would be preferable.
=20

   - Efficiency=20
      - having to construct, or assign an object for every use could be=20
      expensive=20
      - it would inhibit some optimisation (e.g. moving out of loop)
   - Effect=20
      - there could be problems if the parameter was an rvalue reference=20
      - given the following code,
  =20
=20
=20
=20
void fn(inline int a) {/* =E2=80=A6 */}

// =E2=80=A6

int a {/* =E2=80=A6 */};
fn(++a);
=20

=20

 it could give rather surprising results for a.


   - documentation: it is a lot easier to document the conditions under=20
   which the parameter is evaluated, rather than the number of evaluations.

 =20

>  =20
> =20
> On 2014=E2=80=9312=E2=80=9320, at 11:18 PM, Douglas Boffey <douglas...@gm=
ail.com=20
> <javascript:>> wrote:
> =20
>  if the function is inline, replacing the parameter with the AST creating=
=20
> the parameter, and if the function is out of line, passing a thunk to the=
=20
> function, which the function would call.
>
> =20
*Further points:*
The parameter is expanded even if a reference, or a pointer to it, is=20
taken, in which case the reference, resp. the pointer, refers to the cached=
=20
value, not the thunk.
=20
The callee shoud be responsible for invoking any destructor on exit, as it=
=20
is better able to determine whether the thunk was invoked, and may be able=
=20
to optimise out an optional destruction invocation for some code paths, or=
=20
cal the destructor without checking whether a value has been cached=20
for others. (although this is an implementation detail)
=20
Should an inline parameter be passed as a inline parameter to a further=20
function, the thunk should not automatically be invoked.
=20
The following functions (and maybe others, these are the ones that=20
immediately spring to mind) must not cause the thunk to be invoked:
=20

decltype
sizeof
alignas
typeid

=20
Have a joyful Christmas time :D

--=20

---=20
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 e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

------=_Part_778_142250965.1419245872252
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><DIV>On Sunday, 21 December 2014 03:05:38 UTC, David Kraus=
s wrote: </DIV>
<BLOCKQUOTE style=3D"BORDER-LEFT: #ccc 1px solid; MARGIN: 0px 0px 0px 0.8ex=
; PADDING-LEFT: 1ex" class=3Dgmail_quote>
<DIV style=3D"WORD-WRAP: break-word">
<DIV>It=E2=80=99s helpful to mention previous discussion when it exists=E2=
=80=A6</DIV>
<DIV>
<DIV>&nbsp;</DIV></DIV>
<DIV></DIV>
<DIV><A onmousedown=3D"this.href=3D'https://groups.google.com/a/isocpp.org/=
d/topic/std-proposals/kwDmEOQL7oE/discussion';return true;" onclick=3D"this=
..href=3D'https://groups.google.com/a/isocpp.org/d/topic/std-proposals/kwDmE=
OQL7oE/discussion';return true;" href=3D"https://groups.google.com/a/isocpp=
..org/d/topic/std-proposals/kwDmEOQL7oE/discussion" target=3D_blank>https://=
groups.google.com/a/<WBR>isocpp.org/d/topic/std-<WBR>proposals/kwDmEOQL7oE/=
<WBR>discussion</A></DIV>
<DIV><A onmousedown=3D"this.href=3D'https://groups.google.com/a/isocpp.org/=
d/topic/std-proposals/DnxRfo_uQl8/discussion';return true;" onclick=3D"this=
..href=3D'https://groups.google.com/a/isocpp.org/d/topic/std-proposals/DnxRf=
o_uQl8/discussion';return true;" href=3D"https://groups.google.com/a/isocpp=
..org/d/topic/std-proposals/DnxRfo_uQl8/discussion" target=3D_blank>https://=
groups.google.com/a/<WBR>isocpp.org/d/topic/std-<WBR>proposals/DnxRfo_uQl8/=
<WBR>discussion</A></DIV>
<DIV>
<DIV>&nbsp;</DIV></DIV></DIV></BLOCKQUOTE>
<DIV>Thanks for those links.</DIV>
<DIV>&nbsp;</DIV>
<BLOCKQUOTE style=3D"BORDER-LEFT: #ccc 1px solid; MARGIN: 0px 0px 0px 0.8ex=
; PADDING-LEFT: 1ex" class=3Dgmail_quote>
<DIV style=3D"WORD-WRAP: break-word">
<DIV>The obvious questions are:</DIV>
<DIV>
<DIV>&nbsp;</DIV></DIV>
<DIV>1. How does the ABI handle it? Does the thunk wrap an indirect call (s=
td::function-like) or is each thunk a distinct type (lambda-like)? It sound=
s like you=E2=80=99ve left it to the ABI, with indirect thunks.</DIV></DIV>=
</BLOCKQUOTE>
<DIV>&nbsp;</DIV>
<DIV>I would imagine that the thunk was an indirect call, as I cannot see w=
hat else one would reasonably want to do with it.</DIV>
<DIV>&nbsp;</DIV>
<BLOCKQUOTE style=3D"BORDER-LEFT: #ccc 1px solid; MARGIN: 0px 0px 0px 0.8ex=
; PADDING-LEFT: 1ex" class=3Dgmail_quote>
<DIV style=3D"WORD-WRAP: break-word">
<DIV>2. How many times is the argument evaluated? Once (cache-like) or per =
use (conversion-like)?</DIV>
<DIV>
<DIV>&nbsp;</DIV></DIV></DIV></BLOCKQUOTE>
<DIV>Good question.&nbsp; The original suggestion implied once per use, but=
 on reflection, once only (cache-like) would be preferable.</DIV>
<DIV>&nbsp;</DIV>
<UL>
<LI>Efficiency</LI>
<UL>
<LI>having to construct, or assign an object for every use could be expensi=
ve</LI>
<LI>it would inhibit some optimisation (e.g. moving out of loop)</LI></UL>
<LI>Effect</LI>
<UL>
<LI>there could be problems if the parameter was an rvalue reference</LI>
<LI>given the following code,</LI></UL></UL>
<BLOCKQUOTE style=3D"MARGIN-RIGHT: 0px" dir=3Dltr>
<BLOCKQUOTE style=3D"MARGIN-RIGHT: 0px" dir=3Dltr>
<P><BR>&nbsp;</P><CODE class=3Dprettyprint>
<DIV style=3D"BORDER-BOTTOM: #bbb 1px solid; BORDER-LEFT: #bbb 1px solid; B=
ACKGROUND-COLOR: #fafafa; WORD-WRAP: break-word; BORDER-TOP: #bbb 1px solid=
; BORDER-RIGHT: #bbb 1px solid" class=3Dsubprettyprint>&nbsp;</DIV>
<DIV style=3D"BORDER-BOTTOM: #bbb 1px solid; BORDER-LEFT: #bbb 1px solid; B=
ACKGROUND-COLOR: #fafafa; WORD-WRAP: break-word; BORDER-TOP: #bbb 1px solid=
; BORDER-RIGHT: #bbb 1px solid" class=3Dprettyprint><FONT color=3D#660066>v=
oid fn(inline int a) {/* =E2=80=A6 */}<BR><BR>// =E2=80=A6<BR><BR>int a {/*=
 =E2=80=A6 */};<BR>fn(++a);</FONT></DIV>
<DIV style=3D"BORDER-BOTTOM: #bbb 1px solid; BORDER-LEFT: #bbb 1px solid; B=
ACKGROUND-COLOR: #fafafa; WORD-WRAP: break-word; BORDER-TOP: #bbb 1px solid=
; BORDER-RIGHT: #bbb 1px solid" class=3Dprettyprint><FONT color=3D#660066>&=
nbsp;</DIV></FONT></CODE>
<P>&nbsp;</P>
<P>&nbsp;it could give rather surprising results for a.</P></BLOCKQUOTE></B=
LOCKQUOTE>
<UL>
<LI>documentation: it is a lot easier to document the conditions under whic=
h the parameter is evaluated, rather than the number of evaluations.</LI></=
UL>
<DIV>&nbsp;<FONT color=3D#660066>&nbsp;</FONT></DIV>
<BLOCKQUOTE style=3D"BORDER-LEFT: #ccc 1px solid; MARGIN: 0px 0px 0px 0.8ex=
; PADDING-LEFT: 1ex" class=3Dgmail_quote>
<DIV style=3D"WORD-WRAP: break-word">
<DIV>&nbsp;</DIV>
<DIV>
<BLOCKQUOTE type=3D"cite">
<DIV>On 2014=E2=80=9312=E2=80=9320, at 11:18 PM, Douglas Boffey &lt;<A onmo=
usedown=3D"this.href=3D'javascript:';return true;" onclick=3D"this.href=3D'=
javascript:';return true;" href=3D"javascript:" target=3D_blank gdf-obfusca=
ted-mailto=3D"DXBmcl8W8noJ">douglas...@gmail.com</A>&gt; wrote:</DIV>
<DIV>&nbsp;</DIV>
<DIV>
<DIV dir=3Dltr>if the function is inline, replacing the parameter with the =
AST creating the parameter, and if the function is out of line, passing a t=
hunk to the function, which the function would call.</DIV></DIV></BLOCKQUOT=
E></DIV></DIV></BLOCKQUOTE>
<DIV>&nbsp;</DIV>
<DIV><STRONG>Further points:</STRONG></DIV>
<DIV>The parameter is expanded even if a reference, or a pointer to it, is =
taken, in which case the reference, resp. the pointer, refers to the cached=
 value, not the thunk.</DIV>
<DIV>&nbsp;</DIV>
<DIV>The callee shoud be responsible for invoking any destructor on exit, a=
s it is better able to determine whether the thunk was invoked, and may be =
able to optimise out&nbsp;an optional destruction&nbsp;invocation for&nbsp;=
some code paths, or cal the destructor without checking whether a value has=
 been cached for&nbsp;others.&nbsp;(although this is an implementation deta=
il)</DIV>
<DIV>&nbsp;</DIV>
<DIV>Should an inline parameter be passed as a inline parameter to a furthe=
r function, the thunk should not automatically be invoked.</DIV>
<DIV>&nbsp;</DIV>
<DIV>The following functions (and maybe others, these are the ones that imm=
ediately spring to mind)&nbsp;must not cause the thunk to be invoked:</DIV>
<DIV>&nbsp;</DIV>
<BLOCKQUOTE style=3D"MARGIN-RIGHT: 0px" dir=3Dltr>
<DIV>decltype</DIV>
<DIV>sizeof</DIV>
<DIV>alignas</DIV>
<DIV>typeid</DIV></BLOCKQUOTE>
<DIV>&nbsp;</DIV>
<DIV>Have a joyful Christmas time :D</DIV></div>

<p></p>

-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_778_142250965.1419245872252--
------=_Part_777_1913667212.1419245872252--

.


Author: Matthew Woehlke <mw_triad@users.sourceforge.net>
Date: Mon, 22 Dec 2014 12:40:22 -0500
Raw View
On 2014-12-22 05:57, Douglas Boffey wrote:
> On Sunday, 21 December 2014 03:05:38 UTC, David Krauss wrote:
>>  2. How many times is the argument evaluated? Once (cache-like) or per
>> use (conversion-like)?
>
> Good question.  The original suggestion implied once per use, but on
> reflection, once only (cache-like) would be preferable.
> [...]
> The callee shoud be responsible for invoking any destructor on exit, as it
> is better able to determine whether the thunk was invoked, and may be able
> to optimise out an optional destruction invocation for some code paths, or
> cal the destructor without checking whether a value has been cached
> for others. (although this is an implementation detail)

If one conceptualizes the implementation as internally creating a
std::optional<T> (with 'T' being the type of the inline parameter) which
is initially disengaged, and that every access of the parameter in fact
checks if the optional is engaged and, if not, evaluates the inline
parameter and stores the result in the optional, before ultimately
returning what is in the optional instead, I think these sorts of things
sort themselves out nicely.

Naturally, compilers should be free to implement this "as if" for the
sake of optimization... Although if everything is properly inlined, that
may already happen with existing optimization techniques, which would
certainly be convenient for the compiler.

> Should an inline parameter be passed as a inline parameter to a further
> function, the thunk should not automatically be invoked.

The above would make this implicit :-). (Even better, it would do what I
think you want it to do anyway; pass the known value if the thunk has
already been invoked, otherwise pass a *new* thunk which would cause the
parent context to "inherit" the result of executing the thunk.)

This suggests a related point; is it useful for the compiler to
automatically generate overloads that do *not* have inline parameters?
It seems that this would be useful for performance if e.g. a POD value
is passed as an inline parameter; in such case there is no point to any
delayed evaluation techniques.

Example:

  void foo(inline int);

  int a = bar();
  int* b = none();

  foo(5); // calls non-inline version
  foo(a); // calls non-inline version
  foo(++a); // calls inline version with thunk { return ++a; }
  foo(*b); // calls inline version with thunk { return *b; }

More generally, I'm thinking this should perhaps be implementation
defined. Anything that can be passed in registers probably can be passed
non-inline. The standard could require only that if the compiler chooses
a non-inline version, no side effects of evaluating the expression will
be observable if the called function does not in fact use the parameter.

--
Matthew

--

---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

.


Author: Douglas Boffey <douglas.boffey@gmail.com>
Date: Mon, 22 Dec 2014 19:15:51 +0000
Raw View
One thing I'm not sure about is whether parameter packs should ve
inlineable - I've never used them.

On 12/22/14, Matthew Woehlke <mw_triad@users.sourceforge.net> wrote:
> On 2014-12-22 05:57, Douglas Boffey wrote:
>> On Sunday, 21 December 2014 03:05:38 UTC, David Krauss wrote:
>>>  2. How many times is the argument evaluated? Once (cache-like) or per
>>> use (conversion-like)?
>>
>> Good question.  The original suggestion implied once per use, but on
>> reflection, once only (cache-like) would be preferable.
>> [...]
>> The callee shoud be responsible for invoking any destructor on exit, as it
>>
>> is better able to determine whether the thunk was invoked, and may be able
>>
>> to optimise out an optional destruction invocation for some code paths, or
>>
>> cal the destructor without checking whether a value has been cached
>> for others. (although this is an implementation detail)
>
> If one conceptualizes the implementation as internally creating a
> std::optional<T> (with 'T' being the type of the inline parameter) which
> is initially disengaged, and that every access of the parameter in fact
> checks if the optional is engaged and, if not, evaluates the inline
> parameter and stores the result in the optional, before ultimately
> returning what is in the optional instead, I think these sorts of things
> sort themselves out nicely.
>
> Naturally, compilers should be free to implement this "as if" for the
> sake of optimization... Although if everything is properly inlined, that
> may already happen with existing optimization techniques, which would
> certainly be convenient for the compiler.
>
>> Should an inline parameter be passed as a inline parameter to a further
>> function, the thunk should not automatically be invoked.
>
> The above would make this implicit :-). (Even better, it would do what I
> think you want it to do anyway; pass the known value if the thunk has
> already been invoked, otherwise pass a *new* thunk which would cause the
> parent context to "inherit" the result of executing the thunk.)
>
> This suggests a related point; is it useful for the compiler to
> automatically generate overloads that do *not* have inline parameters?
> It seems that this would be useful for performance if e.g. a POD value
> is passed as an inline parameter; in such case there is no point to any
> delayed evaluation techniques.
>
> Example:
>
>   void foo(inline int);
>
>   int a = bar();
>   int* b = none();
>
>   foo(5); // calls non-inline version
>   foo(a); // calls non-inline version
>   foo(++a); // calls inline version with thunk { return ++a; }
>   foo(*b); // calls inline version with thunk { return *b; }
>
> More generally, I'm thinking this should perhaps be implementation
> defined. Anything that can be passed in registers probably can be passed
> non-inline. The standard could require only that if the compiler chooses
> a non-inline version, no side effects of evaluating the expression will
> be observable if the called function does not in fact use the parameter.
>
> --
> Matthew
>
> --
>
> ---
> 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.
> Visit this group at
> http://groups.google.com/a/isocpp.org/group/std-proposals/.
>

--

---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

.


Author: Nicola Gigante <nicola.gigante@gmail.com>
Date: Tue, 23 Dec 2014 12:10:35 +0100
Raw View
--Apple-Mail=_09946B89-B983-49EF-B278-CBCD60B122E1
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=UTF-8


Il giorno 21/dic/2014, alle ore 04:05, David Krauss <potswa@gmail.com> ha s=
critto:

> It=E2=80=99s helpful to mention previous discussion when it exists=E2=80=
=A6
>=20
> https://groups.google.com/a/isocpp.org/d/topic/std-proposals/kwDmEOQL7oE/=
discussion
> https://groups.google.com/a/isocpp.org/d/topic/std-proposals/DnxRfo_uQl8/=
discussion
>=20
> The obvious questions are:
>=20
> 1. How does the ABI handle it? Does the thunk wrap an indirect call (std:=
:function-like) or is each thunk a distinct type (lambda-like)? It sounds l=
ike you=E2=80=99ve left it to the ABI, with indirect thunks.
> 2. How many times is the argument evaluated? Once (cache-like) or per use=
 (conversion-like)?
>=20

I=E2=80=99m happy you cited the first link.=20

After three different people tried to start a discussion about it,
I think there is actual interest in providing a way to encode lazy function=
 arguments in
the language.=20

As for the specific questions:
1) I think the only choice that make sense here is to wrap an indirect call=
..
Note that this can be stated in terms of enclosing the argument expression
into a lambda that captures the outer scope by reference, and wrapped=20
into an std::function. Whoever, the compiler can do much much better than
this in terms of performance, especially in calls that do not cross the ABI
boundary of an executable.

2) I think side effects have to be executed once, and the result cached.
Of course, side effects would be discouraged in arguments of those
kinds of functions, also because the evaluation of performance reason:
the compiler can chose whether to actually emit or not all the lazy machine=
ry
for a call that would not have side effects and whose performance benefit
in avoiding the evaluation of the argument would not be noticeable.

Since a lot of people expressed the doubt that such mechanism could cause
code with unexpected results, I=E2=80=99d like to point out a possible solu=
tion:
require the =E2=80=98inline=E2=80=99 (or =E2=80=98lazy=E2=80=99, or whateve=
r) keyword at the _call_ site, too,
except when calling an overloaded operator|| or operator&&, which already
are expected to not evaluate the arguments sometimes, for basic types at le=
ast.

Bye,
Nicola



--=20

---=20
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 e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

--Apple-Mail=_09946B89-B983-49EF-B278-CBCD60B122E1
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=UTF-8

<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html charset=
=3Dwindows-1252"></head><body style=3D"word-wrap: break-word; -webkit-nbsp-=
mode: space; -webkit-line-break: after-white-space;"><br><div><div>Il giorn=
o 21/dic/2014, alle ore 04:05, David Krauss &lt;<a href=3D"mailto:potswa@gm=
ail.com">potswa@gmail.com</a>&gt; ha scritto:</div><br class=3D"Apple-inter=
change-newline"><blockquote type=3D"cite"><meta http-equiv=3D"Content-Type"=
 content=3D"text/html charset=3Dutf-8"><div style=3D"word-wrap: break-word;=
 -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=3D=
""><div class=3D"">It=E2=80=99s helpful to mention previous discussion when=
 it exists=E2=80=A6</div><div class=3D""><br class=3D""></div><div class=3D=
""></div><div class=3D""><a href=3D"https://groups.google.com/a/isocpp.org/=
d/topic/std-proposals/kwDmEOQL7oE/discussion" class=3D"">https://groups.goo=
gle.com/a/isocpp.org/d/topic/std-proposals/kwDmEOQL7oE/discussion</a></div>=
<div class=3D""><a href=3D"https://groups.google.com/a/isocpp.org/d/topic/s=
td-proposals/DnxRfo_uQl8/discussion" class=3D"">https://groups.google.com/a=
/isocpp.org/d/topic/std-proposals/DnxRfo_uQl8/discussion</a></div><div clas=
s=3D""><br class=3D""></div><div class=3D"">The obvious questions are:</div=
><div class=3D""><br class=3D""></div><div class=3D"">1. How does the ABI h=
andle it? Does the thunk wrap an indirect call (std::function-like) or is e=
ach thunk a distinct type (lambda-like)? It sounds like you=E2=80=99ve left=
 it to the ABI, with indirect thunks.</div><div class=3D"">2. How many time=
s is the argument evaluated? Once (cache-like) or per use (conversion-like)=
?</div><div class=3D""><br class=3D""></div></div></blockquote></div><br><d=
iv>I=E2=80=99m happy you cited the first link.&nbsp;</div><div><br></div><d=
iv>After three different people tried to start a discussion about it,</div>=
<div>I think there is actual interest in providing a way to encode lazy fun=
ction arguments in</div><div>the language.&nbsp;</div><div><br></div><div>A=
s for the specific questions:</div><div>1) I think the only choice that mak=
e sense here is to wrap an indirect call.</div><div>Note that this can be s=
tated in terms of enclosing the argument expression</div><div>into a lambda=
 that captures the outer scope by reference, and wrapped&nbsp;</div><div>in=
to an std::function. Whoever, the compiler can do much much better than</di=
v><div>this in terms of performance, especially in calls that do not cross =
the ABI</div><div>boundary of an executable.</div><div><br></div><div>2) I =
think side effects have to be executed once, and the result cached.</div><d=
iv>Of course, side effects would be discouraged in arguments of those</div>=
<div>kinds of functions, also because the evaluation of performance reason:=
</div><div>the compiler can chose whether to actually emit or not all the l=
azy machinery</div><div>for a call that would not have side effects and who=
se performance benefit</div><div>in avoiding the evaluation of the argument=
 would not be noticeable.</div><div><br></div><div>Since a lot of people ex=
pressed the doubt that such mechanism could cause</div><div>code with unexp=
ected results, I=E2=80=99d like to point out a possible solution:</div><div=
>require the =E2=80=98inline=E2=80=99 (or =E2=80=98lazy=E2=80=99, or whatev=
er) keyword at the _call_ site, too,</div><div>except when calling an overl=
oaded operator|| or operator&amp;&amp;, which already</div><div>are expecte=
d to not evaluate the arguments sometimes, for basic types at least.</div><=
div><br></div><div>Bye,</div><div>Nicola</div><div><br></div><div><br></div=
><div><br></div></body></html>

<p></p>

-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--Apple-Mail=_09946B89-B983-49EF-B278-CBCD60B122E1--

.


Author: Matthew Woehlke <mw_triad@users.sourceforge.net>
Date: Tue, 23 Dec 2014 13:53:01 -0500
Raw View
On 2014-12-23 06:10, Nicola Gigante wrote:
> 1) I think the only choice that make sense here is to wrap an indirect ca=
ll.
> Note that this can be stated in terms of enclosing the argument expressio=
n
> into a lambda that captures the outer scope by reference, and wrapped=20
> into an std::function. Whoever, the compiler can do much much better than
> this in terms of performance, especially in calls that do not cross the A=
BI
> boundary of an executable.

Again, I'm inclined to word this sort of thing "as if", and leave it to
the compiler vendors when/if they can implement it more efficiently.
Using e.g. std::function to explain how it would work makes tons of
sense. Forcing the implementation to *actually use* std::function... not
so much. Just specify the effects clearly and leave the rest to the
compiler.

> 2) I think side effects have to be executed once, and the result cached.

Pedantic: I assume you meant "*at most* once"? (If we don't allow them
to not be executed ever that rather defeats the purpose :-).)

> Of course, side effects would be discouraged in arguments of those
> kinds of functions

Actually, as I see it, lazy evaluation is most interesting when the
arguments *do* have side effects. (Pedantically, I'm including
dereferencing a potentially null pointer as a "side effect", the side
effect here being to raise a SIGSEGV. However I think there are other
uses with other side effects, e.g. incrementing a value, where lazy
evaluation is interesting for the sake of potentially not causing the
side effects. Using e.g. short circuit of the built-in Boolean operators
to selectively trigger side effects isn't that unusual...)

> the compiler can chose whether to actually emit or not all the lazy machi=
nery
> for a call that would not have side effects and whose performance benefit
> in avoiding the evaluation of the argument would not be noticeable.

As long as the specification *allows* the compiler to also emit
non-inline-parameter versions of a function taking an inline parameter,
I guess it doesn't matter whether or not we require that. Note however
that changing our minds on this later, whether at the compiler level or
the standard level, is likely going to cause ABI breakage. (As
previously stated, my own inclination is to allow it, as a performance
optimization.)

(On that note, we probably want to be clear up front if the inline /
lazy-eval specifier is allowed to overload. The easy answer of course is
"not". I'm not sure if there is value to allowing this... OTOH, see next
paragraph.)

> Since a lot of people expressed the doubt that such mechanism could cause
> code with unexpected results, I=E2=80=99d like to point out a possible so=
lution:
> require the =E2=80=98inline=E2=80=99 (or =E2=80=98lazy=E2=80=99, or whate=
ver) keyword at the _call_ site, too,
> except when calling an overloaded operator|| or operator&&, which already
> are expected to not evaluate the arguments sometimes, for basic types at =
least.

If we did that, then it makes sense to permit overloads based on
lazy-eval or not, since the call site makes explicit which one it wants
(again, except for || and && operators). I'm sort of ambivalent about
that, though; if we require extra syntax, there's not much gain over
explicitly passing a std::function, which we could do today.

(Less relevant; I feel like 'inline <expr>' would look really odd :-).)

--=20
Matthew

--=20

---=20
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 e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

.


Author: Douglas Boffey <douglas.boffey@gmail.com>
Date: Tue, 23 Dec 2014 13:48:24 -0800 (PST)
Raw View
------=_Part_4548_1612198534.1419371304538
Content-Type: multipart/alternative;
 boundary="----=_Part_4549_1419586739.1419371304538"

------=_Part_4549_1419586739.1419371304538
Content-Type: text/plain; charset=UTF-8


>
>
>

--

---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

------=_Part_4549_1419586739.1419371304538
Content-Type: text/html; charset=UTF-8

<blockquote class="gmail_quote" style="margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir="ltr"><br></div></blockquote>

<p></p>

-- <br />
<br />
--- <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 email to <a href="mailto:std-proposals+unsubscribe@isocpp.org">std-proposals+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href="mailto:std-proposals@isocpp.org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href="http://groups.google.com/a/isocpp.org/group/std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/</a>.<br />

------=_Part_4549_1419586739.1419371304538--
------=_Part_4548_1612198534.1419371304538
Content-Type: text/plain; charset=UTF-8; name="delayed evaluation parameters.txt"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
 filename="delayed evaluation parameters.txt"
X-Attachment-Id: 68e0b3b6-f029-4e66-a956-567b2f77b171
Content-ID: <68e0b3b6-f029-4e66-a956-567b2f77b171>

Document number: Dxxx=3Dxx-xxxx
Date: xxxx-xx-xx
Project: Programming language C++, Core Working Group
Reply-to: Douglas Boffey <douglas.boffey@gmail.com>

Table of Contents
-----------------
1. Introduction
2. Motivation and Scope
3. Impact on the Standard
4. Design Decisions
5. Technical Specifications
6. Future Enhancements
7. Acknowledgements
8. References

Introduction
------------
This proposal provides Delayed Expression Parameters (DEPs), which are para=
meters to a constructor, function or member function that are only evaluate=
d on first use.

Motivation and Scope
--------------------
Most of the time, function parameters are calculated prior to invocation of=
 a function, but there are occasions where that is not what is needed.

Some of the reasons are:

a) calculation of a parameter might invoke undefined behaviour in some circ=
umstances.  Take, for example, the idiom:

if (a && /* some expression involving *a */)

where a is a pointer to memory, or nullptr.

b) a parameter might be expensive to construct and then destruct.  If it is=
 only sometimes needed, it would make sense only to evaluate it in those ci=
rcumstances.

c) code might need to be included in some builds, e.g. debug builds, that s=
houldn=E2=80=99t be included in other builds, e.g. production builds.  For =
example, code that checks preconditions, postconditions and invariants.

d) it may be that only details of a variable type are required.  For exampl=
e, a user-implementation of sizeof for variables would look like:

template <typename T>
std::size_t my_sizeof(inline T t) {
  return sizeof(T);
}

Impact on the Standard
----------------------
This code introduces no breaking behaviour.

Design Decisions
----------------
There are a number of decisions:

a) Should the parameter be calculated once only (cache-like), or on every o=
ccurance (instance-like)?
This proposal is for a cache-like solution, because:
 * efficiency
  - an instance-like solution might require multiple constructions or assig=
nements
  - an instance-like solution might inhibit optimisations, e.g. moving code=
 out of loop
 * effect
  - multiple calculations might produce unexpected behaviour.  Take, for in=
stance,

void fn(inline int a) {/* =E2=80=A6 */}

// =E2=80=A6

int a{1};
fn(++a);

It could be difficult to predict what a would end up as.

b) When should the parameter be calculated?
A parameter needs to be calculated whenever the value is needed, a referenc=
e of it is taken, or a pointer is made to point to it.  The functions =E2=
=80=98sizeof=E2=80=99, =E2=80=98typeid=E2=80=99, =E2=80=98alignas=E2=80=99 =
and =E2=80=98decltype=E2=80=99 would not cause the DEP to be calculated, as=
 only the type of the DEP is required.  Any references or pointers to the p=
arameter should be to the cached value, not the code generating the value.

c) What about a DEP used within a DEP of a subsidary function?
The DEP should not automatically be calculated, but if it has not been calc=
ulated, the subsidiary function would be responsible for calculating it.

d) Should the DEP be a wrapper (like std::function) or a separate object (l=
ike a lambda)?
AS it would not make sense to refer to the code calculating the value, the =
code should be as if it were a wrapper around the parameter.

e) What nomenclature should be used?
Three options:
 1. a symbol: this would be inconsistent with existing practice, where symb=
ols are part of the type.

 2. introduce a new keyword, e.g. lazy: any new keyword is a potential for =
breaking code, and there is no obvious way, consistent with the current syn=
tax, of introducing a context-sensitive keyword.

 3. use an existing keyword: the keyword, =E2=80=98inline=E2=80=99 bests de=
scribes the effect of a DEP.  It is proposed that it should be put at the b=
eginning of a DEP declaration, to mirror inline variables.

f) What parameters would be allowed to be DEPs?
Initially, ths proposal allows DEPs for all parameters, except template var=
iadic parameters and parameter packs.

Technical Specifications
------------------------
TBD

Future Enhancements
-------------------
There are a number of extensions that could be addad:

- unless the parameter is calculated in a try block, it would be subject to=
 any exception restrictions of the callee, although the code is owned by th=
e caller.  It might be better to permit an exception specification with the=
 DEP.

- in this proposal, DEPs are not allowed for parameter packs.

- in this proposal, DEPs are not allowed for variadic template parameters.

Acknowledgements
----------------
My thanks go to sasho648, whose proposal inspired this proposal.  Also to D=
avid Krauss and Nicole Gigante for their insightful comments.

References
----------

--=20

---=20
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 e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

------=_Part_4548_1612198534.1419371304538--

.


Author: Matthew Woehlke <mw_triad@users.sourceforge.net>
Date: Tue, 23 Dec 2014 17:20:44 -0500
Raw View
On 2014-12-23 16:48, Douglas Boffey wrote:
> [paper]

FWIW, it might be interesting to mention logging as a potential
motivating use case. It's not uncommon to have something like:

  log(level) << expensive_expression;

Obviously if logging is not enabled, it is convenient to not evaluate
expensive_expression. Currently this is usually achieved by making
'log(...)' a macro that expands to something like 'if (enabled)
real_log'. With DEP's, the Log::operator<< could instead take inline
parameters. (Not sure this would actually be a good idea, but it's a
potential use case.)

--
Matthew

--

---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

.


Author: Matthew Woehlke <mw_triad@users.sourceforge.net>
Date: Tue, 23 Dec 2014 17:31:57 -0500
Raw View
On 2014-12-23 16:48, Douglas Boffey wrote:
> c) What about a DEP used within a DEP of a subsidary function?
> The DEP should not automatically be calculated, but if it has not
> been calculated, the subsidiary function would be responsible for
> calculating it.

Maybe this follows, but for clarity, I would also state that if the
subsidary function evaluates the DEP, that evaluation is visible in the
outer function.

For example:

  int bar(inline int a) { return a; }

  void foo(inline int b)
  {
    // b has not been evaluated yet
    bar(b);
    // foo sees that b has been evaluated and has access to the value
  }

> f) What parameters would be allowed to be DEPs?
> Initially, ths proposal allows DEPs for all parameters, except
> template variadic parameters and parameter packs.

Mentioned of course in Future Enhancements, but FWIW this feels like an
unnecessary restriction. Maybe we could simply refrain from either
requiring or forbidding this, and leave it to implementations if they
want to support it initially.

p.s. Thanks!

--
Matthew

--

---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

.


Author: masse.nicolas@gmail.com
Date: Tue, 23 Dec 2014 14:55:57 -0800 (PST)
Raw View
------=_Part_904_576573204.1419375357793
Content-Type: multipart/alternative;
 boundary="----=_Part_905_1019624364.1419375357793"

------=_Part_905_1019624364.1419375357793
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

Some remarks about the motivations :
- your example of the point a) is not relevant, since this code wont=20
evaluate the expression evaluating a. This  proposal doesn't seem to add=20
anything here.
- for the point d), you could write this :=20
template<typename T>
stuct my_sizeof
{
    static constexpr auto value =3D sizeof(T);
}

Also note that as far as I can see, a library based approach should be able=
=20
to solve both point b) and c).
This lead me to ask you this :=20
what are the advantage of integrating this in the core language instead of=
=20
having a library-based approach?



Le mardi 23 d=C3=A9cembre 2014 22:48:24 UTC+1, Douglas Boffey a =C3=A9crit =
:
>
>
>>

--=20

---=20
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 e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

------=_Part_905_1019624364.1419375357793
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Some remarks about the motivations :<br>- your example of =
the point a) is not relevant, since this code wont evaluate the expression =
evaluating a. This&nbsp; proposal doesn't seem to add anything here.<br>- f=
or the point d), you could write this : <br>template&lt;typename T&gt;<br>s=
tuct my_sizeof<br>{<br>&nbsp;&nbsp;&nbsp; static constexpr auto value =3D s=
izeof(T);<br>}<br><br>Also note that as far as I can see, a library based a=
pproach should be able to solve both point b) and c).<br>This lead me to as=
k you this : <br>what are the advantage of integrating this in the core lan=
guage instead of having a library-based approach?<br><br><br><br>Le mardi 2=
3 d=C3=A9cembre 2014 22:48:24 UTC+1, Douglas Boffey a =C3=A9crit&nbsp;:<blo=
ckquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-=
left: 1px #ccc solid;padding-left: 1ex;"><blockquote class=3D"gmail_quote" =
style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left=
:1ex"><div dir=3D"ltr"><br></div></blockquote></blockquote></div>

<p></p>

-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_905_1019624364.1419375357793--
------=_Part_904_576573204.1419375357793--

.


Author: Douglas Boffey <douglas.boffey@gmail.com>
Date: Tue, 23 Dec 2014 15:20:32 -0800 (PST)
Raw View
------=_Part_1023_430869348.1419376832494
Content-Type: multipart/alternative;
 boundary="----=_Part_1024_306274152.1419376832494"

------=_Part_1024_306274152.1419376832494
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable



On Tuesday, 23 December 2014 22:55:57 UTC, masse....@gmail.com wrote:
>
> Some remarks about the motivations :
> - your example of the point a) is not relevant, since this code wont=20
> evaluate the expression evaluating a. This  proposal doesn't seem to add=
=20
> anything here.
>
I disagree: the example is supposed to illustrate how it helps, given the=
=20
bit of the language where it is used.  Maybe I haven't made that explicit=
=20
enough?=20

> - for the point d), you could write this :=20
> template<typename T>
> stuct my_sizeof
> {
>     static constexpr auto value =3D sizeof(T);
> }
>
> Perhaps for that example, but with only a small increase in complexity,=
=20
your example wouldn't work.=20

> Also note that as far as I can see, a library based approach should be=20
> able to solve both point b) and c).
>
Please expand.=20

> This lead me to ask you this :=20
> what are the advantage of integrating this in the core language instead o=
f=20
> having a library-based approach?
>
>
>
> Le mardi 23 d=C3=A9cembre 2014 22:48:24 UTC+1, Douglas Boffey a =C3=A9cri=
t :
>>
>>
>>>

--=20

---=20
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 e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

------=_Part_1024_306274152.1419376832494
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Tuesday, 23 December 2014 22:55:57 UTC, masse..=
...@gmail.com  wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;ma=
rgin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=
=3D"ltr">Some remarks about the motivations :<br>- your example of the poin=
t a) is not relevant, since this code wont evaluate the expression evaluati=
ng a. This&nbsp; proposal doesn't seem to add anything here.<br></div></blo=
ckquote><div>I disagree: the example is supposed to illustrate how it helps=
, given the bit of the language where it is used. &nbsp;Maybe I haven't mad=
e that explicit enough?&nbsp;</div><blockquote class=3D"gmail_quote" style=
=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: =
1ex;"><div dir=3D"ltr">- for the point d), you could write this : <br>templ=
ate&lt;typename T&gt;<br>stuct my_sizeof<br>{<br>&nbsp;&nbsp;&nbsp; static =
constexpr auto value =3D sizeof(T);<br>}<br><br></div></blockquote><div>Per=
haps for that example, but with only a small increase in complexity, your e=
xample wouldn't work.&nbsp;</div><blockquote class=3D"gmail_quote" style=3D=
"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex=
;"><div dir=3D"ltr">Also note that as far as I can see, a library based app=
roach should be able to solve both point b) and c).<br></div></blockquote><=
div>Please expand.&nbsp;</div><blockquote class=3D"gmail_quote" style=3D"ma=
rgin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">=
<div dir=3D"ltr">This lead me to ask you this : <br>what are the advantage =
of integrating this in the core language instead of having a library-based =
approach?<br><br><br><br>Le mardi 23 d=C3=A9cembre 2014 22:48:24 UTC+1, Dou=
glas Boffey a =C3=A9crit&nbsp;:<blockquote class=3D"gmail_quote" style=3D"m=
argin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><blo=
ckquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-le=
ft:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><br></div></blockquote=
></blockquote></div></blockquote></div>

<p></p>

-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_1024_306274152.1419376832494--
------=_Part_1023_430869348.1419376832494--

.


Author: Matthew Woehlke <mw_triad@users.sourceforge.net>
Date: Tue, 23 Dec 2014 18:32:02 -0500
Raw View
On 2014-12-23 17:55, masse.nicolas@gmail.com wrote:
> Some remarks about the motivations :
> - your example of the point a) is not relevant, since this code wont
> evaluate the expression evaluating a. This  proposal doesn't seem to add
> anything here.

Eh? The example did not supply a definition of 'fn', the presumption
being that 'fn' may or may not evaluate its parameter (but that it
should evaluate the parameter at most once).

Note that this is roughly equivalent to:

  void fn(delayed<int> a) { /* ... */ }

  int a{1};
  fn([&]{ return ++a; });

(What's added by the proposal is the 'delayed<T>' magic and the syntatic
sugar to avoid having to explicitly write such a lambda.)

> Also note that as far as I can see, a library based approach should be able
> to solve both point b) and c).

True, but I just mentioned the benefit of a non-library approach :-).
(And in fact I talked about this earlier; if the caller is required to
go through additional gyrations to pass a DEP, then indeed a library
solution is possible. However, a) those gyrations can get rather
verbose, and b) a language approach may offer additional optimization
opportunities to the compiler.)

Thinking on it further, it may be useful to implement this (library or
otherwise) in a way that the DEP passed is actually (a reference to?)
the container for the cached parameter, e.g. something like an extended
std::optional with a std::function (which may be null!) to evaluate the
parameter. This would simplify passing constant values (just pass an
already-evaluated DEP with a null evaluation thunk, rather than needing
to overload) and forwarding of DEP's (since it's by reference, just pass
the caller's DEP).

If anything, some of the above considerations I think make a language
change even more interesting; let the compiler sort out when to pass a
thunk rather than making the user decide.

Another point related to "optimization opportunities"; std::function is
expensive. A language solution allows compiler vendors the freedom to do
whatever to make the thunk as lightweight as they can manage. For
example, maybe the thunk is just a pointer to the stack that contains a
pointer to code that knows where to access the necessary locals relative
to the same stack pointer. We can get away with tricks like this since
the thunk is non-copyable (at least, we know it won't outlive the
caller) that are not possible with something as generic as std::function.

--
Matthew

--

---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

.


Author: Matthew Woehlke <mw_triad@users.sourceforge.net>
Date: Tue, 23 Dec 2014 18:58:30 -0500
Raw View
On 2014-12-23 18:32, Matthew Woehlke wrote:
> Thinking on it further, it may be useful to implement this (library or
> otherwise) in a way that the DEP passed is actually (a reference to?)
> the container for the cached parameter, e.g. something like an extended
> std::optional with a std::function (which may be null!) to evaluate the
> parameter. This would simplify passing constant values (just pass an
> already-evaluated DEP with a null evaluation thunk, rather than needing
> to overload) and forwarding of DEP's (since it's by reference, just pass
> the caller's DEP).
>
> If anything, some of the above considerations I think make a language
> change even more interesting; let the compiler sort out when to pass a
> thunk rather than making the user decide.

I'll also note that I think that, as a language feature, these sorts of
questions (can? will?) fall into the implementation details domain,
which I consider a good thing.

We might want to explicitly mention that a conforming implementation can
execute a function taking a DEP with an already-evaluated value rather
than a thunk, provided that said evaluation has no observable side
effects (and without specifying how an implementation might do such a
thing). Note that the choice of "execute" (vs. "call") is intentional,
e.g. it would be permitted that an implementation generate multiple
versions of a function taking one or more DEP's and choose between them.

--
Matthew

--

---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

.


Author: Nicola Gigante <nicola.gigante@gmail.com>
Date: Wed, 24 Dec 2014 12:41:36 +0100
Raw View
Il giorno 23/dic/2014, alle ore 22:48, Douglas Boffey <douglas.boffey@gmail=
..com> ha scritto:

> [paper]

Apart from a typo in my name (s/Nicole/Nicola), it=E2=80=99s great to see s=
omething written finally!

A couple of points:
- Why restricting the use of variadics? I think anything you can do with on=
e parameter
can be done for a parameter pack. I don=E2=80=99t see the benefit of this r=
estriction, and it also
has some use cases like a logging function with a variadic interface instea=
d of a streaming
one.

- If we=E2=80=99re talking about overloading on lazy parameters, should =E2=
=80=98inline=E2=80=99 be a modifier like=20
const or volatile, from the grammar point of view? This should make it easy=
 to specify
the semantics of cases when you pass inline arguments to other inline param=
eters,=20
saying that the evaluation of the thunk must happen on a =E2=80=9Cinline to=
 non-inline=E2=80=9D conversion.


Bye,
Nicola


--=20

---=20
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 e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

.


Author: Douglas Boffey <douglas.boffey@gmail.com>
Date: Wed, 24 Dec 2014 04:50:51 -0800 (PST)
Raw View
------=_Part_957_1140121579.1419425451872
Content-Type: multipart/alternative;
 boundary="----=_Part_958_26796072.1419425451873"

------=_Part_958_26796072.1419425451873
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable



On Tuesday, 23 December 2014 23:58:51 UTC, Matthew Woehlke wrote:
>
> On 2014-12-23 18:32, Matthew Woehlke wrote:=20
> > Thinking on it further, it may be useful to implement this (library or=
=20
> > otherwise) in a way that the DEP passed is actually (a reference to?)=
=20
> > the container for the cached parameter, e.g. something like an extended=
=20
> > std::optional with a std::function (which may be null!) to evaluate the=
=20
> > parameter. This would simplify passing constant values (just pass an=20
> > already-evaluated DEP with a null evaluation thunk, rather than needing=
=20
> > to overload) and forwarding of DEP's (since it's by reference, just pas=
s=20
> > the caller's DEP).=20
> >=20
> > If anything, some of the above considerations I think make a language=
=20
> > change even more interesting; let the compiler sort out when to pass a=
=20
> > thunk rather than making the user decide.=20
>
> I'll also note that I think that, as a language feature, these sorts of=
=20
> questions (can? will?) fall into the implementation details domain,=20
> which I consider a good thing.=20
>
> We might want to explicitly mention that a conforming implementation can=
=20
> execute a function taking a DEP with an already-evaluated value rather=20
> than a thunk, provided that said evaluation has no observable side=20
> effects (and without specifying how an implementation might do such a=20
> thing). Note that the choice of "execute" (vs. "call") is intentional,=20
> e.g. it would be permitted that an implementation generate multiple=20
> versions of a function taking one or more DEP's and choose between them.=
=20
>
> Added=20

> --=20
> Matthew=20
>
>
On Wednesday, 24 December 2014 11:41 UTC, Nicola Gigante wrote:

l giorno 23/dic/2014, alle ore 22:48, Douglas Boffey <douglas...@gmail.com>=
=20
> ha scritto:=20
> > [paper]=20
> Apart from a typo in my name (s/Nicole/Nicola), it=E2=80=99s great to see=
=20
> something written finally!=20
>
My sincere apologies... corrected.
=20

> A couple of points:=20
> - Why restricting the use of variadics? I think anything you can do with=
=20
> one parameter=20
> can be done for a parameter pack. I don=E2=80=99t see the benefit of this=
=20
> restriction, and it also=20
> has some use cases like a logging function with a variadic interface=20
> instead of a streaming=20
> one.=20
>
Lifted=20

> - If we=E2=80=99re talking about overloading on lazy parameters, should =
=E2=80=98inline=E2=80=99=20
> be a modifier like=20
> const or volatile, from the grammar point of view? This should make it=20
> easy to specify=20
> the semantics of cases when you pass inline arguments to other inline=20
> parameters,=20
> saying that the evaluation of the thunk must happen on a =E2=80=9Cinline =
to=20
> non-inline=E2=80=9D conversion.=20
>
> I'm not sure about this one.

> Bye,=20
> Nicola=20

=20

--=20

---=20
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 e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

------=_Part_958_26796072.1419425451873
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Tuesday, 23 December 2014 23:58:51 UTC, Matthew=
 Woehlke  wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin=
-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On 2014-12-23 =
18:32, Matthew Woehlke wrote:
<br>&gt; Thinking on it further, it may be useful to implement this (librar=
y or
<br>&gt; otherwise) in a way that the DEP passed is actually (a reference t=
o?)
<br>&gt; the container for the cached parameter, e.g. something like an ext=
ended
<br>&gt; std::optional with a std::function (which may be null!) to evaluat=
e the
<br>&gt; parameter. This would simplify passing constant values (just pass =
an
<br>&gt; already-evaluated DEP with a null evaluation thunk, rather than ne=
eding
<br>&gt; to overload) and forwarding of DEP's (since it's by reference, jus=
t pass
<br>&gt; the caller's DEP).
<br>&gt;=20
<br>&gt; If anything, some of the above considerations I think make a langu=
age
<br>&gt; change even more interesting; let the compiler sort out when to pa=
ss a
<br>&gt; thunk rather than making the user decide.
<br>
<br>I'll also note that I think that, as a language feature, these sorts of
<br>questions (can? will?) fall into the implementation details domain,
<br>which I consider a good thing.
<br>
<br>We might want to explicitly mention that a conforming implementation ca=
n
<br>execute a function taking a DEP with an already-evaluated value rather
<br>than a thunk, provided that said evaluation has no observable side
<br>effects (and without specifying how an implementation might do such a
<br>thing). Note that the choice of "execute" (vs. "call") is intentional,
<br>e.g. it would be permitted that an implementation generate multiple
<br>versions of a function taking one or more DEP's and choose between them=
..
<br>
<br></blockquote><div>Added&nbsp;</div><blockquote class=3D"gmail_quote" st=
yle=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-lef=
t: 1ex;">--=20
<br>Matthew
<br>
<br></blockquote><div><br></div>On Wednesday, 24 December 2014 11:41 UTC, N=
icola Gigante wrote:<div><br></div><blockquote class=3D"gmail_quote" style=
=3D"margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-color: r=
gb(204, 204, 204); border-left-style: solid; padding-left: 1ex;">l giorno 2=
3/dic/2014, alle ore 22:48, Douglas Boffey &lt;<a target=3D"_blank" gdf-obf=
uscated-mailto=3D"XKrGIL1JLJYJ" style=3D"color: rgb(102, 17, 204); cursor: =
pointer;">douglas...@gmail.com</a>&gt; ha scritto:&nbsp;<br>&gt; [paper]&nb=
sp;<br>Apart from a typo in my name (s/Nicole/Nicola), it=E2=80=99s great t=
o see something written finally!&nbsp;<br></blockquote><div>My sincere apol=
ogies... corrected.</div><div>&nbsp;</div><blockquote class=3D"gmail_quote"=
 style=3D"margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-co=
lor: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex;">A co=
uple of points:&nbsp;<br>- Why restricting the use of variadics? I think an=
ything you can do with one parameter&nbsp;<br>can be done for a parameter p=
ack. I don=E2=80=99t see the benefit of this restriction, and it also&nbsp;=
<br>has some use cases like a logging function with a variadic interface in=
stead of a streaming&nbsp;<br>one.&nbsp;<br></blockquote><div>Lifted&nbsp;<=
/div><blockquote class=3D"gmail_quote" style=3D"margin: 0px 0px 0px 0.8ex; =
border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-=
style: solid; padding-left: 1ex;">- If we=E2=80=99re talking about overload=
ing on lazy parameters, should =E2=80=98inline=E2=80=99 be a modifier like&=
nbsp;<br>const or volatile, from the grammar point of view? This should mak=
e it easy to specify&nbsp;<br>the semantics of cases when you pass inline a=
rguments to other inline parameters,&nbsp;<br>saying that the evaluation of=
 the thunk must happen on a =E2=80=9Cinline to non-inline=E2=80=9D conversi=
on.&nbsp;<br><br></blockquote><div>I'm not sure about this one.</div><block=
quote class=3D"gmail_quote" style=3D"margin: 0px 0px 0px 0.8ex; border-left=
-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: soli=
d; padding-left: 1ex;">Bye,&nbsp;<br>Nicola&nbsp;</blockquote><div>&nbsp;</=
div></div>

<p></p>

-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_958_26796072.1419425451873--
------=_Part_957_1140121579.1419425451872
Content-Type: text/plain; charset=UTF-8; name="delayed evaluation parameters.txt"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
 filename="delayed evaluation parameters.txt"
X-Attachment-Id: 69c10277-bdec-40cd-99ef-b9519af9d7dc
Content-ID: <69c10277-bdec-40cd-99ef-b9519af9d7dc>

Document number: Dxxx=3Dxx-xxxx
Date: xxxx-xx-xx
Project: Programming language C++, Core Working Group
Reply-to: Douglas Boffey <douglas.boffey@gmail.com>

Table of Contents
-----------------
1. Introduction
2. Motivation and Scope
3. Impact on the Standard
4. Design Decisions
5. Technical Specifications
6. Future Enhancements
7. Acknowledgements
8. References

Introduction
------------
This proposal provides Delayed Expression Parameters (DEPs), which are para=
meters to a constructor, function or member function that are only evaluate=
d on first use.

Motivation and Scope
--------------------
Most of the time, function parameters are evaluated prior to invocation of =
a function, but there are occasions where that is not what is needed.

Some of the reasons are:

a) evaluation of a parameter might invoke undefined behaviour in some circu=
mstances.  Take, for example, the idiom:

if (a && /* some expression involving *a */)

where a is a pointer to memory, or nullptr.

b) a parameter might be expensive to construct and then destruct.  If it is=
 only sometimes needed, it would make sense only to evaluate it in those ci=
rcumstances.

c) code might need to be included in some builds, e.g. debug builds, that s=
houldn=E2=80=99t be included in other builds, e.g. production builds.  For =
example, code that checks preconditions, postconditions and invariants.

d) it may be that only details of a variable type are required.  For exampl=
e, a user-implementation of sizeof for variables would look like:

template <typename T>
std::size_t my_sizeof(inline T t) {
  return sizeof(T);
}

e) logging may be optionally enabled.  Given, for example,

log(level) << expensive_expression

it is convenient not to evaluate expensive_expression.

Currently, c) and e) are usually achieved by using macro functions, expandi=
ng to something like:

if (/* enabled */) /* something potentially involving an expensive expressi=
on */

Impact on the Standard
----------------------
This code introduces no breaking behaviour.

Design Decisions
----------------
There are a number of decisions:

a) Should the parameter be evaluated once only (cache-like), or on every oc=
curance (instance-like)?
This proposal is for a cache-like solution, because:
 * efficiency
  - an instance-like solution might require multiple constructions or assig=
nements
  - an instance-like solution might inhibit optimisations, e.g. moving code=
 out of loop
 * effect
  - there could be problems if the DEP was an rvalue
  - multiple evaluations might produce unexpected behaviour.  Take, for ins=
tance,

void fn(inline int a) {/* =E2=80=A6 */}

// =E2=80=A6

int a{1};
fn(++a);

It could be difficult to predict what a would end up as.
 * documentation: it would be easier to document the conditions under which=
 the DEP is evaluated rather than the number of times it is evaluated.

b) When should the parameter be evaluated?
A parameter needs to be evaluated whenever the value is needed, a reference=
 of it is taken, or a pointer is made to point to it.  The functions =E2=80=
=98sizeof=E2=80=99, =E2=80=98typeid=E2=80=99, =E2=80=98alignas=E2=80=99 and=
 =E2=80=98decltype=E2=80=99 would not cause the DEP to be evaluated, as onl=
y the type of the DEP is required.  Any references or pointers to the param=
eter should be to the cached value, not the code generating the value.

c) What about a DEP used within a DEP of a subsidary function?
The DEP should not automatically be evaluated, but if it has not been evalu=
ated, the subsidiary function would be responsible for evaluating it.

If the subsidiary function evaluates the DEP, that evaluation is visible in=
 the outer function.

For example:

int bar(inline int a) {
  return a;
}

void foo(inline int b) {
  // b has not been evaluated yet
  bar(b);
  // foo sees that b has been evaluated and has access to the value
}

d) Should the DEP be a wrapper (like std::function) or a separate object (l=
ike a lambda)?
AS it would not make sense to refer to the code evaluating the value, the c=
ode should be as if it were a wrapper around the parameter.

e) What nomenclature should be used?
Three options:
 1. a symbol: this would be inconsistent with existing practice, where symb=
ols are part of the type.

 2. introduce a new keyword, e.g. lazy: any new keyword is a potential for =
breaking code, and there is no obvious way, consistent with the current syn=
tax, of introducing a context-sensitive keyword.

 3. use an existing keyword: the keyword, =E2=80=98inline=E2=80=99 bests de=
scribes the effect of a DEP.  It is proposed that it should be put at the b=
eginning of a DEP declaration, to mirror inline variables.

f) A conforming implementation can execute a function taking a DEP with an =
already-evaluated value rather than a thunk, provided that the evaluation h=
as no observable side effects (and without specifying how an implementation=
 might do such a thing).  For example, it would be permitted that an implem=
entation generate multiple versions of a function taking one or more DEPs a=
nd choose between them.

Technical Specifications
------------------------
TBD

Future Enhancements
-------------------
Unless the parameter is evaluated in a try block, it would be subject to an=
y exception restrictions of the callee, although the code is owned by the c=
aller.  It might be better to permit an exception specification with the DE=
P.

Acknowledgements
----------------
My thanks go to sasho648, whose proposal inspired this proposal.  Also to N=
icola Gigante, David Krauss and Matthew Woehlke for their insightful commen=
ts.

References
----------
See https://groups.google.com/a/isocpp.org/forum/#!topic/std-proposals/ftrF=
qbyu7pQ for a discussion on this

Other, similar proposals can be found on https://groups.google.com/a/isocpp=
..org/forum/#!topic/std-proposals/ftrFqbyu7pQ and https://groups.google.com/=
a/isocpp.org/d/topic/std-proposals/DnxRfo_uQl8/discussion

--=20

---=20
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 e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

------=_Part_957_1140121579.1419425451872--

.


Author: Nicola Gigante <nicola.gigante@gmail.com>
Date: Wed, 24 Dec 2014 14:10:25 +0100
Raw View
Il giorno 23/dic/2014, alle ore 19:53, Matthew Woehlke <mw_triad@users.sour=
ceforge.net> ha scritto:

> Again, I'm inclined to word this sort of thing "as if", and leave it to
> the compiler vendors when/if they can implement it more efficiently.
> Using e.g. std::function to explain how it would work makes tons of
> sense. Forcing the implementation to *actually use* std::function... not
> so much. Just specify the effects clearly and leave the rest to the
> compiler.
>=20

We completely agree on this point!

> Pedantic: I assume you meant "*at most* once"? (If we don't allow them
> to not be executed ever that rather defeats the purpose :-).)

Yes, of course ;)

>=20
>> Of course, side effects would be discouraged in arguments of those
>> kinds of functions
>=20
> Actually, as I see it, lazy evaluation is most interesting when the
> arguments *do* have side effects. (Pedantically, I'm including
> dereferencing a potentially null pointer as a "side effect", the side
> effect here being to raise a SIGSEGV. However I think there are other
> uses with other side effects, e.g. incrementing a value, where lazy
> evaluation is interesting for the sake of potentially not causing the
> side effects. Using e.g. short circuit of the built-in Boolean operators
> to selectively trigger side effects isn't that unusual=E2=80=A6)
>=20

If =E2=80=9Ccause undefined behavior=E2=80=9D (like the sigsegv you mention=
ed) is a side effect,
then yes, of course one of the most valuable use cases of this feature!

> If we did that, then it makes sense to permit overloads based on
> lazy-eval or not, since the call site makes explicit which one it wants
> (again, except for || and && operators). I'm sort of ambivalent about
> that, though; if we require extra syntax, there's not much gain over
> explicitly passing a std::function, which we could do today.
>=20

I don=E2=80=99t think overloading would be very useful anyway. What would y=
ou
do differently in the non lazy version?

> (Less relevant; I feel like 'inline <expr>' would look really odd :-).)
>=20

yes, but =E2=80=98inline=E2=80=99 is odd as a keyword here anyway. Is it so=
 infeasible to
add a keyword to the language in a major revision like C++17?

I think =E2=80=98lazy=E2=80=99 as a name is not used very often.=20
And C++17 will already reserve much more used keywords like=20
=E2=80=98requires=E2=80=99 and =E2=80=98await=E2=80=99.

However, rather than require the keyword, I would propose that
if the user does not add it, then the expression is evaluated as usual:

void func(lazy int); // Function with lazy parameter
void func2(int); // Normal function

func(x) // Evaluates x at call site.
func(lazy x) // Defer evaluation.

func2(lazy x); // Not allowed


Another point is if we can deduce it in template parameters.

template<typename T>
void func(T v);

func(inline x); // Will func instance have a lazy argument?

> --=20
> Matthew

Bye,
Nicola

--=20

---=20
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 e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

.


Author: masse.nicolas@gmail.com
Date: Wed, 24 Dec 2014 05:40:54 -0800 (PST)
Raw View
------=_Part_4193_1557259116.1419428454969
Content-Type: multipart/alternative;
 boundary="----=_Part_4194_1470756623.1419428454970"

------=_Part_4194_1470756623.1419428454970
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable



Le mercredi 24 d=C3=A9cembre 2014 00:32:19 UTC+1, Matthew Woehlke a =C3=A9c=
rit :
>
> ...
>
> > Also note that as far as I can see, a library based approach should be=
=20
> able=20
> > to solve both point b) and c).=20
>
> True, but I just mentioned the benefit of a non-library approach :-).=20
> (And in fact I talked about this earlier; if the caller is required to=20
> go through additional gyrations to pass a DEP, then indeed a library=20
> solution is possible. However, a) those gyrations can get rather=20
> verbose


In fact it would add a lambda around the parameter. More verbose, true, but=
=20
I can live with it.
=20

> , and b) a language approach may offer additional optimization=20
> opportunities to the compiler.)=20
>
>
I'm unsure of that, especially since the overhead added by the wrapper will=
=20
still remain quite minimal compared to the cost of actually executing the=
=20
parameter.
Anyway, I don't know much about compiler internals, so having some advices=
=20
from compilers vendors would probably help here.
=20

> Thinking on it further, it may be useful to implement this (library or=20
> otherwise) in a way that the DEP passed is actually (a reference to?)=20
> the container for the cached parameter, e.g. something like an extended=
=20
> std::optional with a std::function (which may be null!) to evaluate the=
=20
> parameter. This would simplify passing constant values (just pass an=20
> already-evaluated DEP with a null evaluation thunk, rather than needing=
=20
> to overload) and forwarding of DEP's (since it's by reference, just pass=
=20
> the caller's DEP).=20
>
>
Completely agree here. (in fact this was what I was thinkink about).
=20

> If anything, some of the above considerations I think make a language=20
> change even more interesting; let the compiler sort out when to pass a=20
> thunk rather than making the user decide.=20
>
> Another point related to "optimization opportunities"; std::function is=
=20
> expensive. A language solution allows compiler vendors the freedom to do=
=20
> whatever to make the thunk as lightweight as they can manage. For=20
> example, maybe the thunk is just a pointer to the stack that contains a=
=20
> pointer to code that knows where to access the necessary locals relative=
=20
> to the same stack pointer. We can get away with tricks like this since=20
> the thunk is non-copyable (at least, we know it won't outlive the=20
> caller) that are not possible with something as generic as std::function.=
=20
>
>
Again, having some input from compiler vendors here would be of a great=20
value.
=20

> --=20
> Matthew=20
>
>
 Nicolas.
=20

--=20

---=20
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 e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

------=_Part_4194_1470756623.1419428454970
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>Le mercredi 24 d=C3=A9cembre 2014 00:32:19 UTC+1, =
Matthew Woehlke a =C3=A9crit&nbsp;:<blockquote class=3D"gmail_quote" style=
=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: =
1ex;">...<br>
<br>&gt; Also note that as far as I can see, a library based approach shoul=
d be able=20
<br>&gt; to solve both point b) and c).
<br>
<br>True, but I just mentioned the benefit of a non-library approach :-).
<br>(And in fact I talked about this earlier; if the caller is required to
<br>go through additional gyrations to pass a DEP, then indeed a library
<br>solution is possible. However, a) those gyrations can get rather
<br>verbose</blockquote><div><br>In fact it would add a lambda around the p=
arameter. More verbose, true, but I can live with it.<br>&nbsp;<br></div><b=
lockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;borde=
r-left: 1px #ccc solid;padding-left: 1ex;">, and b) a language approach may=
 offer additional optimization
<br>opportunities to the compiler.)
<br>
<br></blockquote><div><br>I'm unsure of that, especially since the overhead=
 added by the wrapper will still remain quite minimal compared to the cost =
of actually executing the parameter.<br>Anyway, I don't know much about com=
piler internals, so having some advices from compilers vendors would probab=
ly help here.<br></div><div>&nbsp;</div><blockquote class=3D"gmail_quote" s=
tyle=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-le=
ft: 1ex;">Thinking on it further, it may be useful to implement this (libra=
ry or
<br>otherwise) in a way that the DEP passed is actually (a reference to?)
<br>the container for the cached parameter, e.g. something like an extended
<br>std::optional with a std::function (which may be null!) to evaluate the
<br>parameter. This would simplify passing constant values (just pass an
<br>already-evaluated DEP with a null evaluation thunk, rather than needing
<br>to overload) and forwarding of DEP's (since it's by reference, just pas=
s
<br>the caller's DEP).
<br>
<br></blockquote><div><br>Completely agree here. (in fact this was what I w=
as thinkink about).<br>&nbsp;</div><blockquote class=3D"gmail_quote" style=
=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: =
1ex;">If anything, some of the above considerations I think make a language
<br>change even more interesting; let the compiler sort out when to pass a
<br>thunk rather than making the user decide.
<br>
<br>Another point related to "optimization opportunities"; std::function is
<br>expensive. A language solution allows compiler vendors the freedom to d=
o
<br>whatever to make the thunk as lightweight as they can manage. For
<br>example, maybe the thunk is just a pointer to the stack that contains a
<br>pointer to code that knows where to access the necessary locals relativ=
e
<br>to the same stack pointer. We can get away with tricks like this since
<br>the thunk is non-copyable (at least, we know it won't outlive the
<br>caller) that are not possible with something as generic as std::functio=
n.
<br>
<br></blockquote><div><br>Again, having some input from compiler vendors he=
re would be of a great value.<br>&nbsp;</div><blockquote class=3D"gmail_quo=
te" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;paddi=
ng-left: 1ex;">--=20
<br>Matthew
<br>
<br></blockquote><div><br>&nbsp;Nicolas.<br></div><div>&nbsp;</div></div>

<p></p>

-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_4194_1470756623.1419428454970--
------=_Part_4193_1557259116.1419428454969--

.


Author: Matthew Woehlke <mw_triad@users.sourceforge.net>
Date: Wed, 24 Dec 2014 11:22:38 -0500
Raw View
On 2014-12-24 08:10, Nicola Gigante wrote:
> Il giorno 23/dic/2014, alle ore 19:53, Matthew Woehlke ha scritto:
>> If we [require 'inline' before a DEP parameter at the call site],=20
>> then it makes sense to permit overloads based on lazy-eval or not,
>> since the call site makes explicit which one it wants (again,
>> except for || and && operators). I'm sort of ambivalent about that,
>> though; if we require extra syntax, there's not much gain over
>> explicitly passing a std::function, which we could do today.
>
> I don=E2=80=99t think overloading would be very useful anyway. What would=
 you
> do differently in the non lazy version?

Note: "makes sense" does not necessarily imply "is desirable" :-).
Probably nothing. But...

  foo(a, inline b); // calls foo(T1, inline T2), obviously
  foo(a, b); // calls foo(T1, T2), obviously

....because the overload resolution is thoroughly non-ambiguous.

>> (Less relevant; I feel like 'inline <expr>' would look really odd :-).)
>=20
> yes, but =E2=80=98inline=E2=80=99 is odd as a keyword here anyway. Is it =
so infeasible to
> add a keyword to the language in a major revision like C++17?

No, and it's not the use of 'inline' specifically. I just don't feel
like the call site should need to be specially decorated at all. (I
think 'inline' is fine for marking a DEP.)

--=20
Matthew

--=20

---=20
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 e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

.


Author: Matthew Woehlke <mw_triad@users.sourceforge.net>
Date: Wed, 24 Dec 2014 11:40:11 -0500
Raw View
On 2014-12-24 08:40, masse.nicolas@gmail.com wrote:
> Le mercredi 24 d=C3=A9cembre 2014 00:32:19 UTC+1, Matthew Woehlke a =C3=
=A9crit :
>>> Also note that as far as I can see, a library based approach should be=
=20
>>> able to solve both point b) and c).=20
>>
>> True, but I just mentioned the benefit of a non-library approach :-).=20
>> (And in fact I talked about this earlier; if the caller is required to=
=20
>> go through additional gyrations to pass a DEP, then indeed a library=20
>> solution is possible. However, a) those gyrations can get rather=20
>> verbose,
>=20
> In fact it would add a lambda around the parameter.

Exactly:

  foo(++a);
    - vs. -
  foo(inline ++a);
    - vs. -
  foo([&]{ return ++a; });

I'm on record as voting for the first :-).

>> and b) a language approach may offer additional optimization=20
>> opportunities to the compiler.)=20
>
> I'm unsure of that, especially since the overhead added by the wrapper wi=
ll=20
> still remain quite minimal compared to the cost of actually executing the=
=20
> parameter.

Can the wrapper be constructed already evaluated? (Well, this one at
least I would think we can manage.)

Can the wrapper's thunk be as lightweight as a pair of pointers?
(Remember that the wrapper needs either a knowable or template type for
the thunk.)

Can we get a zero-overhead solution when passing a DEP to another
function taking a DEP? Note that this means passing it by reference,
which we can't normally do via a temporary (or has that been relaxed?).

Those are the questions I'd be asking to weigh the value of a language
feature over a library solution, with respect to the performance
implications.

--=20
Matthew

--=20

---=20
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 e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

.


Author: Matthew Woehlke <mw_triad@users.sourceforge.net>
Date: Wed, 24 Dec 2014 11:42:10 -0500
Raw View
On 2014-12-24 07:50, Douglas Boffey wrote:
> On Tuesday, 23 December 2014 23:58:51 UTC, Matthew Woehlke wrote:
>> We might want to explicitly mention that a conforming implementation can=
=20
>> execute a function taking a DEP with an already-evaluated value rather=
=20
>> than a thunk, provided that said evaluation has no observable side=20
>> effects (and without specifying how an implementation might do such a=20
>> thing). Note that the choice of "execute" (vs. "call") is intentional,=
=20
>> e.g. it would be permitted that an implementation generate multiple=20
>> versions of a function taking one or more DEP's and choose between them.=
=20
>
> Added=20

Thanks; I think this is fairly important to include for its optimization
potential.

>> A couple of points:=20
>> - Why restricting the use of variadics? I think anything you can do
>> with one parameter can be done for a parameter pack. I don=E2=80=99t see
>> the benefit of this restriction, and it also has some use cases
>> like a logging function with a variadic interface instead of a
>> streaming one.
>
> Lifted=20

FWIW I felt the same way, but let it be since you'd already explicitly
mentioned this as a future direction.

>> - If we=E2=80=99re talking about overloading on lazy parameters, should
>> =E2=80=98inline=E2=80=99 be a modifier like const or volatile, from the =
grammar
>> point of view? This should make it easy to specify the semantics of
>> cases when you pass inline arguments to other inline parameters,=20
>> saying that the evaluation of the thunk must happen on a =E2=80=9Cinline
>> to non-inline=E2=80=9D conversion.

We already call out how the first case should behave, if a little
indirectly. The latter (DEP to non-DEP) I would think is obvious that
counts as 'use' and would evaluate the DEP at that point. Now...

> I'm not sure about this one.

....if it makes sense to express the above using some particular language
related to modifiers, I'm not sure either :-).

--=20
Matthew

--=20

---=20
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 e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

.


Author: masse.nicolas@gmail.com
Date: Thu, 25 Dec 2014 06:01:13 -0800 (PST)
Raw View
------=_Part_5567_1465029643.1419516073912
Content-Type: multipart/alternative;
 boundary="----=_Part_5568_1853197046.1419516073912"

------=_Part_5568_1853197046.1419516073912
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable



Le mercredi 24 d=C3=A9cembre 2014 17:40:28 UTC+1, Matthew Woehlke a =C3=A9c=
rit :
>
> On 2014-12-24 08:40, masse....@gmail.com <javascript:> wrote:=20
> > Le mercredi 24 d=C3=A9cembre 2014 00:32:19 UTC+1, Matthew Woehlke a =C3=
=A9crit :=20
> >>> Also note that as far as I can see, a library based approach should b=
e=20
> >>> able to solve both point b) and c).=20
> >>=20
> >> True, but I just mentioned the benefit of a non-library approach :-).=
=20
> >> (And in fact I talked about this earlier; if the caller is required to=
=20
> >> go through additional gyrations to pass a DEP, then indeed a library=
=20
> >> solution is possible. However, a) those gyrations can get rather=20
> >> verbose,=20
> >=20
> > In fact it would add a lambda around the parameter.=20
>
> Exactly:=20
>
>   foo(++a);=20
>     - vs. -=20
>   foo(inline ++a);=20
>     - vs. -=20
>   foo([&]{ return ++a; });=20
>
>
I've implemented the delay<T> class. It turns out that using this is more=
=20
like
foo(delayed<int> { [&]{ return ++a; } });
because the compiler isn't able to infer delayed<int> from the lambda, so=
=20
we should help him here.


> >> and b) a language approach may offer additional optimization=20
> >> opportunities to the compiler.)=20
> >=20
> > I'm unsure of that, especially since the overhead added by the wrapper=
=20
> will=20
> > still remain quite minimal compared to the cost of actually executing=
=20
> the=20
> > parameter.=20
>
> Can the wrapper be constructed already evaluated? (Well, this one at=20
> least I would think we can manage.)=20
>

Yes, it works.=20
=20

> Can the wrapper's thunk be as lightweight as a pair of pointers?=20
> (Remember that the wrapper needs either a knowable or template type for=
=20
> the thunk.)=20
>
> My wrapper contains 2 member :
- the std::function responsible for computing the value(if not computed yet=
)
- the computed value itself

Can we get a zero-overhead solution when passing a DEP to another=20
> function taking a DEP? Note that this means passing it by reference,=20
> which we can't normally do via a temporary (or has that been relaxed?).=
=20
>
> passing references does work.
=20

> Those are the questions I'd be asking to weigh the value of a language=20
> feature over a library solution, with respect to the performance=20
> implications.=20
>
> =20
Here I join the code i've written. (tested with clang-3.5.0) so you can=20
have a look.
=20

> --=20
> Matthew=20
>
>
Nicolas
=20

--=20

---=20
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 e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

------=_Part_5568_1853197046.1419516073912
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>Le mercredi 24 d=C3=A9cembre 2014 17:40:28 UTC+1, =
Matthew Woehlke a =C3=A9crit&nbsp;:<blockquote class=3D"gmail_quote" style=
=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: =
1ex;">On 2014-12-24 08:40, <a href=3D"javascript:" target=3D"_blank" gdf-ob=
fuscated-mailto=3D"S9mJdFM1mToJ" onmousedown=3D"this.href=3D'javascript:';r=
eturn true;" onclick=3D"this.href=3D'javascript:';return true;">masse....@g=
mail.com</a> wrote:
<br>&gt; Le mercredi 24 d=C3=A9cembre 2014 00:32:19 UTC+1, Matthew Woehlke =
a =C3=A9crit :
<br>&gt;&gt;&gt; Also note that as far as I can see, a library based approa=
ch should be=20
<br>&gt;&gt;&gt; able to solve both point b) and c).=20
<br>&gt;&gt;
<br>&gt;&gt; True, but I just mentioned the benefit of a non-library approa=
ch :-).=20
<br>&gt;&gt; (And in fact I talked about this earlier; if the caller is req=
uired to=20
<br>&gt;&gt; go through additional gyrations to pass a DEP, then indeed a l=
ibrary=20
<br>&gt;&gt; solution is possible. However, a) those gyrations can get rath=
er=20
<br>&gt;&gt; verbose,
<br>&gt;=20
<br>&gt; In fact it would add a lambda around the parameter.
<br>
<br>Exactly:
<br>
<br>&nbsp; foo(++a);
<br>&nbsp; &nbsp; - vs. -
<br>&nbsp; foo(inline ++a);
<br>&nbsp; &nbsp; - vs. -
<br>&nbsp; foo([&amp;]{ return ++a; });
<br>
<br></blockquote><div><br>I've implemented the delay&lt;T&gt; class. It tur=
ns out that using this is more like<br><div class=3D"prettyprint" style=3D"=
background-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187); bor=
der-style: solid; border-width: 1px; word-wrap: break-word;"><code class=3D=
"prettyprint"><div class=3D"subprettyprint"><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify">foo</span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify">delayed</span><span style=3D"color: #080;" class=3D"styled-by-pr=
ettify">&lt;int&gt;</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
{</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">[&amp;]{</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">return</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">++</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify">a</span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">;</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">}=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">});</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"><br></span></div></code></=
div>because the compiler isn't able to infer delayed&lt;int&gt; from the la=
mbda, so we should help him here.<br><br></div><blockquote class=3D"gmail_q=
uote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;pad=
ding-left: 1ex;">
<br>&gt;&gt; and b) a language approach may offer additional optimization=
=20
<br>&gt;&gt; opportunities to the compiler.)=20
<br>&gt;
<br>&gt; I'm unsure of that, especially since the overhead added by the wra=
pper will=20
<br>&gt; still remain quite minimal compared to the cost of actually execut=
ing the=20
<br>&gt; parameter.
<br>
<br>Can the wrapper be constructed already evaluated? (Well, this one at
<br>least I would think we can manage.)
<br></blockquote><div><br>Yes, it works. <br></div><div>&nbsp;</div><blockq=
uote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-lef=
t: 1px #ccc solid;padding-left: 1ex;">Can the wrapper's thunk be as lightwe=
ight as a pair of pointers?
<br>(Remember that the wrapper needs either a knowable or template type for
<br>the thunk.)
<br>
<br></blockquote><div>My wrapper contains 2 member :<br>- the std::function=
 responsible for computing the value(if not computed yet)<br>- the computed=
 value itself<br><br></div><blockquote class=3D"gmail_quote" style=3D"margi=
n: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">Can=
 we get a zero-overhead solution when passing a DEP to another
<br>function taking a DEP? Note that this means passing it by reference,
<br>which we can't normally do via a temporary (or has that been relaxed?).
<br>
<br></blockquote><div>passing references does work.<br>&nbsp;</div><blockqu=
ote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left=
: 1px #ccc solid;padding-left: 1ex;">Those are the questions I'd be asking =
to weigh the value of a language
<br>feature over a library solution, with respect to the performance
<br>implications.
<br>
<br></blockquote><div>&nbsp;</div><div>Here I join the code i've written. (=
tested with clang-3.5.0) so you can have a look.<br>&nbsp;</div><blockquote=
 class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1=
px #ccc solid;padding-left: 1ex;">--=20
<br>Matthew
<br>
<br></blockquote><div><br>Nicolas<br>&nbsp;</div></div>

<p></p>

-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_5568_1853197046.1419516073912--
------=_Part_5567_1465029643.1419516073912
Content-Type: text/x-c++src; charset=US-ASCII; name=delayed.cpp
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename=delayed.cpp
X-Attachment-Id: 8c00e8fc-438b-4773-bc6d-3393f3df7157
Content-ID: <8c00e8fc-438b-4773-bc6d-3393f3df7157>

#include <functional>
#include <iostream>
#include <utility>

using namespace std;

template<typename T>
class delayed final
{
 using func_type = function<T()>;
 mutable func_type m_function;
 mutable T m_value;
public:
 delayed(func_type&& function)
 : m_function(function), m_value()
 {
  cout << "moved ctor" << endl;
 }
 delayed(const func_type& function)
 : m_function(function), m_value()
 {
  cout << "copy ctor" << endl;
 }
 delayed(T&& value)
 : m_function(), m_value(value)
 {
  cout << "moved value ctor" << endl;
 }
 delayed(const T& value)
 : m_function(), m_value(value)
 {
  cout << "copy value ctor" << endl;
 }

 delayed& operator =(T value)
 {
  m_value = value;
  m_function = nullptr;
  return *this;
 }

 delayed& operator =(func_type&& function)
 {
  m_function = function;
  return *this;
 }

 delayed& operator =(const func_type& function)
 {
  m_function = function;
  return *this;
 }

 const T& get() const
 {
  if(m_function)
  {
   m_value = m_function();
   m_function = nullptr;
  }
  return m_value;
 }

 T& get()
 {
  if(m_function)
  {
   m_value = m_function();
   m_function = nullptr;
  }
  return m_value;
 }
 T& operator *()
 {
  return get();
 }
 const T& operator *() const
 {
  return get();
 }
 T* operator ->()
 {
  return &(get());
 }
 const T* const operator ->() const
 {
  return &(get());
 }
};

template<typename T>
ostream& operator<< (ostream& stream, const delayed<T>& value)
{
 return stream << value.get();
}


void test1(const delayed<int>& value)
{
 cout << "the value is " << value.get() << std::endl;
}

void test2(const delayed<int>& value)
{
 cout << "the value is still " << value << std::endl;
}


void test(const delayed<int>& value)
{
 test1(value);
 test2(value);
}

void test(const delayed<string>& value)
{
 cout << "the string length is " << value->size() << std::endl;
 cout << "the string is " << value << std::endl;
}

int main(int argc, char** argv)
{
 test(++argc);
 test(delayed<int> { [&argc]() { cout << " [computing value] "; return ++argc; } });
 function<int()> f = [argc]() -> int { cout << " [computing value] "; return argc; };
 test(f);


 string text = "string test";
 test(text);
 test(string("string test2"));

 return 0;
}

------=_Part_5567_1465029643.1419516073912--

.


Author: Douglas Boffey <douglas.boffey@gmail.com>
Date: Thu, 25 Dec 2014 07:07:29 -0800 (PST)
Raw View
------=_Part_1_757375839.1419520049407
Content-Type: multipart/alternative;
 boundary="----=_Part_2_1080150304.1419520049407"

------=_Part_2_1080150304.1419520049407
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

Just one question: have you checked the assembler output to check how=20
efficient it actually is?

On Thursday, 25 December 2014 14:01:13 UTC, masse....@gmail.com wrote:
>
>
>
> Le mercredi 24 d=C3=A9cembre 2014 17:40:28 UTC+1, Matthew Woehlke a =C3=
=A9crit :
>>
>> On 2014-12-24 08:40, masse....@gmail.com wrote:=20
>> > Le mercredi 24 d=C3=A9cembre 2014 00:32:19 UTC+1, Matthew Woehlke a =
=C3=A9crit :=20
>> >>> Also note that as far as I can see, a library based approach should=
=20
>> be=20
>> >>> able to solve both point b) and c).=20
>> >>=20
>> >> True, but I just mentioned the benefit of a non-library approach :-).=
=20
>> >> (And in fact I talked about this earlier; if the caller is required t=
o=20
>> >> go through additional gyrations to pass a DEP, then indeed a library=
=20
>> >> solution is possible. However, a) those gyrations can get rather=20
>> >> verbose,=20
>> >=20
>> > In fact it would add a lambda around the parameter.=20
>>
>> Exactly:=20
>>
>>   foo(++a);=20
>>     - vs. -=20
>>   foo(inline ++a);=20
>>     - vs. -=20
>>   foo([&]{ return ++a; });=20
>>
>>
> I've implemented the delay<T> class. It turns out that using this is more=
=20
> like
> foo(delayed<int> { [&]{ return ++a; } });
> because the compiler isn't able to infer delayed<int> from the lambda, so=
=20
> we should help him here.
>
>
>> >> and b) a language approach may offer additional optimization=20
>> >> opportunities to the compiler.)=20
>> >=20
>> > I'm unsure of that, especially since the overhead added by the wrapper=
=20
>> will=20
>> > still remain quite minimal compared to the cost of actually executing=
=20
>> the=20
>> > parameter.=20
>>
>> Can the wrapper be constructed already evaluated? (Well, this one at=20
>> least I would think we can manage.)=20
>>
>
> Yes, it works.=20
> =20
>
>> Can the wrapper's thunk be as lightweight as a pair of pointers?=20
>> (Remember that the wrapper needs either a knowable or template type for=
=20
>> the thunk.)=20
>>
>> My wrapper contains 2 member :
> - the std::function responsible for computing the value(if not computed=
=20
> yet)
> - the computed value itself
>
> Can we get a zero-overhead solution when passing a DEP to another=20
>> function taking a DEP? Note that this means passing it by reference,=20
>> which we can't normally do via a temporary (or has that been relaxed?).=
=20
>>
>> passing references does work.
> =20
>
>> Those are the questions I'd be asking to weigh the value of a language=
=20
>> feature over a library solution, with respect to the performance=20
>> implications.=20
>>
>> =20
> Here I join the code i've written. (tested with clang-3.5.0) so you can=
=20
> have a look.
> =20
>
>> --=20
>> Matthew=20
>>
>>
> Nicolas
> =20
>

--=20

---=20
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 e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

------=_Part_2_1080150304.1419520049407
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Just one question: have you checked the assembler output t=
o check how efficient it actually is?<br><br>On Thursday, 25 December 2014 =
14:01:13 UTC, masse....@gmail.com  wrote:<blockquote class=3D"gmail_quote" =
style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-l=
eft: 1ex;"><div dir=3D"ltr"><br><br>Le mercredi 24 d=C3=A9cembre 2014 17:40=
:28 UTC+1, Matthew Woehlke a =C3=A9crit&nbsp;:<blockquote class=3D"gmail_qu=
ote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding=
-left:1ex">On 2014-12-24 08:40, <a>masse....@gmail.com</a> wrote:
<br>&gt; Le mercredi 24 d=C3=A9cembre 2014 00:32:19 UTC+1, Matthew Woehlke =
a =C3=A9crit :
<br>&gt;&gt;&gt; Also note that as far as I can see, a library based approa=
ch should be=20
<br>&gt;&gt;&gt; able to solve both point b) and c).=20
<br>&gt;&gt;
<br>&gt;&gt; True, but I just mentioned the benefit of a non-library approa=
ch :-).=20
<br>&gt;&gt; (And in fact I talked about this earlier; if the caller is req=
uired to=20
<br>&gt;&gt; go through additional gyrations to pass a DEP, then indeed a l=
ibrary=20
<br>&gt;&gt; solution is possible. However, a) those gyrations can get rath=
er=20
<br>&gt;&gt; verbose,
<br>&gt;=20
<br>&gt; In fact it would add a lambda around the parameter.
<br>
<br>Exactly:
<br>
<br>&nbsp; foo(++a);
<br>&nbsp; &nbsp; - vs. -
<br>&nbsp; foo(inline ++a);
<br>&nbsp; &nbsp; - vs. -
<br>&nbsp; foo([&amp;]{ return ++a; });
<br>
<br></blockquote><div><br>I've implemented the delay&lt;T&gt; class. It tur=
ns out that using this is more like<br><div style=3D"background-color:rgb(2=
50,250,250);border-color:rgb(187,187,187);border-style:solid;border-width:1=
px;word-wrap:break-word"><code><div><span style=3D"color:#000">foo</span><s=
pan style=3D"color:#660">(</span><span style=3D"color:#000">delayed</span><=
span style=3D"color:#080">&lt;int&gt;</span><span style=3D"color:#000"> </s=
pan><span style=3D"color:#660">{</span><span style=3D"color:#000"> </span><=
span style=3D"color:#660">[&amp;]{</span><span style=3D"color:#000"> </span=
><span style=3D"color:#008">return</span><span style=3D"color:#000"> </span=
><span style=3D"color:#660">++</span><span style=3D"color:#000">a</span><sp=
an style=3D"color:#660">;</span><span style=3D"color:#000"> </span><span st=
yle=3D"color:#660">}</span><span style=3D"color:#000"> </span><span style=
=3D"color:#660">});</span><span style=3D"color:#000"><br></span></div></cod=
e></div>because the compiler isn't able to infer delayed&lt;int&gt; from th=
e lambda, so we should help him here.<br><br></div><blockquote class=3D"gma=
il_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;pa=
dding-left:1ex">
<br>&gt;&gt; and b) a language approach may offer additional optimization=
=20
<br>&gt;&gt; opportunities to the compiler.)=20
<br>&gt;
<br>&gt; I'm unsure of that, especially since the overhead added by the wra=
pper will=20
<br>&gt; still remain quite minimal compared to the cost of actually execut=
ing the=20
<br>&gt; parameter.
<br>
<br>Can the wrapper be constructed already evaluated? (Well, this one at
<br>least I would think we can manage.)
<br></blockquote><div><br>Yes, it works. <br></div><div>&nbsp;</div><blockq=
uote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:=
1px #ccc solid;padding-left:1ex">Can the wrapper's thunk be as lightweight =
as a pair of pointers?
<br>(Remember that the wrapper needs either a knowable or template type for
<br>the thunk.)
<br>
<br></blockquote><div>My wrapper contains 2 member :<br>- the std::function=
 responsible for computing the value(if not computed yet)<br>- the computed=
 value itself<br><br></div><blockquote class=3D"gmail_quote" style=3D"margi=
n:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex">Can we g=
et a zero-overhead solution when passing a DEP to another
<br>function taking a DEP? Note that this means passing it by reference,
<br>which we can't normally do via a temporary (or has that been relaxed?).
<br>
<br></blockquote><div>passing references does work.<br>&nbsp;</div><blockqu=
ote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1=
px #ccc solid;padding-left:1ex">Those are the questions I'd be asking to we=
igh the value of a language
<br>feature over a library solution, with respect to the performance
<br>implications.
<br>
<br></blockquote><div>&nbsp;</div><div>Here I join the code i've written. (=
tested with clang-3.5.0) so you can have a look.<br>&nbsp;</div><blockquote=
 class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px =
#ccc solid;padding-left:1ex">--=20
<br>Matthew
<br>
<br></blockquote><div><br>Nicolas<br>&nbsp;</div></div></blockquote></div>

<p></p>

-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_2_1080150304.1419520049407--
------=_Part_1_757375839.1419520049407--

.


Author: masse.nicolas@gmail.com
Date: Thu, 25 Dec 2014 08:49:54 -0800 (PST)
Raw View
------=_Part_50_1926075664.1419526194755
Content-Type: multipart/alternative;
 boundary="----=_Part_51_385189970.1419526194755"

------=_Part_51_385189970.1419526194755
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

No I didn't

Le jeudi 25 d=C3=A9cembre 2014 16:07:29 UTC+1, Douglas Boffey a =C3=A9crit =
:
>
> Just one question: have you checked the assembler output to check how=20
> efficient it actually is?
>
> On Thursday, 25 December 2014 14:01:13 UTC, masse....@gmail.com wrote:
>>
>>
>>
>> Le mercredi 24 d=C3=A9cembre 2014 17:40:28 UTC+1, Matthew Woehlke a =C3=
=A9crit :
>>>
>>> On 2014-12-24 08:40, masse....@gmail.com wrote:=20
>>> > Le mercredi 24 d=C3=A9cembre 2014 00:32:19 UTC+1, Matthew Woehlke a =
=C3=A9crit :=20
>>> >>> Also note that as far as I can see, a library based approach should=
=20
>>> be=20
>>> >>> able to solve both point b) and c).=20
>>> >>=20
>>> >> True, but I just mentioned the benefit of a non-library approach :-)=
..=20
>>> >> (And in fact I talked about this earlier; if the caller is required=
=20
>>> to=20
>>> >> go through additional gyrations to pass a DEP, then indeed a library=
=20
>>> >> solution is possible. However, a) those gyrations can get rather=20
>>> >> verbose,=20
>>> >=20
>>> > In fact it would add a lambda around the parameter.=20
>>>
>>> Exactly:=20
>>>
>>>   foo(++a);=20
>>>     - vs. -=20
>>>   foo(inline ++a);=20
>>>     - vs. -=20
>>>   foo([&]{ return ++a; });=20
>>>
>>>
>> I've implemented the delay<T> class. It turns out that using this is mor=
e=20
>> like
>> foo(delayed<int> { [&]{ return ++a; } });
>> because the compiler isn't able to infer delayed<int> from the lambda, s=
o=20
>> we should help him here.
>>
>>
>>> >> and b) a language approach may offer additional optimization=20
>>> >> opportunities to the compiler.)=20
>>> >=20
>>> > I'm unsure of that, especially since the overhead added by the wrappe=
r=20
>>> will=20
>>> > still remain quite minimal compared to the cost of actually executing=
=20
>>> the=20
>>> > parameter.=20
>>>
>>> Can the wrapper be constructed already evaluated? (Well, this one at=20
>>> least I would think we can manage.)=20
>>>
>>
>> Yes, it works.=20
>> =20
>>
>>> Can the wrapper's thunk be as lightweight as a pair of pointers?=20
>>> (Remember that the wrapper needs either a knowable or template type for=
=20
>>> the thunk.)=20
>>>
>>> My wrapper contains 2 member :
>> - the std::function responsible for computing the value(if not computed=
=20
>> yet)
>> - the computed value itself
>>
>> Can we get a zero-overhead solution when passing a DEP to another=20
>>> function taking a DEP? Note that this means passing it by reference,=20
>>> which we can't normally do via a temporary (or has that been relaxed?).=
=20
>>>
>>> passing references does work.
>> =20
>>
>>> Those are the questions I'd be asking to weigh the value of a language=
=20
>>> feature over a library solution, with respect to the performance=20
>>> implications.=20
>>>
>>> =20
>> Here I join the code i've written. (tested with clang-3.5.0) so you can=
=20
>> have a look.
>> =20
>>
>>> --=20
>>> Matthew=20
>>>
>>>
>> Nicolas
>> =20
>>
>

--=20

---=20
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 e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

------=_Part_51_385189970.1419526194755
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">No I didn't<br><br>Le jeudi 25 d=C3=A9cembre 2014 16:07:29=
 UTC+1, Douglas Boffey a =C3=A9crit&nbsp;:<blockquote class=3D"gmail_quote"=
 style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-=
left: 1ex;"><div dir=3D"ltr">Just one question: have you checked the assemb=
ler output to check how efficient it actually is?<br><br>On Thursday, 25 De=
cember 2014 14:01:13 UTC, <a>masse....@gmail.com</a>  wrote:<blockquote cla=
ss=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc=
 solid;padding-left:1ex"><div dir=3D"ltr"><br><br>Le mercredi 24 d=C3=A9cem=
bre 2014 17:40:28 UTC+1, Matthew Woehlke a =C3=A9crit&nbsp;:<blockquote cla=
ss=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc=
 solid;padding-left:1ex">On 2014-12-24 08:40, <a>masse....@gmail.com</a> wr=
ote:
<br>&gt; Le mercredi 24 d=C3=A9cembre 2014 00:32:19 UTC+1, Matthew Woehlke =
a =C3=A9crit :
<br>&gt;&gt;&gt; Also note that as far as I can see, a library based approa=
ch should be=20
<br>&gt;&gt;&gt; able to solve both point b) and c).=20
<br>&gt;&gt;
<br>&gt;&gt; True, but I just mentioned the benefit of a non-library approa=
ch :-).=20
<br>&gt;&gt; (And in fact I talked about this earlier; if the caller is req=
uired to=20
<br>&gt;&gt; go through additional gyrations to pass a DEP, then indeed a l=
ibrary=20
<br>&gt;&gt; solution is possible. However, a) those gyrations can get rath=
er=20
<br>&gt;&gt; verbose,
<br>&gt;=20
<br>&gt; In fact it would add a lambda around the parameter.
<br>
<br>Exactly:
<br>
<br>&nbsp; foo(++a);
<br>&nbsp; &nbsp; - vs. -
<br>&nbsp; foo(inline ++a);
<br>&nbsp; &nbsp; - vs. -
<br>&nbsp; foo([&amp;]{ return ++a; });
<br>
<br></blockquote><div><br>I've implemented the delay&lt;T&gt; class. It tur=
ns out that using this is more like<br><div style=3D"background-color:rgb(2=
50,250,250);border-color:rgb(187,187,187);border-style:solid;border-width:1=
px;word-wrap:break-word"><code><div><span style=3D"color:#000">foo</span><s=
pan style=3D"color:#660">(</span><span style=3D"color:#000">delayed</span><=
span style=3D"color:#080">&lt;int&gt;</span><span style=3D"color:#000"> </s=
pan><span style=3D"color:#660">{</span><span style=3D"color:#000"> </span><=
span style=3D"color:#660">[&amp;]{</span><span style=3D"color:#000"> </span=
><span style=3D"color:#008">return</span><span style=3D"color:#000"> </span=
><span style=3D"color:#660">++</span><span style=3D"color:#000">a</span><sp=
an style=3D"color:#660">;</span><span style=3D"color:#000"> </span><span st=
yle=3D"color:#660">}</span><span style=3D"color:#000"> </span><span style=
=3D"color:#660">});</span><span style=3D"color:#000"><br></span></div></cod=
e></div>because the compiler isn't able to infer delayed&lt;int&gt; from th=
e lambda, so we should help him here.<br><br></div><blockquote class=3D"gma=
il_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;pa=
dding-left:1ex">
<br>&gt;&gt; and b) a language approach may offer additional optimization=
=20
<br>&gt;&gt; opportunities to the compiler.)=20
<br>&gt;
<br>&gt; I'm unsure of that, especially since the overhead added by the wra=
pper will=20
<br>&gt; still remain quite minimal compared to the cost of actually execut=
ing the=20
<br>&gt; parameter.
<br>
<br>Can the wrapper be constructed already evaluated? (Well, this one at
<br>least I would think we can manage.)
<br></blockquote><div><br>Yes, it works. <br></div><div>&nbsp;</div><blockq=
uote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:=
1px #ccc solid;padding-left:1ex">Can the wrapper's thunk be as lightweight =
as a pair of pointers?
<br>(Remember that the wrapper needs either a knowable or template type for
<br>the thunk.)
<br>
<br></blockquote><div>My wrapper contains 2 member :<br>- the std::function=
 responsible for computing the value(if not computed yet)<br>- the computed=
 value itself<br><br></div><blockquote class=3D"gmail_quote" style=3D"margi=
n:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex">Can we g=
et a zero-overhead solution when passing a DEP to another
<br>function taking a DEP? Note that this means passing it by reference,
<br>which we can't normally do via a temporary (or has that been relaxed?).
<br>
<br></blockquote><div>passing references does work.<br>&nbsp;</div><blockqu=
ote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1=
px #ccc solid;padding-left:1ex">Those are the questions I'd be asking to we=
igh the value of a language
<br>feature over a library solution, with respect to the performance
<br>implications.
<br>
<br></blockquote><div>&nbsp;</div><div>Here I join the code i've written. (=
tested with clang-3.5.0) so you can have a look.<br>&nbsp;</div><blockquote=
 class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px =
#ccc solid;padding-left:1ex">--=20
<br>Matthew
<br>
<br></blockquote><div><br>Nicolas<br>&nbsp;</div></div></blockquote></div><=
/blockquote></div>

<p></p>

-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_51_385189970.1419526194755--
------=_Part_50_1926075664.1419526194755--

.


Author: Scott Prager <splinterofchaos@gmail.com>
Date: Thu, 25 Dec 2014 17:46:12 -0800 (PST)
Raw View
------=_Part_5765_1160806888.1419558372887
Content-Type: multipart/alternative;
 boundary="----=_Part_5766_1939917268.1419558372887"

------=_Part_5766_1939917268.1419558372887
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

A more efficiency-oriented version might be parametrized on the function=20
itself and define `T` as `std::result_of_t<F()>`,
although it would make overloading based on the result type a little more=
=20
difficult as the exact type would be `delayed<F>`.
Plus, any function using it would require a template argument, but that=20
might not be a bad thing.

If the value is known not to be initialized at the start of the function=20
(through inlining) it can likely be optimized such that

template<typename F, typename G>
typename std::common_type<delayed<F>::value_type
                         ,delayed<G>::value_type>::type
  cond(bool b, delayed<F> f, delayed<G> g)
{
  if (f.get()) return f.get();
  return g.get();
}

// ...
auto x =3D cond(b,f,g)

would have no more or less efficiency than

auto x =3D b ? f() : g();

While, even with `std::function`, some compiler optimization assumptions=20
will hold when inlined, this won't be the case otherwise.

However, it seems anti-idiomatic to parameterize a class on its function,=
=20
so I don't know that the above would be advisable. The only place it might=
=20
possibly be relevant would be the critical loop of an application.

Also, this discussion reminds me of `ftl::lazy<T>`=20
<https://github.com/beark/ftl/blob/master/include/ftl/lazy.h#L101>.

On Thursday, December 25, 2014 9:01:13 AM UTC-5, masse....@gmail.com wrote:
>
>
>
> Le mercredi 24 d=C3=A9cembre 2014 17:40:28 UTC+1, Matthew Woehlke a =C3=
=A9crit :
>>
>> On 2014-12-24 08:40, masse....@gmail.com wrote:=20
>> > Le mercredi 24 d=C3=A9cembre 2014 00:32:19 UTC+1, Matthew Woehlke a =
=C3=A9crit :=20
>> >>> Also note that as far as I can see, a library based approach should=
=20
>> be=20
>> >>> able to solve both point b) and c).=20
>> >>=20
>> >> True, but I just mentioned the benefit of a non-library approach :-).=
=20
>> >> (And in fact I talked about this earlier; if the caller is required t=
o=20
>> >> go through additional gyrations to pass a DEP, then indeed a library=
=20
>> >> solution is possible. However, a) those gyrations can get rather=20
>> >> verbose,=20
>> >=20
>> > In fact it would add a lambda around the parameter.=20
>>
>> Exactly:=20
>>
>>   foo(++a);=20
>>     - vs. -=20
>>   foo(inline ++a);=20
>>     - vs. -=20
>>   foo([&]{ return ++a; });=20
>>
>>
> I've implemented the delay<T> class. It turns out that using this is more=
=20
> like
> foo(delayed<int> { [&]{ return ++a; } });
> because the compiler isn't able to infer delayed<int> from the lambda, so=
=20
> we should help him here.
>
>
>> >> and b) a language approach may offer additional optimization=20
>> >> opportunities to the compiler.)=20
>> >=20
>> > I'm unsure of that, especially since the overhead added by the wrapper=
=20
>> will=20
>> > still remain quite minimal compared to the cost of actually executing=
=20
>> the=20
>> > parameter.=20
>>
>> Can the wrapper be constructed already evaluated? (Well, this one at=20
>> least I would think we can manage.)=20
>>
>
> Yes, it works.=20
> =20
>
>> Can the wrapper's thunk be as lightweight as a pair of pointers?=20
>> (Remember that the wrapper needs either a knowable or template type for=
=20
>> the thunk.)=20
>>
>> My wrapper contains 2 member :
> - the std::function responsible for computing the value(if not computed=
=20
> yet)
> - the computed value itself
>
> Can we get a zero-overhead solution when passing a DEP to another=20
>> function taking a DEP? Note that this means passing it by reference,=20
>> which we can't normally do via a temporary (or has that been relaxed?).=
=20
>>
>> passing references does work.
> =20
>
>> Those are the questions I'd be asking to weigh the value of a language=
=20
>> feature over a library solution, with respect to the performance=20
>> implications.=20
>>
>> =20
> Here I join the code i've written. (tested with clang-3.5.0) so you can=
=20
> have a look.
> =20
>
>> --=20
>> Matthew=20
>>
>>
> Nicolas
> =20
>

--=20

---=20
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 e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

------=_Part_5766_1939917268.1419558372887
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">A more efficiency-oriented version might be parametrized o=
n the function itself and define `T` as `std::result_of_t&lt;F()&gt;`,<div>=
although it would make overloading based on the result type a little more d=
ifficult as the exact type would be `delayed&lt;F&gt;`.</div><div>Plus, any=
 function using it would require a template argument, but that might not be=
 a bad thing.</div><div><br></div><div>If the value is known not to be init=
ialized at the start of the function (through inlining) it can likely be op=
timized such that</div><div><br></div><div class=3D"prettyprint" style=3D"b=
order: 1px solid rgb(187, 187, 187); word-wrap: break-word; background-colo=
r: rgb(250, 250, 250);"><code class=3D"prettyprint"><div class=3D"subpretty=
print"><span style=3D"color: #008;" class=3D"styled-by-prettify">template</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><=
span style=3D"color: #008;" class=3D"styled-by-prettify">typename</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"> F</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" =
class=3D"styled-by-prettify">typename</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"> G</span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">&gt;</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"><br></span><span style=3D"color: #008;" class=3D"styled-by-pre=
ttify">typename</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"> std</span><span style=3D"color: #660;" class=3D"styled-by-prettify">:=
:</span><span style=3D"color: #000;" class=3D"styled-by-prettify">common_ty=
pe</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify">delayed</span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify">F</span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">&gt;::</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify">value_type<br>&nbsp; &nbsp; &nbsp; &=
nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify">delayed</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify">G</span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">&gt;::</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify">value_type</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">&gt;::</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify">type<br>&nbsp; cond</span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">(</span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">bool</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> b</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
> delayed</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&=
lt;</span><span style=3D"color: #000;" class=3D"styled-by-prettify">F</span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">&gt;</span><span=
 style=3D"color: #000;" class=3D"styled-by-prettify"> f</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"> delayed</span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">&lt;</span><span style=3D"color: #000;"=
 class=3D"styled-by-prettify">G</span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">&gt;</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> g</span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">)</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><b=
r></span><span style=3D"color: #660;" class=3D"styled-by-prettify">{</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"><br>&nbsp; </span=
><span style=3D"color: #008;" class=3D"styled-by-prettify">if</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify">f</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">.</span><span style=3D"color: #008;" class=3D"style=
d-by-prettify">get</span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">())</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">return</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"> f</span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">.</span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">get</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">();</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"><br>&nbsp; </span><span style=3D"color: #0=
08;" class=3D"styled-by-prettify">return</span><span style=3D"color: #000;"=
 class=3D"styled-by-prettify"> g</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">.</span><span style=3D"color: #008;" class=3D"style=
d-by-prettify">get</span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">();</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
><br></span><span style=3D"color: #660;" class=3D"styled-by-prettify">}</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"><br><br></span=
><span style=3D"color: #800;" class=3D"styled-by-prettify">// ...</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span sty=
le=3D"color: #008;" class=3D"styled-by-prettify">auto</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"> x </span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> cond</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify">b</span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify">f</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify">g</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">)</span><font color=3D"#6666=
00"></font></div></code></div><div><br></div><div>would have no more or les=
s efficiency than</div><div><br></div><div><div class=3D"prettyprint" style=
=3D"border: 1px solid rgb(187, 187, 187); word-wrap: break-word; background=
-color: rgb(250, 250, 250);"><code class=3D"prettyprint"><div class=3D"subp=
rettyprint"><span style=3D"color: #008;" class=3D"styled-by-prettify">auto<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"> x </span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> b </span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">?</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"> f</span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">()</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">:</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
 g</span><span style=3D"color: #660;" class=3D"styled-by-prettify">();</spa=
n></div></code></div></div><div><br></div><div>While, even with `std::funct=
ion`, some compiler optimization assumptions will hold when inlined, this w=
on't be the case otherwise.</div><div><br></div><div>However, it seems anti=
-idiomatic to parameterize a class on its function, so I don't know that th=
e above would be advisable. The only place it might possibly be relevant wo=
uld be the critical loop of an application.</div><div><br></div><div>Also, =
this discussion reminds me of <a href=3D"https://github.com/beark/ftl/blob/=
master/include/ftl/lazy.h#L101">`ftl::lazy&lt;T&gt;`</a>.</div><div><br>On =
Thursday, December 25, 2014 9:01:13 AM UTC-5, masse....@gmail.com wrote:<bl=
ockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border=
-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><br><br>Le mercr=
edi 24 d=C3=A9cembre 2014 17:40:28 UTC+1, Matthew Woehlke a =C3=A9crit&nbsp=
;:<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;bor=
der-left:1px #ccc solid;padding-left:1ex">On 2014-12-24 08:40, <a>masse....=
@gmail.com</a> wrote:
<br>&gt; Le mercredi 24 d=C3=A9cembre 2014 00:32:19 UTC+1, Matthew Woehlke =
a =C3=A9crit :
<br>&gt;&gt;&gt; Also note that as far as I can see, a library based approa=
ch should be=20
<br>&gt;&gt;&gt; able to solve both point b) and c).=20
<br>&gt;&gt;
<br>&gt;&gt; True, but I just mentioned the benefit of a non-library approa=
ch :-).=20
<br>&gt;&gt; (And in fact I talked about this earlier; if the caller is req=
uired to=20
<br>&gt;&gt; go through additional gyrations to pass a DEP, then indeed a l=
ibrary=20
<br>&gt;&gt; solution is possible. However, a) those gyrations can get rath=
er=20
<br>&gt;&gt; verbose,
<br>&gt;=20
<br>&gt; In fact it would add a lambda around the parameter.
<br>
<br>Exactly:
<br>
<br>&nbsp; foo(++a);
<br>&nbsp; &nbsp; - vs. -
<br>&nbsp; foo(inline ++a);
<br>&nbsp; &nbsp; - vs. -
<br>&nbsp; foo([&amp;]{ return ++a; });
<br>
<br></blockquote><div><br>I've implemented the delay&lt;T&gt; class. It tur=
ns out that using this is more like<br><div style=3D"background-color:rgb(2=
50,250,250);border-color:rgb(187,187,187);border-style:solid;border-width:1=
px;word-wrap:break-word"><code><div><span style=3D"color:#000">foo</span><s=
pan style=3D"color:#660">(</span><span style=3D"color:#000">delayed</span><=
span style=3D"color:#080">&lt;int&gt;</span><span style=3D"color:#000"> </s=
pan><span style=3D"color:#660">{</span><span style=3D"color:#000"> </span><=
span style=3D"color:#660">[&amp;]{</span><span style=3D"color:#000"> </span=
><span style=3D"color:#008">return</span><span style=3D"color:#000"> </span=
><span style=3D"color:#660">++</span><span style=3D"color:#000">a</span><sp=
an style=3D"color:#660">;</span><span style=3D"color:#000"> </span><span st=
yle=3D"color:#660">}</span><span style=3D"color:#000"> </span><span style=
=3D"color:#660">});</span><span style=3D"color:#000"><br></span></div></cod=
e></div>because the compiler isn't able to infer delayed&lt;int&gt; from th=
e lambda, so we should help him here.<br><br></div><blockquote class=3D"gma=
il_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;pa=
dding-left:1ex">
<br>&gt;&gt; and b) a language approach may offer additional optimization=
=20
<br>&gt;&gt; opportunities to the compiler.)=20
<br>&gt;
<br>&gt; I'm unsure of that, especially since the overhead added by the wra=
pper will=20
<br>&gt; still remain quite minimal compared to the cost of actually execut=
ing the=20
<br>&gt; parameter.
<br>
<br>Can the wrapper be constructed already evaluated? (Well, this one at
<br>least I would think we can manage.)
<br></blockquote><div><br>Yes, it works. <br></div><div>&nbsp;</div><blockq=
uote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:=
1px #ccc solid;padding-left:1ex">Can the wrapper's thunk be as lightweight =
as a pair of pointers?
<br>(Remember that the wrapper needs either a knowable or template type for
<br>the thunk.)
<br>
<br></blockquote><div>My wrapper contains 2 member :<br>- the std::function=
 responsible for computing the value(if not computed yet)<br>- the computed=
 value itself<br><br></div><blockquote class=3D"gmail_quote" style=3D"margi=
n:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex">Can we g=
et a zero-overhead solution when passing a DEP to another
<br>function taking a DEP? Note that this means passing it by reference,
<br>which we can't normally do via a temporary (or has that been relaxed?).
<br>
<br></blockquote><div>passing references does work.<br>&nbsp;</div><blockqu=
ote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1=
px #ccc solid;padding-left:1ex">Those are the questions I'd be asking to we=
igh the value of a language
<br>feature over a library solution, with respect to the performance
<br>implications.
<br>
<br></blockquote><div>&nbsp;</div><div>Here I join the code i've written. (=
tested with clang-3.5.0) so you can have a look.<br>&nbsp;</div><blockquote=
 class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px =
#ccc solid;padding-left:1ex">--=20
<br>Matthew
<br>
<br></blockquote><div><br>Nicolas<br>&nbsp;</div></div></blockquote></div><=
/div>

<p></p>

-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_5766_1939917268.1419558372887--
------=_Part_5765_1160806888.1419558372887--

.


Author: Matthew Woehlke <mw_triad@users.sourceforge.net>
Date: Fri, 26 Dec 2014 12:03:32 -0500
Raw View
On 2014-12-25 09:01, masse.nicolas@gmail.com wrote:
> Le mercredi 24 d=C3=A9cembre 2014 17:40:28 UTC+1, Matthew Woehlke a =C3=
=A9crit :
>> Can the wrapper's thunk be as lightweight as a pair of pointers?=20
>> (Remember that the wrapper needs either a knowable or template type for=
=20
>> the thunk.)=20
>
> My wrapper contains 2 member :
> - the std::function responsible for computing the value(if not computed y=
et)
> - the computed value itself

Ah! That's clever; I hadn't thought of using the presence or absence of
the thunk as the indicator if it's been evaluated already.

That said... what is the overhead of the std::function? I admit I
haven't actually looked into that, but I'd be surprised if it is not
larger than two pointers. (If it involves a heap allocation at all, that
would be *horrifically* inefficient compared to what a language feature
ought to be able to manage...)

From some cursory web searching, it looks like a heap allocation may be
likely, given that any "reasonable" DEP is pretty well assumed to need
some storage space. That right there is, to me, the biggest reason to go
with a language feature instead. Since we know that the DEP will not
outlive where it is created, we can keep all information that the thunk
needs on the stack. If the thunk is well written, it should need *at
most* a pointer into the stack that gives a known location relative to
the caller's stack frame, which the thunk can then access directly
without needing to copy things or access them via indirection.

>> Can we get a zero-overhead solution when passing a DEP to another=20
>> function taking a DEP? Note that this means passing it by reference,=20
>> which we can't normally do via a temporary (or has that been relaxed?).=
=20
>
> passing references does work.

Why not?

In a language implementation, I would expect that the caller would
construct the DEP on the stack (remember, it is fixed size) and pass the
pointer to the DEP to the function taking a DEP parameter. If that
function in turn calls another DEP-taking function with the DEP, it can
just pass the same pointer.

(Oh... and the DEP pointer itself could be the stack reference that the
thunk needs, so the DEP overhead just became *one* pointer, not counting
the code of the thunk itself.)

> Here I join the code i've written. (tested with clang-3.5.0) so you can=
=20
> have a look.

Seems okay as a proof of concept, but I'll also note that a "real"
implementation should avoid constructing the value when initializing to
a thunk.

--=20
Matthew

--=20

---=20
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 e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

.


Author: Matthew Woehlke <mw_triad@users.sourceforge.net>
Date: Fri, 26 Dec 2014 12:13:20 -0500
Raw View
On 2014-12-25 20:46, Scott Prager wrote:
> A more efficiency-oriented version might be parametrized on the function
> itself and define `T` as `std::result_of_t<F()>`,
> although it would make overloading based on the result type a little more
> difficult as the exact type would be `delayed<F>`.
> Plus, any function using it would require a template argument, but that
> might not be a bad thing.

No. That's not just bad, that's fatal. Now I have to provide users with
the definition of any function taking a DEP.

As currently proposed, a DEP can be defined in some other TU and not
resolved until link time. Making DEP's necessarily template parameters
would preclude that.

Also, I suspect this would make it unnecessarily awkward to specify the
value type.

--
Matthew

--

---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

.


Author: Douglas Boffey <douglas.boffey@gmail.com>
Date: Mon, 5 Jan 2015 21:58:42 +0000
Raw View
Should it be UB if a variable needed for a DEP is accessed in the
function?  Otherwise, optimisations may be inhibited.

On 12/26/14, Matthew Woehlke <mw_triad@users.sourceforge.net> wrote:
> On 2014-12-25 20:46, Scott Prager wrote:
>> A more efficiency-oriented version might be parametrized on the function
>> itself and define `T` as `std::result_of_t<F()>`,
>> although it would make overloading based on the result type a little more
>>
>> difficult as the exact type would be `delayed<F>`.
>> Plus, any function using it would require a template argument, but that
>> might not be a bad thing.
>
> No. That's not just bad, that's fatal. Now I have to provide users with
> the definition of any function taking a DEP.
>
> As currently proposed, a DEP can be defined in some other TU and not
> resolved until link time. Making DEP's necessarily template parameters
> would preclude that.
>
> Also, I suspect this would make it unnecessarily awkward to specify the
> value type.
>
> --
> Matthew
>
> --
>
> ---
> 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.
> Visit this group at
> http://groups.google.com/a/isocpp.org/group/std-proposals/.
>

--

---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

.


Author: Matthew Woehlke <mw_triad@users.sourceforge.net>
Date: Tue, 06 Jan 2015 11:01:16 -0500
Raw View
On 2015-01-05 16:58, Douglas Boffey wrote:
> Should it be UB if a variable needed for a DEP is accessed in the
> function?  Otherwise, optimisations may be inhibited.

Do you mean something like:

  int foo(inline int a, int& b)
  {
    int c = b;
    return a + c;
  }

  int bar = 2;
  foo(++bar, bar); // is result 5 or 6?

That's a good question. This seems similar to the case of overlapping
pointers to memcpy... I wonder if something like [[restrict]] would be
useful.

I would say, as a rule of thumb, if instead of a DEP, you passed
whatever values are needed for the DEP expression by reference, and
wrote out the DEP expression at the point where the DEP would be
evaluated, that if doing so would result in UB, then the DEP is also UB,
otherwise not. (Hopefully this would result naturally from most
implementations, anyway.)

Honestly, though, I think that both concrete examples and input from
compiler authors (which I am not) would be helpful here.

Conversely, it may be safer to just say that it's UB and expect / hope
that compilers will anyway do the reasonable thing when possible.

--
Matthew

--

---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

.


Author: Nicola Gigante <nicola.gigante@gmail.com>
Date: Tue, 6 Jan 2015 19:35:21 +0100
Raw View
Il giorno 06/gen/2015, alle ore 17:01, Matthew Woehlke <mw_triad@users.sourceforge.net> ha scritto:
>
>> On 2015-01-05 16:58, Douglas Boffey wrote:
>> Should it be UB if a variable needed for a DEP is accessed in the
>> function?  Otherwise, optimisations may be inhibited.
>
> Do you mean something like:
>
>  int foo(inline int a, int& b)
>  {
>    int c = b;
>    return a + c;
>  }
>
>  int bar = 2;
>  foo(++bar, bar); // is result 5 or 6?
>
> That's a good question. This seems similar to the case of overlapping
> pointers to memcpy... I wonder if something like [[restrict]] would be
> useful.
>
> I would say, as a rule of thumb, if instead of a DEP, you passed
> whatever values are needed for the DEP expression by reference, and
> wrote out the DEP expression at the point where the DEP would be
> evaluated, that if doing so would result in UB, then the DEP is also UB,
> otherwise not. (Hopefully this would result naturally from most
> implementations, anyway.)
>
> Honestly, though, I think that both concrete examples and input from
> compiler authors (which I am not) would be helpful here.
>
> Conversely, it may be safer to just say that it's UB and expect / hope
> that compilers will anyway do the reasonable thing when possible.
>

That should be unspecified, not undefined. In the same way as the order of evaluation of function arguments.

UB is a strong punishment. We don't want people to break the universe just to have passed a variable to a function, do we?

> --
> Matthew
>

Bye,
Nicola

--

---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

.


Author: Arthur O'Dwyer <arthur.j.odwyer@gmail.com>
Date: Tue, 6 Jan 2015 12:58:22 -0800 (PST)
Raw View
------=_Part_4649_446700897.1420577902334
Content-Type: multipart/alternative;
 boundary="----=_Part_4650_99145967.1420577902334"

------=_Part_4650_99145967.1420577902334
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

I don't really see the advantage of "hiding" the laziness of lazy=20
parameters. In this very thread, Nicola (and later Matthew? I'm not sure)=
=20
have suggested that it might be wise to

> require the =E2=80=98inline=E2=80=99 (or =E2=80=98lazy=E2=80=99, or whate=
ver) keyword at the _call_ site,=20
too

If you allow that as a possibility, then you can implement the entire=20
mechanism in just a few lines of code, which you can dump into your own=20
project's "lazy.hpp". I don't think any change to the Standard itself is=20
warranted.
Here's the code, which is valid C++14 and C++1z (and can be made C++11 by=
=20
replacing a few `auto`s). Notice the features:
- Call site is explicitly annotated with lazy(x).
- Implementation clearly indicates exactly where the evaluation takes=20
place, rather than leaving it fuzzily implicit.
- Implementing a function "as lazy" does not *force* laziness; you can=20
annotate the call site with eager(x) just as easily as lazy(x).
- Implementation retains control of when and where any copy-constructions=
=20
take place: i.e., whether we evaluate the thunk multiple times, or=20
once-and-cache, or once-and-not-cache (saving the cost of a=20
copy-construction, which may not even be possible in the general case, e.g.=
=20
lazy expressions whose return type is unique_ptr).
- No heavyweight library dependencies; the whole thing is implemented in=20
terms of core language features.

=3D=3D=3D=3D=3D

// Here's the library implementation.

template<class L> struct lazy_t {
    L l_;
    lazy_t(L l) : l_(l) {}
    auto eval() { return l_(); }
};
template<class L> auto make_lazy(L&& lambda) {
    return lazy_t<L>(lambda);
}
#define lazy(expr) make_lazy([&]{ return expr; })

template<class E> struct eager_t {
    E e_;
    eager_t(E e) : e_(e) {}
    auto eval() { return e_; }
};
template<class E> auto make_eager(E&& eager) {
    return eager_t<E>(static_cast<E&&>(eager));
}
#define eager(expr) make_eager(expr)

// Here's the user's code.

#include <stdio.h>
#include <stdlib.h>

#ifdef CPP_1z

auto cond(bool b, auto /*lazy*/ x, auto /*lazy*/ y)
{
    return b ? x.eval() : y.eval();
}

#else
template<class L1, class L2>
auto cond(bool b, L1 /*lazy*/ x, L2 /*lazy*/ y) {
    return b ? x.eval() : y.eval();
}
#endif

int main(int argc, char** argv) {
    int a =3D atoi(argv[1]);
    int b =3D atoi(argv[2]);
    int c =3D atoi(argv[3]);
    int d =3D cond(a, lazy(++b), lazy(c++));
    printf("%d %d %d %d\n", a,b,c,d);
}

=3D=3D=3D=3D=3D



On Tuesday, January 6, 2015 10:35:25 AM UTC-8, Nicola Gigante wrote:
>
> Il giorno 06/gen/2015, alle ore 17:01, Matthew Woehlke <
> mw_t...@users.sourceforge.net <javascript:>> ha scritto:=20
> >=20
> >> On 2015-01-05 16:58, Douglas Boffey wrote:=20
> >> Should it be UB if a variable needed for a DEP is accessed in the=20
> >> function?  Otherwise, optimisations may be inhibited.=20
> >=20
> > Do you mean something like:=20
> >=20
> >  int foo(inline int a, int& b)=20
> >  {=20
> >    int c =3D b;=20
> >    return a + c;=20
> >  }=20
> >=20
> >  int bar =3D 2;=20
> >  foo(++bar, bar); // is result 5 or 6?=20
> >=20
> > That's a good question. This seems similar to the case of overlapping=
=20
> > pointers to memcpy... I wonder if something like [[restrict]] would be=
=20
> > useful.=20
> >=20
> > I would say, as a rule of thumb, if instead of a DEP, you passed=20
> > whatever values are needed for the DEP expression by reference, and=20
> > wrote out the DEP expression at the point where the DEP would be=20
> > evaluated, that if doing so would result in UB, then the DEP is also UB=
,=20
> > otherwise not. (Hopefully this would result naturally from most=20
> > implementations, anyway.)=20
> >=20
> > Honestly, though, I think that both concrete examples and input from=20
> > compiler authors (which I am not) would be helpful here.=20
> >=20
> > Conversely, it may be safer to just say that it's UB and expect / hope=
=20
> > that compilers will anyway do the reasonable thing when possible.=20
> >=20
>
> That should be unspecified, not undefined. In the same way as the order o=
f=20
> evaluation of function arguments.=20
>
> UB is a strong punishment. We don't want people to break the universe jus=
t=20
> to have passed a variable to a function, do we?=20
>
> > --=20
> > Matthew=20
> >=20
>
> Bye,=20
> Nicola=20

--=20

---=20
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 e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

------=_Part_4650_99145967.1420577902334
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div><div>I don't really see the advantage of "hiding" the=
 laziness of lazy parameters. In this very thread, Nicola (and later Matthe=
w? I'm not sure) have suggested that it might be wise to</div><div><br></di=
v><div>&gt; require the =E2=80=98inline=E2=80=99 (or =E2=80=98lazy=E2=80=99=
, or whatever) keyword at the _call_ site, too<br></div><div><br></div><div=
>If you allow that as a possibility, then you can implement the entire mech=
anism in just a few lines of code, which you can dump into your own project=
's "lazy.hpp". I don't think any change to the Standard itself is warranted=
..</div><div>Here's the code, which is valid C++14 and C++1z (and can be mad=
e C++11 by replacing a few `auto`s). Notice the features:</div><div>- Call =
site is explicitly annotated with lazy(x).</div><div>- Implementation clear=
ly indicates exactly where the evaluation takes place, rather than leaving =
it fuzzily implicit.<br></div><div>- Implementing a function "as lazy" does=
 not *force* laziness; you can annotate the call site with eager(x) just as=
 easily as lazy(x).</div><div>- Implementation retains control of when and =
where any copy-constructions take place: i.e., whether we evaluate the thun=
k multiple times, or once-and-cache, or once-and-not-cache (saving the cost=
 of a copy-construction, which may not even be possible in the general case=
, e.g. lazy expressions whose return type is unique_ptr).<br></div><div>- N=
o heavyweight library dependencies; the whole thing is implemented in terms=
 of core language features.</div><div><br></div><div>=3D=3D=3D=3D=3D</div><=
div><br></div><div>// Here's the library implementation.</div><div><br></di=
v><div><div>template&lt;class L&gt; struct lazy_t {</div><div>&nbsp; &nbsp;=
 L l_;</div><div>&nbsp; &nbsp; lazy_t(L l) : l_(l) {}</div><div>&nbsp; &nbs=
p; auto eval() { return l_(); }</div><div>};</div><div>template&lt;class L&=
gt; auto make_lazy(L&amp;&amp; lambda) {</div><div>&nbsp; &nbsp; return laz=
y_t&lt;L&gt;(lambda);</div><div>}</div><div>#define lazy(expr) make_lazy([&=
amp;]{ return expr; })</div><div><br></div><div>template&lt;class E&gt; str=
uct eager_t {</div><div>&nbsp; &nbsp; E e_;</div><div>&nbsp; &nbsp; eager_t=
(E e) : e_(e) {}</div><div>&nbsp; &nbsp; auto eval() { return e_; }</div><d=
iv>};</div><div>template&lt;class E&gt; auto make_eager(E&amp;&amp; eager) =
{</div><div>&nbsp; &nbsp; return eager_t&lt;E&gt;(static_cast&lt;E&amp;&amp=
;&gt;(eager));</div><div>}</div><div>#define eager(expr) make_eager(expr)</=
div></div><div><br></div><div>// Here's the user's code.</div><div><br></di=
v><div>#include &lt;stdio.h&gt;</div><div>#include &lt;stdlib.h&gt;</div><d=
iv><br></div><div>#ifdef CPP_1z</div><div><br></div><div>auto cond(bool b, =
auto /*lazy*/ x, auto /*lazy*/ y)</div><div>{</div><div>&nbsp; &nbsp; retur=
n b ? x.eval() : y.eval();</div><div>}</div><div><br></div><div>#else</div>=
<div>template&lt;class L1, class L2&gt;</div><div>auto cond(bool b, L1 /*la=
zy*/ x, L2 /*lazy*/ y) {</div><div>&nbsp; &nbsp; return b ? x.eval() : y.ev=
al();</div><div>}</div><div>#endif</div><div><br></div><div>int main(int ar=
gc, char** argv) {</div><div>&nbsp; &nbsp; int a =3D atoi(argv[1]);</div><d=
iv>&nbsp; &nbsp; int b =3D atoi(argv[2]);</div><div>&nbsp; &nbsp; int c =3D=
 atoi(argv[3]);</div><div>&nbsp; &nbsp; int d =3D cond(a, lazy(++b), lazy(c=
++));</div><div>&nbsp; &nbsp; printf("%d %d %d %d\n", a,b,c,d);</div><div>}=
</div></div><div><br></div><div>=3D=3D=3D=3D=3D</div><div><br></div><br><br=
>On Tuesday, January 6, 2015 10:35:25 AM UTC-8, Nicola Gigante wrote:<block=
quote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-le=
ft: 1px #ccc solid;padding-left: 1ex;">Il giorno 06/gen/2015, alle ore 17:0=
1, Matthew Woehlke &lt;<a href=3D"javascript:" target=3D"_blank" gdf-obfusc=
ated-mailto=3D"-ywICXWrJy8J" onmousedown=3D"this.href=3D'javascript:';retur=
n true;" onclick=3D"this.href=3D'javascript:';return true;">mw_t...@users.s=
ourceforge.<wbr>net</a>&gt; ha scritto:
<br>&gt;=20
<br>&gt;&gt; On 2015-01-05 16:58, Douglas Boffey wrote:
<br>&gt;&gt; Should it be UB if a variable needed for a DEP is accessed in =
the
<br>&gt;&gt; function? &nbsp;Otherwise, optimisations may be inhibited.
<br>&gt;=20
<br>&gt; Do you mean something like:
<br>&gt;=20
<br>&gt; &nbsp;int foo(inline int a, int&amp; b)
<br>&gt; &nbsp;{
<br>&gt; &nbsp; &nbsp;int c =3D b;
<br>&gt; &nbsp; &nbsp;return a + c;
<br>&gt; &nbsp;}
<br>&gt;=20
<br>&gt; &nbsp;int bar =3D 2;
<br>&gt; &nbsp;foo(++bar, bar); // is result 5 or 6?
<br>&gt;=20
<br>&gt; That's a good question. This seems similar to the case of overlapp=
ing
<br>&gt; pointers to memcpy... I wonder if something like [[restrict]] woul=
d be
<br>&gt; useful.
<br>&gt;=20
<br>&gt; I would say, as a rule of thumb, if instead of a DEP, you passed
<br>&gt; whatever values are needed for the DEP expression by reference, an=
d
<br>&gt; wrote out the DEP expression at the point where the DEP would be
<br>&gt; evaluated, that if doing so would result in UB, then the DEP is al=
so UB,
<br>&gt; otherwise not. (Hopefully this would result naturally from most
<br>&gt; implementations, anyway.)
<br>&gt;=20
<br>&gt; Honestly, though, I think that both concrete examples and input fr=
om
<br>&gt; compiler authors (which I am not) would be helpful here.
<br>&gt;=20
<br>&gt; Conversely, it may be safer to just say that it's UB and expect / =
hope
<br>&gt; that compilers will anyway do the reasonable thing when possible.
<br>&gt;=20
<br>
<br>That should be unspecified, not undefined. In the same way as the order=
 of evaluation of function arguments.=20
<br>
<br>UB is a strong punishment. We don't want people to break the universe j=
ust to have passed a variable to a function, do we?
<br>
<br>&gt; --=20
<br>&gt; Matthew
<br>&gt;=20
<br>
<br>Bye,
<br>Nicola </blockquote></div>

<p></p>

-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_4650_99145967.1420577902334--
------=_Part_4649_446700897.1420577902334--

.


Author: Douglas Boffey <douglas.boffey@gmail.com>
Date: Tue, 6 Jan 2015 22:04:31 +0000
Raw View
Firstly, I don't believe it can be as efficient as a core
implementation, and secondly, I would not want the ugly extras

On 1/6/15, Arthur O'Dwyer <arthur.j.odwyer@gmail.com> wrote:
> I don't really see the advantage of "hiding" the laziness of lazy
> parameters. In this very thread, Nicola (and later Matthew? I'm not sure)
> have suggested that it might be wise to
>
>> require the =E2=80=98inline=E2=80=99 (or =E2=80=98lazy=E2=80=99, or what=
ever) keyword at the _call_ site,
>>
> too
>
> If you allow that as a possibility, then you can implement the entire
> mechanism in just a few lines of code, which you can dump into your own
> project's "lazy.hpp". I don't think any change to the Standard itself is
> warranted.
> Here's the code, which is valid C++14 and C++1z (and can be made C++11 by
> replacing a few `auto`s). Notice the features:
> - Call site is explicitly annotated with lazy(x).
> - Implementation clearly indicates exactly where the evaluation takes
> place, rather than leaving it fuzzily implicit.
> - Implementing a function "as lazy" does not *force* laziness; you can
> annotate the call site with eager(x) just as easily as lazy(x).
> - Implementation retains control of when and where any copy-constructions
> take place: i.e., whether we evaluate the thunk multiple times, or
> once-and-cache, or once-and-not-cache (saving the cost of a
> copy-construction, which may not even be possible in the general case, e.=
g.
>
> lazy expressions whose return type is unique_ptr).
> - No heavyweight library dependencies; the whole thing is implemented in
> terms of core language features.
>
> =3D=3D=3D=3D=3D
>
> // Here's the library implementation.
>
> template<class L> struct lazy_t {
>     L l_;
>     lazy_t(L l) : l_(l) {}
>     auto eval() { return l_(); }
> };
> template<class L> auto make_lazy(L&& lambda) {
>     return lazy_t<L>(lambda);
> }
> #define lazy(expr) make_lazy([&]{ return expr; })
>
> template<class E> struct eager_t {
>     E e_;
>     eager_t(E e) : e_(e) {}
>     auto eval() { return e_; }
> };
> template<class E> auto make_eager(E&& eager) {
>     return eager_t<E>(static_cast<E&&>(eager));
> }
> #define eager(expr) make_eager(expr)
>
> // Here's the user's code.
>
> #include <stdio.h>
> #include <stdlib.h>
>
> #ifdef CPP_1z
>
> auto cond(bool b, auto /*lazy*/ x, auto /*lazy*/ y)
> {
>     return b ? x.eval() : y.eval();
> }
>
> #else
> template<class L1, class L2>
> auto cond(bool b, L1 /*lazy*/ x, L2 /*lazy*/ y) {
>     return b ? x.eval() : y.eval();
> }
> #endif
>
> int main(int argc, char** argv) {
>     int a =3D atoi(argv[1]);
>     int b =3D atoi(argv[2]);
>     int c =3D atoi(argv[3]);
>     int d =3D cond(a, lazy(++b), lazy(c++));
>     printf("%d %d %d %d\n", a,b,c,d);
> }
>
> =3D=3D=3D=3D=3D
>
>
>
> On Tuesday, January 6, 2015 10:35:25 AM UTC-8, Nicola Gigante wrote:
>>
>> Il giorno 06/gen/2015, alle ore 17:01, Matthew Woehlke <
>> mw_t...@users.sourceforge.net <javascript:>> ha scritto:
>> >
>> >> On 2015-01-05 16:58, Douglas Boffey wrote:
>> >> Should it be UB if a variable needed for a DEP is accessed in the
>> >> function?  Otherwise, optimisations may be inhibited.
>> >
>> > Do you mean something like:
>> >
>> >  int foo(inline int a, int& b)
>> >  {
>> >    int c =3D b;
>> >    return a + c;
>> >  }
>> >
>> >  int bar =3D 2;
>> >  foo(++bar, bar); // is result 5 or 6?
>> >
>> > That's a good question. This seems similar to the case of overlapping
>> > pointers to memcpy... I wonder if something like [[restrict]] would be
>> > useful.
>> >
>> > I would say, as a rule of thumb, if instead of a DEP, you passed
>> > whatever values are needed for the DEP expression by reference, and
>> > wrote out the DEP expression at the point where the DEP would be
>> > evaluated, that if doing so would result in UB, then the DEP is also U=
B,
>> >
>> > otherwise not. (Hopefully this would result naturally from most
>> > implementations, anyway.)
>> >
>> > Honestly, though, I think that both concrete examples and input from
>> > compiler authors (which I am not) would be helpful here.
>> >
>> > Conversely, it may be safer to just say that it's UB and expect / hope
>> > that compilers will anyway do the reasonable thing when possible.
>> >
>>
>> That should be unspecified, not undefined. In the same way as the order =
of
>>
>> evaluation of function arguments.
>>
>> UB is a strong punishment. We don't want people to break the universe ju=
st
>>
>> to have passed a variable to a function, do we?
>>
>> > --
>> > Matthew
>> >
>>
>> Bye,
>> Nicola
>
> --
>
> ---
> 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.
> Visit this group at
> http://groups.google.com/a/isocpp.org/group/std-proposals/.
>

--=20

---=20
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 e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

.


Author: Douglas Boffey <douglas.boffey@gmail.com>
Date: Tue, 6 Jan 2015 22:07:30 +0000
Raw View
Any syntax surely should be consistent with operator&& and operator||.

On 1/6/15, Douglas Boffey <douglas.boffey@gmail.com> wrote:
> Firstly, I don't believe it can be as efficient as a core
> implementation, and secondly, I would not want the ugly extras
>
> On 1/6/15, Arthur O'Dwyer <arthur.j.odwyer@gmail.com> wrote:
>> I don't really see the advantage of "hiding" the laziness of lazy
>> parameters. In this very thread, Nicola (and later Matthew? I'm not sure=
)
>> have suggested that it might be wise to
>>
>>> require the =E2=80=98inline=E2=80=99 (or =E2=80=98lazy=E2=80=99, or wha=
tever) keyword at the _call_
>>> site,
>>>
>> too
>>
>> If you allow that as a possibility, then you can implement the entire
>> mechanism in just a few lines of code, which you can dump into your own
>> project's "lazy.hpp". I don't think any change to the Standard itself is
>> warranted.
>> Here's the code, which is valid C++14 and C++1z (and can be made C++11 b=
y
>> replacing a few `auto`s). Notice the features:
>> - Call site is explicitly annotated with lazy(x).
>> - Implementation clearly indicates exactly where the evaluation takes
>> place, rather than leaving it fuzzily implicit.
>> - Implementing a function "as lazy" does not *force* laziness; you can
>> annotate the call site with eager(x) just as easily as lazy(x).
>> - Implementation retains control of when and where any copy-construction=
s
>> take place: i.e., whether we evaluate the thunk multiple times, or
>> once-and-cache, or once-and-not-cache (saving the cost of a
>> copy-construction, which may not even be possible in the general case,
>> e.g.
>>
>> lazy expressions whose return type is unique_ptr).
>> - No heavyweight library dependencies; the whole thing is implemented in
>> terms of core language features.
>>
>> =3D=3D=3D=3D=3D
>>
>> // Here's the library implementation.
>>
>> template<class L> struct lazy_t {
>>     L l_;
>>     lazy_t(L l) : l_(l) {}
>>     auto eval() { return l_(); }
>> };
>> template<class L> auto make_lazy(L&& lambda) {
>>     return lazy_t<L>(lambda);
>> }
>> #define lazy(expr) make_lazy([&]{ return expr; })
>>
>> template<class E> struct eager_t {
>>     E e_;
>>     eager_t(E e) : e_(e) {}
>>     auto eval() { return e_; }
>> };
>> template<class E> auto make_eager(E&& eager) {
>>     return eager_t<E>(static_cast<E&&>(eager));
>> }
>> #define eager(expr) make_eager(expr)
>>
>> // Here's the user's code.
>>
>> #include <stdio.h>
>> #include <stdlib.h>
>>
>> #ifdef CPP_1z
>>
>> auto cond(bool b, auto /*lazy*/ x, auto /*lazy*/ y)
>> {
>>     return b ? x.eval() : y.eval();
>> }
>>
>> #else
>> template<class L1, class L2>
>> auto cond(bool b, L1 /*lazy*/ x, L2 /*lazy*/ y) {
>>     return b ? x.eval() : y.eval();
>> }
>> #endif
>>
>> int main(int argc, char** argv) {
>>     int a =3D atoi(argv[1]);
>>     int b =3D atoi(argv[2]);
>>     int c =3D atoi(argv[3]);
>>     int d =3D cond(a, lazy(++b), lazy(c++));
>>     printf("%d %d %d %d\n", a,b,c,d);
>> }
>>
>> =3D=3D=3D=3D=3D
>>
>>
>>
>> On Tuesday, January 6, 2015 10:35:25 AM UTC-8, Nicola Gigante wrote:
>>>
>>> Il giorno 06/gen/2015, alle ore 17:01, Matthew Woehlke <
>>> mw_t...@users.sourceforge.net <javascript:>> ha scritto:
>>> >
>>> >> On 2015-01-05 16:58, Douglas Boffey wrote:
>>> >> Should it be UB if a variable needed for a DEP is accessed in the
>>> >> function?  Otherwise, optimisations may be inhibited.
>>> >
>>> > Do you mean something like:
>>> >
>>> >  int foo(inline int a, int& b)
>>> >  {
>>> >    int c =3D b;
>>> >    return a + c;
>>> >  }
>>> >
>>> >  int bar =3D 2;
>>> >  foo(++bar, bar); // is result 5 or 6?
>>> >
>>> > That's a good question. This seems similar to the case of overlapping
>>> > pointers to memcpy... I wonder if something like [[restrict]] would b=
e
>>> > useful.
>>> >
>>> > I would say, as a rule of thumb, if instead of a DEP, you passed
>>> > whatever values are needed for the DEP expression by reference, and
>>> > wrote out the DEP expression at the point where the DEP would be
>>> > evaluated, that if doing so would result in UB, then the DEP is also
>>> > UB,
>>> >
>>> > otherwise not. (Hopefully this would result naturally from most
>>> > implementations, anyway.)
>>> >
>>> > Honestly, though, I think that both concrete examples and input from
>>> > compiler authors (which I am not) would be helpful here.
>>> >
>>> > Conversely, it may be safer to just say that it's UB and expect / hop=
e
>>> > that compilers will anyway do the reasonable thing when possible.
>>> >
>>>
>>> That should be unspecified, not undefined. In the same way as the order
>>> of
>>>
>>> evaluation of function arguments.
>>>
>>> UB is a strong punishment. We don't want people to break the universe
>>> just
>>>
>>> to have passed a variable to a function, do we?
>>>
>>> > --
>>> > Matthew
>>> >
>>>
>>> Bye,
>>> Nicola
>>
>> --
>>
>> ---
>> You received this message because you are subscribed to the Google Group=
s
>> "ISO C++ Standard - Future Proposals" group.
>> To unsubscribe from this group and stop receiving emails from it, send a=
n
>> email to std-proposals+unsubscribe@isocpp.org.
>> To post to this group, send email to std-proposals@isocpp.org.
>> Visit this group at
>> http://groups.google.com/a/isocpp.org/group/std-proposals/.
>>
>

--=20

---=20
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 e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

.


Author: Douglas Boffey <douglas.boffey@gmail.com>
Date: Tue, 20 Jan 2015 06:52:03 +0000
Raw View
Would anyone be willing to present this at Urbana, please?

On 12/24/14, Douglas Boffey <douglas.boffey@gmail.com> wrote:
>
>
> On Tuesday, 23 December 2014 23:58:51 UTC, Matthew Woehlke wrote:
>>
>> On 2014-12-23 18:32, Matthew Woehlke wrote:
>> > Thinking on it further, it may be useful to implement this (library or
>> > otherwise) in a way that the DEP passed is actually (a reference to?)
>> > the container for the cached parameter, e.g. something like an extende=
d
>> >
>> > std::optional with a std::function (which may be null!) to evaluate th=
e
>> >
>> > parameter. This would simplify passing constant values (just pass an
>> > already-evaluated DEP with a null evaluation thunk, rather than needin=
g
>> >
>> > to overload) and forwarding of DEP's (since it's by reference, just pa=
ss
>> >
>> > the caller's DEP).
>> >
>> > If anything, some of the above considerations I think make a language
>> > change even more interesting; let the compiler sort out when to pass a
>> > thunk rather than making the user decide.
>>
>> I'll also note that I think that, as a language feature, these sorts of
>> questions (can? will?) fall into the implementation details domain,
>> which I consider a good thing.
>>
>> We might want to explicitly mention that a conforming implementation can
>> execute a function taking a DEP with an already-evaluated value rather
>> than a thunk, provided that said evaluation has no observable side
>> effects (and without specifying how an implementation might do such a
>> thing). Note that the choice of "execute" (vs. "call") is intentional,
>> e.g. it would be permitted that an implementation generate multiple
>> versions of a function taking one or more DEP's and choose between them.
>>
>> Added
>
>> --
>> Matthew
>>
>>
> On Wednesday, 24 December 2014 11:41 UTC, Nicola Gigante wrote:
>
> l giorno 23/dic/2014, alle ore 22:48, Douglas Boffey <douglas...@gmail.co=
m>
>
>> ha scritto:
>> > [paper]
>> Apart from a typo in my name (s/Nicole/Nicola), it=E2=80=99s great to se=
e
>> something written finally!
>>
> My sincere apologies... corrected.
>
>
>> A couple of points:
>> - Why restricting the use of variadics? I think anything you can do with
>> one parameter
>> can be done for a parameter pack. I don=E2=80=99t see the benefit of thi=
s
>> restriction, and it also
>> has some use cases like a logging function with a variadic interface
>> instead of a streaming
>> one.
>>
> Lifted
>
>> - If we=E2=80=99re talking about overloading on lazy parameters, should =
=E2=80=98inline=E2=80=99
>> be a modifier like
>> const or volatile, from the grammar point of view? This should make it
>> easy to specify
>> the semantics of cases when you pass inline arguments to other inline
>> parameters,
>> saying that the evaluation of the thunk must happen on a =E2=80=9Cinline=
 to
>> non-inline=E2=80=9D conversion.
>>
>> I'm not sure about this one.
>
>> Bye,
>> Nicola
>
>
>
> --
>
> ---
> 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.
> Visit this group at
> http://groups.google.com/a/isocpp.org/group/std-proposals/.
>

--=20

---=20
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 e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

.