Topic: Pass-by-lambda


Author: Hyman Rosen <hyman.rosen@gmail.com>
Date: Wed, 14 May 2014 13:52:03 -0700 (PDT)
Raw View
------=_Part_666_31729337.1400100723238
Content-Type: text/plain; charset=UTF-8

I propose to allow function parameter declarations to be prefixed with [&]*.
 *Doing so would cause those parameters to be *passed by lambda*. That is,
when the function is called, the argument expression for that parameter is
not evaluated.  Instead, it is wrapped in a 0-parameter
capture-by-reference lambda that returns that expression, and the lambda is
passed to the function.  When the function would access the variable. it
calls the lambda instead and uses its return value (and it may do so any
number of times, including 0).

Among other things, this could be used to finally implement user-defined
*operator&&* and *operator||* with proper short-circuiting:

*class A*

*{    bool is() const;*

*  public:*
*    bool operator&&([&] A other) const { return is() && other.is(); }*
*    bool operator||([&] A other) const { return is() || other.is(); }*
*};*

*A f();*
*A g();*

*void test()*
*{*
*    if (f() && g()) { ... }  **// Calls g() only if f().is()*
    if (f() || g()) { ... }  *// Calls g() only if !f().is()*
*}*

The above code is equivalent to

*class A*

*{    bool is() const;*

*  public:*
*    bool operator&&(A (*other)()) const { return is() && other().is(); }*
*    bool operator||(A (*other)()) const { return is() || other().is(); }*
*};*

*A f();*
*A g();*

*void test()*
*{*
*    if (f().operator&&([&] { return g(); }) { ... }*
    if (f().operator||([&] { return g(); }) { ... }
*}*

Another example:

*template <typename T>*
*void repeat(size_t n, [&] T t) { while (n-- > 0) { t; } }*

*void test()*
*{*
*    int i = 1;*

*    repeat(5, i += 2);*
*    assert(i == 11);*

    repeat(0, i += 2);
    assert(i == 11);
*}*

--

---
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_666_31729337.1400100723238
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">I propose to allow function parameter declarations to be p=
refixed with <font face=3D"courier new, monospace" style=3D"font-weight: bo=
ld;">[&amp;]</font><b style=3D"font-family: arial, sans-serif;">. &nbsp;</b=
><font face=3D"arial, sans-serif">Doing so would cause those parameters to =
be </font><i style=3D"font-family: arial, sans-serif;">passed by lambda</i>=
<font face=3D"arial, sans-serif">. That is, when the function is called, th=
e argument expression for that parameter is not evaluated. &nbsp;Instead, i=
t is wrapped in a 0-parameter capture-by-reference lambda that returns that=
 expression, and the lambda is passed to the function. &nbsp;When the funct=
ion would access</font><font face=3D"arial, sans-serif">&nbsp;the variable.=
 it calls the lambda instead and uses its return value (and it may do so an=
y number of times, including 0).</font><br><br><font face=3D"arial, sans-se=
rif">Among other things, this could be used to finally implement user-defin=
ed </font><b><font face=3D"courier new, monospace">operator&amp;&amp;</font=
></b><font face=3D"arial, sans-serif"> and </font><font face=3D"courier new=
, monospace"><b>operator||</b></font><font face=3D"arial, sans-serif">&nbsp=
;with proper short-circuiting:</font><br><br><font face=3D"courier new, mon=
ospace"><b>class A</b></font><div><font face=3D"courier new, monospace"><b>=
{<br>&nbsp; &nbsp; bool is() const;</b></font></div><div><font face=3D"cour=
ier new, monospace"><b><br></b></font></div><div><font face=3D"courier new,=
 monospace"><b>&nbsp; public:</b></font></div><div><font face=3D"courier ne=
w, monospace"><b>&nbsp; &nbsp; bool operator&amp;&amp;([&amp;] A other) con=
st { return is() &amp;&amp; other.is(); }</b></font></div><div><font face=
=3D"courier new, monospace"><b>&nbsp; &nbsp; bool operator||([&amp;] A othe=
r) const { return is() || other.is(); }</b></font></div><div><font face=3D"=
courier new, monospace"><b>};</b></font></div><div><font face=3D"courier ne=
w, monospace"><b><br></b></font></div><div><font face=3D"courier new, monos=
pace"><b>A f();</b></font></div><div><font face=3D"courier new, monospace">=
<b>A g();</b></font></div><div><font face=3D"courier new, monospace"><b><br=
></b></font></div><div><font face=3D"courier new, monospace"><b>void test()=
</b></font></div><div><font face=3D"courier new, monospace"><b>{</b></font>=
</div><div><b style=3D"font-family: 'courier new', monospace;">&nbsp; &nbsp=
; if (f() &amp;&amp; g()) { ... } &nbsp;</b><i><font face=3D"arial, sans-se=
rif">// Calls </font><b><font face=3D"courier new, monospace">g()</font></b=
><font face=3D"arial, sans-serif"> only if </font><font face=3D"courier new=
, monospace"><b>f().is()</b></font></i></div><div><font face=3D"courier new=
, monospace" style=3D"font-weight: bold;">&nbsp; &nbsp; if (f() || g()) { .=
... } &nbsp;</font><i><font face=3D"arial, sans-serif">// Calls </font><b><f=
ont face=3D"courier new, monospace">g()</font></b><font face=3D"arial, sans=
-serif"> only if </font><font face=3D"courier new, monospace"><b>!f().is()<=
/b></font></i></div><div><font face=3D"courier new, monospace"><b>}</b></fo=
nt></div><div><font face=3D"courier new, monospace"><b><br></b></font></div=
><div><font face=3D"arial, sans-serif">The above code is equivalent to</fon=
t></div><div><font face=3D"arial, sans-serif"><br></font></div><div><font f=
ace=3D"courier new, monospace"><b>class A</b></font><div><font face=3D"cour=
ier new, monospace"><b>{<br>&nbsp; &nbsp; bool is() const;</b></font></div>=
<div><font face=3D"courier new, monospace"><b><br></b></font></div><div><fo=
nt face=3D"courier new, monospace"><b>&nbsp; public:</b></font></div><div><=
font face=3D"courier new, monospace"><b>&nbsp; &nbsp; bool operator&amp;&am=
p;(A (*other)()) const { return is() &amp;&amp; other().is(); }</b></font><=
/div><div><font face=3D"courier new, monospace"><b>&nbsp; &nbsp; bool opera=
tor||(A (*other)()) const { return is() || other().is(); }</b></font></div>=
<div><font face=3D"courier new, monospace"><b>};</b></font></div><div><font=
 face=3D"courier new, monospace"><b><br></b></font></div><div><font face=3D=
"courier new, monospace"><b>A f();</b></font></div><div><font face=3D"couri=
er new, monospace"><b>A g();</b></font></div><div><font face=3D"courier new=
, monospace"><b><br></b></font></div><div><font face=3D"courier new, monosp=
ace"><b>void test()</b></font></div><div><font face=3D"courier new, monospa=
ce"><b>{</b></font></div><div><b style=3D"font-family: 'courier new', monos=
pace;">&nbsp; &nbsp; if (f().operator&amp;&amp;([&amp;] { return g(); }) { =
.... }</b></div><div><font face=3D"courier new, monospace" style=3D"font-wei=
ght: bold;">&nbsp; &nbsp; if (f().operator||([&amp;] { return g(); }) { ...=
 }</font></div><div><font face=3D"courier new, monospace"><b>}</b></font></=
div></div><div><font face=3D"courier new, monospace"><b><br></b></font></di=
v><div><font face=3D"arial, sans-serif">Another example:</font></div><div><=
font face=3D"arial, sans-serif"><br></font></div><div><font face=3D"courier=
 new, monospace"><b>template &lt;typename T&gt;</b></font></div><div><font =
face=3D"courier new, monospace"><b>void repeat(size_t n, [&amp;] T t) { whi=
le (n-- &gt; 0) { t; } }</b></font></div><div><font face=3D"courier new, mo=
nospace"><b><br></b></font></div><div><font face=3D"courier new, monospace"=
><b>void test()</b></font></div><div><font face=3D"courier new, monospace">=
<b>{</b></font></div><div><font face=3D"courier new, monospace"><b>&nbsp; &=
nbsp; int i =3D 1;</b></font></div><div><font face=3D"courier new, monospac=
e"><b><br></b></font></div><div><font face=3D"courier new, monospace"><b>&n=
bsp; &nbsp; repeat(5, i +=3D 2);</b></font></div><div><font face=3D"courier=
 new, monospace"><b>&nbsp; &nbsp; assert(i =3D=3D 11);</b></font></div><div=
><font face=3D"courier new, monospace"><b><br></b></font></div><span style=
=3D"font-family: 'courier new', monospace; font-weight: bold;">&nbsp; &nbsp=
; repeat(0, i +=3D 2);</span><div><span style=3D"font-family: 'courier new'=
, monospace; font-weight: bold;">&nbsp; &nbsp; assert(i =3D=3D 11);</span><=
/div><div><font face=3D"courier new, monospace"><b>}</b></font></div><div><=
font face=3D"arial, sans-serif"><br></font></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_666_31729337.1400100723238--

.


Author: =?UTF-8?Q?David_Rodr=C3=ADguez_Ibeas?= <dibeas@ieee.org>
Date: Wed, 14 May 2014 18:23:54 -0400
Raw View
--001a11c1243cc049bb04f963a28c
Content-Type: text/plain; charset=UTF-8

From a user point of view, I am not too fond of the idea of the lambda
being evaluated on each use inside the function. This is screaming about
well known issues with macros. If the expression that is mapped to the
lambda has any side effects, it would not be visible to the caller how many
times those side effects will be evaluated.

void f([&] int i);
int i = 0;
f(++i);          // What is the value of 'i' here? Cannot be known without
seeing the implementation of 'f'

Additionally if the argument is an rvalue-expression, you would have a
different issue, in code that looks fine from the point of view of the
function:

int accumulate([&] std::vector<int> v) {
    return std::accumulate(v.begin(), v.end(), 0);
}

Without knowing how this will be called, 'v' might be an rvalue-expression,
and 'v.begin()' and 'v.end()' might be iterators into two different
containers. To some extent this could be worked around by carefully
implementing the function:

int accumulate([&] std::vector<int> v) {
    const auto& local = v;
    return std::accumulate(local.begin(), local.end(), 0);
}

To this respect,  it seems more appropriate to require that the compiler
evaluates the lambda at most once if the argument is actually evaluated.
The implementation of 'operator||' in the original code would be
transformed by the compiler into something like:

bool operator||( [&] A a) const {
    if (is()) return true;
    else {
        auto &&__tmp = a(); // evaluation of the lambda only once, and only
if needed
        return __tmp.is();
    }
}

This would break the use case for 'repeat', but I believe this is saner
than supporting 'repeat' at the cost of not knowing how many times it is
going to be evaluated (in other functions) or the possibilities for
mistakes in the implementation of the function assuming that the argument
is an object and not the expression being evaluated every time.

I am not sure how to properly encode const-volatile into the syntax. The
argument is really a callable entity, but it is designed to look like an
object. Should the presence of 'const', 'volatile' or l-/r-value references
affect the callable? (probably not) The result of the expression? I am not
sure how to map that. But that is not the harder problem.

A lower level problem is the fact that stateful lambdas cannot be converted
to regular function pointers, which means that the equivalence relationship
in the original text is broken, and raises the question of what would the
argument to the function really be.  One option is to restrict this to
templates, in which case it will be mapped directly to a lambda generated
on the fly at the place of call for each lambda-argument. But this limits
the use for the 'operator||' and 'operator&&'.

If this needs to be available outside of templates, a vocabulary type that
does type-erasure would be needed. The obvious choice here would be
'std::function<T&&()>' for a type 'T' deduced from the expression, but this
means that more often than not there will be a dynamic allocation per call
to the function (this overhead is not unique to 'std::function' really, it
is rather a side effect of requiring type-erasure).

   David



On Wed, May 14, 2014 at 4:52 PM, Hyman Rosen <hyman.rosen@gmail.com> wrote:

> I propose to allow function parameter declarations to be prefixed with [&]*.
>  *Doing so would cause those parameters to be *passed by lambda*. That
> is, when the function is called, the argument expression for that parameter
> is not evaluated.  Instead, it is wrapped in a 0-parameter
> capture-by-reference lambda that returns that expression, and the lambda is
> passed to the function.  When the function would access the variable. it
> calls the lambda instead and uses its return value (and it may do so any
> number of times, including 0).
>
> Among other things, this could be used to finally implement user-defined
> *operator&&* and *operator||* with proper short-circuiting:
>
> *class A*
>
> *{    bool is() const;*
>
> *  public:*
> *    bool operator&&([&] A other) const { return is() && other.is
> <http://other.is>(); }*
> *    bool operator||([&] A other) const { return is() || other.is
> <http://other.is>(); }*
> *};*
>
> *A f();*
> *A g();*
>
> *void test()*
> *{*
> *    if (f() && g()) { ... }  **// Calls g() only if f().is()*
>     if (f() || g()) { ... }  *// Calls g() only if !f().is()*
> *}*
>
> The above code is equivalent to
>
> *class A*
>
> *{    bool is() const;*
>
> *  public:*
> *    bool operator&&(A (*other)()) const { return is() && other().is(); }*
> *    bool operator||(A (*other)()) const { return is() || other().is(); }*
> *};*
>
> *A f();*
> *A g();*
>
> *void test()*
> *{*
> *    if (f().operator&&([&] { return g(); }) { ... }*
>     if (f().operator||([&] { return g(); }) { ... }
> *}*
>
> Another example:
>
> *template <typename T>*
> *void repeat(size_t n, [&] T t) { while (n-- > 0) { t; } }*
>
> *void test()*
> *{*
> *    int i = 1;*
>
> *    repeat(5, i += 2);*
> *    assert(i == 11);*
>
>     repeat(0, i += 2);
>     assert(i == 11);
> *}*
>
>  --
>
> ---
> 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/.

--001a11c1243cc049bb04f963a28c
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">From a user point of view, I am not too fond of the idea o=
f the lambda being evaluated on each use inside the function. This is screa=
ming about well known issues with macros. If the expression that is mapped =
to the lambda has any side effects, it would not be visible to the caller h=
ow many times those side effects will be evaluated.<br>
<br>void f([&amp;] int i);<br>int i =3D 0;<br>f(++i); =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0// What is the value of &#39;i&#39; here? Cannot be known with=
out seeing the implementation of &#39;f&#39;<br><br>Additionally if the arg=
ument is an rvalue-expression, you would have a different issue, in code th=
at looks fine from the point of view of the function:<br>
<br>int accumulate([&amp;] std::vector&lt;int&gt; v) {<br>=C2=A0 =C2=A0 ret=
urn=C2=A0std::accumulate(v.begin(), v.end(), 0);<br>}<br><br><div>Without k=
nowing how this will be called, &#39;v&#39; might be an rvalue-expression, =
and &#39;v.begin()&#39; and &#39;v.end()&#39; might be iterators into two d=
ifferent containers. To some extent this could be worked around by carefull=
y implementing the function:<br>
<br>int accumulate([&amp;] std::vector&lt;int&gt; v) {<br>=C2=A0 =C2=A0 con=
st auto&amp; local =3D v;<br>=C2=A0 =C2=A0 return std::accumulate(local.beg=
in(), local.end(), 0);<br>}<br><br>To this respect, =C2=A0it seems more app=
ropriate to require that the compiler evaluates the lambda at most once if =
the argument is actually evaluated. The implementation of &#39;operator||&#=
39; in the original code would be transformed by the compiler into somethin=
g like:<br>
<br>bool operator||( [&amp;] A a) const {<br>=C2=A0 =C2=A0 if (is()) return=
 true;<br>=C2=A0 =C2=A0 else {<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 auto &amp;&am=
p;__tmp =3D a(); // evaluation of the lambda only once, and only if needed<=
br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 return __<a href=3D"http://tmp.is">tmp.is</a=
>();<br>
=C2=A0 =C2=A0 }<br>}<br><br>This would break the use case for &#39;repeat&#=
39;, but I believe this is saner than supporting &#39;repeat&#39; at the co=
st of not knowing how many times it is going to be evaluated (in other func=
tions) or the possibilities for mistakes in the implementation of the funct=
ion assuming that the argument is an object and not the expression being ev=
aluated every time.<br>
<br>I am not sure how to properly encode const-volatile into the syntax. Th=
e argument is really a callable entity, but it is designed to look like an =
object. Should the presence of &#39;const&#39;, &#39;volatile&#39; or l-/r-=
value references affect the callable? (probably not) The result of the expr=
ession? I am not sure how to map that. But that is not the harder problem.=
=C2=A0<br>
<br>A lower level problem is the fact that stateful lambdas cannot be conve=
rted to regular function pointers, which means that the equivalence relatio=
nship in the original text is broken, and raises the question of what would=
 the argument to the function really be. =C2=A0One option is to restrict th=
is to templates, in which case it will be mapped directly to a lambda gener=
ated on the fly at the place of call for each lambda-argument. But this lim=
its the use for the &#39;operator||&#39; and &#39;operator&amp;&amp;&#39;.=
=C2=A0<br>
<br>If this needs to be available outside of templates, a vocabulary type t=
hat does type-erasure would be needed. The obvious choice here would be &#3=
9;std::function&lt;T&amp;&amp;()&gt;&#39; for a type &#39;T&#39; deduced fr=
om the expression, but this means that more often than not there will be a =
dynamic allocation per call to the function (this overhead is not unique to=
 &#39;std::function&#39; really, it is rather a side effect of requiring ty=
pe-erasure).<br>
<br>=C2=A0 =C2=A0David<br><br></div></div><div class=3D"gmail_extra"><br><b=
r><div class=3D"gmail_quote">On Wed, May 14, 2014 at 4:52 PM, Hyman Rosen <=
span dir=3D"ltr">&lt;<a href=3D"mailto:hyman.rosen@gmail.com" target=3D"_bl=
ank">hyman.rosen@gmail.com</a>&gt;</span> wrote:<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex"><div dir=3D"ltr">I propose to allow function=
 parameter declarations to be prefixed with <font face=3D"courier new, mono=
space" style=3D"font-weight:bold">[&amp;]</font><b style=3D"font-family:ari=
al,sans-serif">. =C2=A0</b><font face=3D"arial, sans-serif">Doing so would =
cause those parameters to be </font><i style=3D"font-family:arial,sans-seri=
f">passed by lambda</i><font face=3D"arial, sans-serif">. That is, when the=
 function is called, the argument expression for that parameter is not eval=
uated. =C2=A0Instead, it is wrapped in a 0-parameter capture-by-reference l=
ambda that returns that expression, and the lambda is passed to the functio=
n. =C2=A0When the function would access</font><font face=3D"arial, sans-ser=
if">=C2=A0the variable. it calls the lambda instead and uses its return val=
ue (and it may do so any number of times, including 0).</font><br>
<br><font face=3D"arial, sans-serif">Among other things, this could be used=
 to finally implement user-defined </font><b><font face=3D"courier new, mon=
ospace">operator&amp;&amp;</font></b><font face=3D"arial, sans-serif"> and =
</font><font face=3D"courier new, monospace"><b>operator||</b></font><font =
face=3D"arial, sans-serif">=C2=A0with proper short-circuiting:</font><br>
<br><font face=3D"courier new, monospace"><b>class A</b></font><div><font f=
ace=3D"courier new, monospace"><b>{<br>=C2=A0 =C2=A0 bool is() const;</b></=
font></div><div><font face=3D"courier new, monospace"><b><br></b></font></d=
iv><div><font face=3D"courier new, monospace"><b>=C2=A0 public:</b></font><=
/div>
<div><font face=3D"courier new, monospace"><b>=C2=A0 =C2=A0 bool operator&a=
mp;&amp;([&amp;] A other) const { return is() &amp;&amp; <a href=3D"http://=
other.is" target=3D"_blank">other.is</a>(); }</b></font></div><div><font fa=
ce=3D"courier new, monospace"><b>=C2=A0 =C2=A0 bool operator||([&amp;] A ot=
her) const { return is() || <a href=3D"http://other.is" target=3D"_blank">o=
ther.is</a>(); }</b></font></div>
<div><font face=3D"courier new, monospace"><b>};</b></font></div><div><font=
 face=3D"courier new, monospace"><b><br></b></font></div><div><font face=3D=
"courier new, monospace"><b>A f();</b></font></div><div><font face=3D"couri=
er new, monospace"><b>A g();</b></font></div>
<div><font face=3D"courier new, monospace"><b><br></b></font></div><div><fo=
nt face=3D"courier new, monospace"><b>void test()</b></font></div><div><fon=
t face=3D"courier new, monospace"><b>{</b></font></div><div><b style=3D"fon=
t-family:&#39;courier new&#39;,monospace">=C2=A0 =C2=A0 if (f() &amp;&amp; =
g()) { ... } =C2=A0</b><i><font face=3D"arial, sans-serif">// Calls </font>=
<b><font face=3D"courier new, monospace">g()</font></b><font face=3D"arial,=
 sans-serif"> only if </font><font face=3D"courier new, monospace"><b>f().i=
s()</b></font></i></div>
<div><font face=3D"courier new, monospace" style=3D"font-weight:bold">=C2=
=A0 =C2=A0 if (f() || g()) { ... } =C2=A0</font><i><font face=3D"arial, san=
s-serif">// Calls </font><b><font face=3D"courier new, monospace">g()</font=
></b><font face=3D"arial, sans-serif"> only if </font><font face=3D"courier=
 new, monospace"><b>!f().is()</b></font></i></div>
<div><font face=3D"courier new, monospace"><b>}</b></font></div><div><font =
face=3D"courier new, monospace"><b><br></b></font></div><div><font face=3D"=
arial, sans-serif">The above code is equivalent to</font></div><div><font f=
ace=3D"arial, sans-serif"><br>
</font></div><div><font face=3D"courier new, monospace"><b>class A</b></fon=
t><div><font face=3D"courier new, monospace"><b>{<br>=C2=A0 =C2=A0 bool is(=
) const;</b></font></div><div><font face=3D"courier new, monospace"><b><br>=
</b></font></div>
<div><font face=3D"courier new, monospace"><b>=C2=A0 public:</b></font></di=
v><div><font face=3D"courier new, monospace"><b>=C2=A0 =C2=A0 bool operator=
&amp;&amp;(A (*other)()) const { return is() &amp;&amp; other().is(); }</b>=
</font></div><div>
<font face=3D"courier new, monospace"><b>=C2=A0 =C2=A0 bool operator||(A (*=
other)()) const { return is() || other().is(); }</b></font></div><div><font=
 face=3D"courier new, monospace"><b>};</b></font></div><div><font face=3D"c=
ourier new, monospace"><b><br>
</b></font></div><div><font face=3D"courier new, monospace"><b>A f();</b></=
font></div><div><font face=3D"courier new, monospace"><b>A g();</b></font><=
/div><div><font face=3D"courier new, monospace"><b><br></b></font></div><di=
v>
<font face=3D"courier new, monospace"><b>void test()</b></font></div><div><=
font face=3D"courier new, monospace"><b>{</b></font></div><div><b style=3D"=
font-family:&#39;courier new&#39;,monospace">=C2=A0 =C2=A0 if (f().operator=
&amp;&amp;([&amp;] { return g(); }) { ... }</b></div>
<div><font face=3D"courier new, monospace" style=3D"font-weight:bold">=C2=
=A0 =C2=A0 if (f().operator||([&amp;] { return g(); }) { ... }</font></div>=
<div><font face=3D"courier new, monospace"><b>}</b></font></div></div><div>=
<font face=3D"courier new, monospace"><b><br>
</b></font></div><div><font face=3D"arial, sans-serif">Another example:</fo=
nt></div><div><font face=3D"arial, sans-serif"><br></font></div><div><font =
face=3D"courier new, monospace"><b>template &lt;typename T&gt;</b></font></=
div>
<div><font face=3D"courier new, monospace"><b>void repeat(size_t n, [&amp;]=
 T t) { while (n-- &gt; 0) { t; } }</b></font></div><div><font face=3D"cour=
ier new, monospace"><b><br></b></font></div><div><font face=3D"courier new,=
 monospace"><b>void test()</b></font></div>
<div><font face=3D"courier new, monospace"><b>{</b></font></div><div><font =
face=3D"courier new, monospace"><b>=C2=A0 =C2=A0 int i =3D 1;</b></font></d=
iv><div><font face=3D"courier new, monospace"><b><br></b></font></div><div>=
<font face=3D"courier new, monospace"><b>=C2=A0 =C2=A0 repeat(5, i +=3D 2);=
</b></font></div>
<div><font face=3D"courier new, monospace"><b>=C2=A0 =C2=A0 assert(i =3D=3D=
 11);</b></font></div><div><font face=3D"courier new, monospace"><b><br></b=
></font></div><span style=3D"font-family:&#39;courier new&#39;,monospace;fo=
nt-weight:bold">=C2=A0 =C2=A0 repeat(0, i +=3D 2);</span><div>
<span style=3D"font-family:&#39;courier new&#39;,monospace;font-weight:bold=
">=C2=A0 =C2=A0 assert(i =3D=3D 11);</span></div><div><font face=3D"courier=
 new, monospace"><b>}</b></font></div><span class=3D"HOEnZb"><font color=3D=
"#888888"><div><font face=3D"arial, sans-serif"><br>
</font></div></font></span></div><span class=3D"HOEnZb"><font color=3D"#888=
888">

<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" target=3D"_=
blank">std-proposals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br>
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/" target=3D"_blank">http://groups.google.com/a/isocpp.org/gro=
up/std-proposals/</a>.<br>
</font></span></blockquote></div><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 />

--001a11c1243cc049bb04f963a28c--

.


Author: Diggory Blake <diggsey@googlemail.com>
Date: Wed, 14 May 2014 17:29:22 -0700 (PDT)
Raw View
------=_Part_3310_10599051.1400113762069
Content-Type: text/plain; charset=UTF-8

Making them implicit template parameters would give best performance and
maps most closely to the way the compiler generates code for the existing
short-circuit operators.

On Wednesday, 14 May 2014 21:52:03 UTC+1, Hyman Rosen wrote:
>
> I propose to allow function parameter declarations to be prefixed with [&]*.
>  *Doing so would cause those parameters to be *passed by lambda*. That
> is, when the function is called, the argument expression for that parameter
> is not evaluated.  Instead, it is wrapped in a 0-parameter
> capture-by-reference lambda that returns that expression, and the lambda is
> passed to the function.  When the function would access the variable. it
> calls the lambda instead and uses its return value (and it may do so any
> number of times, including 0).
>
> Among other things, this could be used to finally implement user-defined
> *operator&&* and *operator||* with proper short-circuiting:
>
> *class A*
>
> *{    bool is() const;*
>
> *  public:*
> *    bool operator&&([&] A other) const { return is() && other.is
> <http://other.is>(); }*
> *    bool operator||([&] A other) const { return is() || other.is
> <http://other.is>(); }*
> *};*
>
> *A f();*
> *A g();*
>
> *void test()*
> *{*
> *    if (f() && g()) { ... }  **// Calls g() only if f().is()*
>     if (f() || g()) { ... }  *// Calls g() only if !f().is()*
> *}*
>
> The above code is equivalent to
>
> *class A*
>
> *{    bool is() const;*
>
> *  public:*
> *    bool operator&&(A (*other)()) const { return is() && other().is(); }*
> *    bool operator||(A (*other)()) const { return is() || other().is(); }*
> *};*
>
> *A f();*
> *A g();*
>
> *void test()*
> *{*
> *    if (f().operator&&([&] { return g(); }) { ... }*
>     if (f().operator||([&] { return g(); }) { ... }
> *}*
>
> Another example:
>
> *template <typename T>*
> *void repeat(size_t n, [&] T t) { while (n-- > 0) { t; } }*
>
> *void test()*
> *{*
> *    int i = 1;*
>
> *    repeat(5, i += 2);*
> *    assert(i == 11);*
>
>     repeat(0, i += 2);
>     assert(i == 11);
> *}*
>
>

--

---
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_3310_10599051.1400113762069
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Making them implicit template parameters would give best p=
erformance and maps most closely to the way the compiler generates code for=
 the existing short-circuit operators.<br><br>On Wednesday, 14 May 2014 21:=
52:03 UTC+1, Hyman Rosen  wrote:<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">I propose to allow function parameter declarations to be=
 prefixed with <font style=3D"font-weight:bold" face=3D"courier new, monosp=
ace">[&amp;]</font><b style=3D"font-family:arial,sans-serif">. &nbsp;</b><f=
ont face=3D"arial, sans-serif">Doing so would cause those parameters to be =
</font><i style=3D"font-family:arial,sans-serif">passed by lambda</i><font =
face=3D"arial, sans-serif">. That is, when the function is called, the argu=
ment expression for that parameter is not evaluated. &nbsp;Instead, it is w=
rapped in a 0-parameter capture-by-reference lambda that returns that expre=
ssion, and the lambda is passed to the function. &nbsp;When the function wo=
uld access</font><font face=3D"arial, sans-serif">&nbsp;the variable. it ca=
lls the lambda instead and uses its return value (and it may do so any numb=
er of times, including 0).</font><br><br><font face=3D"arial, sans-serif">A=
mong other things, this could be used to finally implement user-defined </f=
ont><b><font face=3D"courier new, monospace">operator&amp;&amp;</font></b><=
font face=3D"arial, sans-serif"> and </font><font face=3D"courier new, mono=
space"><b>operator||</b></font><font face=3D"arial, sans-serif">&nbsp;with =
proper short-circuiting:</font><br><br><font face=3D"courier new, monospace=
"><b>class A</b></font><div><font face=3D"courier new, monospace"><b>{<br>&=
nbsp; &nbsp; bool is() const;</b></font></div><div><font face=3D"courier ne=
w, monospace"><b><br></b></font></div><div><font face=3D"courier new, monos=
pace"><b>&nbsp; public:</b></font></div><div><font face=3D"courier new, mon=
ospace"><b>&nbsp; &nbsp; bool operator&amp;&amp;([&amp;] A other) const { r=
eturn is() &amp;&amp; <a href=3D"http://other.is" target=3D"_blank" onmouse=
down=3D"this.href=3D'http://www.google.com/url?q\75http%3A%2F%2Fother.is\46=
sa\75D\46sntz\0751\46usg\75AFQjCNF4eju-xuoerUmrT8yvX6wjnRDFpw';return true;=
" onclick=3D"this.href=3D'http://www.google.com/url?q\75http%3A%2F%2Fother.=
is\46sa\75D\46sntz\0751\46usg\75AFQjCNF4eju-xuoerUmrT8yvX6wjnRDFpw';return =
true;">other.is</a>(); }</b></font></div><div><font face=3D"courier new, mo=
nospace"><b>&nbsp; &nbsp; bool operator||([&amp;] A other) const { return i=
s() || <a href=3D"http://other.is" target=3D"_blank" onmousedown=3D"this.hr=
ef=3D'http://www.google.com/url?q\75http%3A%2F%2Fother.is\46sa\75D\46sntz\0=
751\46usg\75AFQjCNF4eju-xuoerUmrT8yvX6wjnRDFpw';return true;" onclick=3D"th=
is.href=3D'http://www.google.com/url?q\75http%3A%2F%2Fother.is\46sa\75D\46s=
ntz\0751\46usg\75AFQjCNF4eju-xuoerUmrT8yvX6wjnRDFpw';return true;">other.is=
</a>(); }</b></font></div><div><font face=3D"courier new, monospace"><b>};<=
/b></font></div><div><font face=3D"courier new, monospace"><b><br></b></fon=
t></div><div><font face=3D"courier new, monospace"><b>A f();</b></font></di=
v><div><font face=3D"courier new, monospace"><b>A g();</b></font></div><div=
><font face=3D"courier new, monospace"><b><br></b></font></div><div><font f=
ace=3D"courier new, monospace"><b>void test()</b></font></div><div><font fa=
ce=3D"courier new, monospace"><b>{</b></font></div><div><b style=3D"font-fa=
mily:'courier new',monospace">&nbsp; &nbsp; if (f() &amp;&amp; g()) { ... }=
 &nbsp;</b><i><font face=3D"arial, sans-serif">// Calls </font><b><font fac=
e=3D"courier new, monospace">g()</font></b><font face=3D"arial, sans-serif"=
> only if </font><font face=3D"courier new, monospace"><b>f().is()</b></fon=
t></i></div><div><font style=3D"font-weight:bold" face=3D"courier new, mono=
space">&nbsp; &nbsp; if (f() || g()) { ... } &nbsp;</font><i><font face=3D"=
arial, sans-serif">// Calls </font><b><font face=3D"courier new, monospace"=
>g()</font></b><font face=3D"arial, sans-serif"> only if </font><font face=
=3D"courier new, monospace"><b>!f().is()</b></font></i></div><div><font fac=
e=3D"courier new, monospace"><b>}</b></font></div><div><font face=3D"courie=
r new, monospace"><b><br></b></font></div><div><font face=3D"arial, sans-se=
rif">The above code is equivalent to</font></div><div><font face=3D"arial, =
sans-serif"><br></font></div><div><font face=3D"courier new, monospace"><b>=
class A</b></font><div><font face=3D"courier new, monospace"><b>{<br>&nbsp;=
 &nbsp; bool is() const;</b></font></div><div><font face=3D"courier new, mo=
nospace"><b><br></b></font></div><div><font face=3D"courier new, monospace"=
><b>&nbsp; public:</b></font></div><div><font face=3D"courier new, monospac=
e"><b>&nbsp; &nbsp; bool operator&amp;&amp;(A (*other)()) const { return is=
() &amp;&amp; other().is(); }</b></font></div><div><font face=3D"courier ne=
w, monospace"><b>&nbsp; &nbsp; bool operator||(A (*other)()) const { return=
 is() || other().is(); }</b></font></div><div><font face=3D"courier new, mo=
nospace"><b>};</b></font></div><div><font face=3D"courier new, monospace"><=
b><br></b></font></div><div><font face=3D"courier new, monospace"><b>A f();=
</b></font></div><div><font face=3D"courier new, monospace"><b>A g();</b></=
font></div><div><font face=3D"courier new, monospace"><b><br></b></font></d=
iv><div><font face=3D"courier new, monospace"><b>void test()</b></font></di=
v><div><font face=3D"courier new, monospace"><b>{</b></font></div><div><b s=
tyle=3D"font-family:'courier new',monospace">&nbsp; &nbsp; if (f().operator=
&amp;&amp;([&amp;] { return g(); }) { ... }</b></div><div><font style=3D"fo=
nt-weight:bold" face=3D"courier new, monospace">&nbsp; &nbsp; if (f().opera=
tor||([&amp;] { return g(); }) { ... }</font></div><div><font face=3D"couri=
er new, monospace"><b>}</b></font></div></div><div><font face=3D"courier ne=
w, monospace"><b><br></b></font></div><div><font face=3D"arial, sans-serif"=
>Another example:</font></div><div><font face=3D"arial, sans-serif"><br></f=
ont></div><div><font face=3D"courier new, monospace"><b>template &lt;typena=
me T&gt;</b></font></div><div><font face=3D"courier new, monospace"><b>void=
 repeat(size_t n, [&amp;] T t) { while (n-- &gt; 0) { t; } }</b></font></di=
v><div><font face=3D"courier new, monospace"><b><br></b></font></div><div><=
font face=3D"courier new, monospace"><b>void test()</b></font></div><div><f=
ont face=3D"courier new, monospace"><b>{</b></font></div><div><font face=3D=
"courier new, monospace"><b>&nbsp; &nbsp; int i =3D 1;</b></font></div><div=
><font face=3D"courier new, monospace"><b><br></b></font></div><div><font f=
ace=3D"courier new, monospace"><b>&nbsp; &nbsp; repeat(5, i +=3D 2);</b></f=
ont></div><div><font face=3D"courier new, monospace"><b>&nbsp; &nbsp; asser=
t(i =3D=3D 11);</b></font></div><div><font face=3D"courier new, monospace">=
<b><br></b></font></div><span style=3D"font-family:'courier new',monospace;=
font-weight:bold">&nbsp; &nbsp; repeat(0, i +=3D 2);</span><div><span style=
=3D"font-family:'courier new',monospace;font-weight:bold">&nbsp; &nbsp; ass=
ert(i =3D=3D 11);</span></div><div><font face=3D"courier new, monospace"><b=
>}</b></font></div><div><font face=3D"arial, sans-serif"><br></font></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_3310_10599051.1400113762069--

.


Author: Jeremy Maitin-Shepard <jeremy@jeremyms.com>
Date: Wed, 14 May 2014 23:03:32 -0700 (PDT)
Raw View
------=_Part_297_8707681.1400133812999
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable



On Wednesday, May 14, 2014 3:23:54 PM UTC-7, David Rodr=C3=ADguez Ibeas wro=
te:
>
> From a user point of view, I am not too fond of the idea of the lambda=20
> being evaluated on each use inside the function. This is screaming about=
=20
> well known issues with macros. If the expression that is mapped to the=20
> lambda has any side effects, it would not be visible to the caller how ma=
ny=20
> times those side effects will be evaluated.
>


It seems to me that the function should be allowed to evaluate the argument=
=20
multiple times.  However, to avoid confusion, there should be no implicit=
=20
evaluation: the lambda parameters should have the type of a functor.  To=20
evaluate, the function uses the usual function call syntax.  Thus, it would=
=20
only be syntactic sugar for the call site.

=20

>
>
>
> If this needs to be available outside of templates, a vocabulary type tha=
t=20
> does type-erasure would be needed. The obvious choice here would be=20
> 'std::function<T&&()>' for a type 'T' deduced from the expression, but th=
is=20
> means that more often than not there will be a dynamic allocation per cal=
l=20
> to the function (this overhead is not unique to 'std::function' really, i=
t=20
> is rather a side effect of requiring type-erasure).
>
> Actually, type erasure does not require dynamic allocation if the functio=
n=20
type does not have to be copyable.  There is still the virtual function=20
call overhead, though.  It seems there needs to be a way to specify the=20
true function type of the argument.  Perhaps the type specified in the=20
function signature should be the function type rather than the return value=
=20
of the function.  That would seem to solve the problem nicely.

--=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_297_8707681.1400133812999
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Wednesday, May 14, 2014 3:23:54 PM UTC-7, David=
 Rodr=C3=ADguez Ibeas wrote:<blockquote class=3D"gmail_quote" style=3D"marg=
in: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><d=
iv dir=3D"ltr">From a user point of view, I am not too fond of the idea of =
the lambda being evaluated on each use inside the function. This is screami=
ng about well known issues with macros. If the expression that is mapped to=
 the lambda has any side effects, it would not be visible to the caller how=
 many times those side effects will be evaluated.<br></div></blockquote><di=
v dir=3D"ltr"><br><br>It seems to me that the function should be allowed to=
 evaluate the=20
argument multiple times.&nbsp; However, to avoid confusion, there should be=
=20
no implicit evaluation: the lambda parameters should have the type of a=20
functor.&nbsp; To evaluate, the function uses the usual function call=20
syntax.&nbsp; Thus, it would only be syntactic sugar for the call site.<br>=
</div><div><br>&nbsp;</div><blockquote class=3D"gmail_quote" style=3D"margi=
n: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><di=
v dir=3D"ltr"><br><br><br><div>If this needs to be available outside of tem=
plates, a vocabulary type that does type-erasure would be needed. The obvio=
us choice here would be 'std::function&lt;T&amp;&amp;()&gt;' for a type 'T'=
 deduced from the expression, but this means that more often than not there=
 will be a dynamic allocation per call to the function (this overhead is no=
t unique to 'std::function' really, it is rather a side effect of requiring=
 type-erasure).<br>
<br></div></div></blockquote><div>Actually, type erasure does not require d=
ynamic allocation if the function type does not have to be copyable.&nbsp; =
There is still the virtual function call overhead, though.&nbsp; It seems t=
here needs to be a way to specify the true function type of the argument.&n=
bsp; Perhaps the type specified in the function signature should be the fun=
ction type rather than the return value of the function.&nbsp; That would s=
eem to solve the problem nicely.<br></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_297_8707681.1400133812999--

.


Author: Nevin Liber <nevin@eviloverlord.com>
Date: Thu, 15 May 2014 12:55:51 -0500
Raw View
--f46d0435c0046ec80a04f97404bf
Content-Type: text/plain; charset=UTF-8

On 14 May 2014 15:52, Hyman Rosen <hyman.rosen@gmail.com> wrote:

> I propose to allow function parameter declarations to be prefixed with [&]*.
>  *Doing so would cause those parameters to be *passed by lambda*. That
> is, when the function is called, the argument expression for that parameter
> is not evaluated.  Instead, it is wrapped in a 0-parameter
> capture-by-reference lambda that returns that expression, and the lambda is
> passed to the function.  When the function would access the variable. it
> calls the lambda instead and uses its return value (and it may do so any
> number of times, including 0).
>
> *template <typename T>*
> *void repeat(size_t n, [&] T t) { while (n-- > 0) { t; } }*
>
> *void test()*
> *{*
> *    int i = 1;*
>
> *    repeat(5, i += 2);*
> *    assert(i == 11);*
>
>     repeat(0, i += 2);
>     assert(i == 11);
> *}*
>

As I understand it, this is just syntactic sugar for:

*template <typename F>*
*void repeat(size_t n, F const& f) { while (n-- > 0) { f(); } }*

*void test()*
*{*
*    int i = 1;*

*    repeat(5, [&]{i += 2;});*
*    assert(i == 11);*

    repeat(0, [&]{i += 2;});
    assert(i == 11);
*}*

 The latter is certainly more flexible (I don't have to use lambdas; I
don't have to capture by reference, etc.) than your proposal.

And as has already been pointed out, you really have to understand the
callee to know what will happen to the caller's variables, especially with
respect to exceptions being thrown.  That being said, it probably isn't
that much worse than passing by non-const reference (which is why many of
us prefer to return by value most of the time instead of passing in
something to be modified).

Other than the short circuit case, what are the other compelling use cases?
--
 Nevin ":-)" Liber  <mailto:nevin@eviloverlord.com>  (847) 691-1404

--

---
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/.

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

<div dir=3D"ltr">On 14 May 2014 15:52, Hyman Rosen <span dir=3D"ltr">&lt;<a=
 href=3D"mailto:hyman.rosen@gmail.com" target=3D"_blank">hyman.rosen@gmail.=
com</a>&gt;</span> wrote:<br><div class=3D"gmail_extra"><div class=3D"gmail=
_quote"><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">

<div dir=3D"ltr">I propose to allow function parameter declarations to be p=
refixed with <font face=3D"courier new, monospace" style=3D"font-weight:bol=
d">[&amp;]</font><b style=3D"font-family:arial,sans-serif">. =C2=A0</b><fon=
t face=3D"arial, sans-serif">Doing so would cause those parameters to be </=
font><i style=3D"font-family:arial,sans-serif">passed by lambda</i><font fa=
ce=3D"arial, sans-serif">. That is, when the function is called, the argume=
nt expression for that parameter is not evaluated. =C2=A0Instead, it is wra=
pped in a 0-parameter capture-by-reference lambda that returns that express=
ion, and the lambda is passed to the function. =C2=A0When the function woul=
d access</font><font face=3D"arial, sans-serif">=C2=A0the variable. it call=
s the lambda instead and uses its return value (and it may do so any number=
 of times, including 0).</font><br>

<br><div><font face=3D"courier new, monospace"><b>template &lt;typename T&g=
t;</b></font></div><div><font face=3D"courier new, monospace"><b>void repea=
t(size_t n, [&amp;] T t) { while (n-- &gt; 0) { t; } }</b></font></div><div=
>

<font face=3D"courier new, monospace"><b><br></b></font></div><div><font fa=
ce=3D"courier new, monospace"><b>void test()</b></font></div><div><font fac=
e=3D"courier new, monospace"><b>{</b></font></div><div><font face=3D"courie=
r new, monospace"><b>=C2=A0 =C2=A0 int i =3D 1;</b></font></div>

<div><font face=3D"courier new, monospace"><b><br></b></font></div><div><fo=
nt face=3D"courier new, monospace"><b>=C2=A0 =C2=A0 repeat(5, i +=3D 2);</b=
></font></div><div><font face=3D"courier new, monospace"><b>=C2=A0 =C2=A0 a=
ssert(i =3D=3D 11);</b></font></div>

<div><font face=3D"courier new, monospace"><b><br></b></font></div><span st=
yle=3D"font-family:&#39;courier new&#39;,monospace;font-weight:bold">=C2=A0=
 =C2=A0 repeat(0, i +=3D 2);</span><div><span style=3D"font-family:&#39;cou=
rier new&#39;,monospace;font-weight:bold">=C2=A0 =C2=A0 assert(i =3D=3D 11)=
;</span></div>

<div><font face=3D"courier new, monospace"><b>}</b></font></div></div></blo=
ckquote><div><br></div><div>As I understand it, this is just syntactic suga=
r for:</div><div><br></div><div><b style=3D"font-family:&#39;courier new&#3=
9;,monospace">template &lt;typename F&gt;</b><br>

<b style=3D"font-family:&#39;courier new&#39;,monospace">void repeat(size_t=
 n, F const&amp; f) { while (n-- &gt; 0) { f(); } }</b><br><font face=3D"co=
urier new, monospace"><b><br></b></font><b style=3D"font-family:&#39;courie=
r new&#39;,monospace">void test()</b><br>

<b style=3D"font-family:&#39;courier new&#39;,monospace">{</b><br><b style=
=3D"font-family:&#39;courier new&#39;,monospace">=C2=A0 =C2=A0 int i =3D 1;=
</b><br><font face=3D"courier new, monospace"><b><br></b></font><b style=3D=
"font-family:&#39;courier new&#39;,monospace">=C2=A0 =C2=A0 repeat(5, [&amp=
;]{i +=3D 2;});</b><br>

<b style=3D"font-family:&#39;courier new&#39;,monospace">=C2=A0 =C2=A0 asse=
rt(i =3D=3D 11);</b><br><font face=3D"courier new, monospace"><b><br></b></=
font><span style=3D"font-family:&#39;courier new&#39;,monospace;font-weight=
:bold">=C2=A0 =C2=A0 repeat(0, [&amp;]{i +=3D 2;});</span><br>

<span style=3D"font-family:&#39;courier new&#39;,monospace;font-weight:bold=
">=C2=A0 =C2=A0 assert(i =3D=3D 11);</span><br><b style=3D"font-family:&#39=
;courier new&#39;,monospace">}</b></div><div><font face=3D"courier new, mon=
ospace"><b><br>
</b></font></div>
<div><div><div><div>The latter is certainly more flexible (I don&#39;t have=
 to use lambdas; I don&#39;t have to capture by reference, etc.) than your =
proposal. =C2=A0</div><div><br></div><div>And as has already been pointed o=
ut, you really have to understand the callee to know what will happen to th=
e caller&#39;s variables, especially with respect to exceptions being throw=
n. =C2=A0That being said, it probably isn&#39;t that much worse than passin=
g by non-const reference (which is why many of us prefer to return by value=
 most of the time instead of passing in something to be modified).</div>

<div><br></div><div>Other than the short circuit case, what are the other c=
ompelling use cases?</div></div></div></div></div>-- <br>=C2=A0Nevin &quot;=
:-)&quot; Liber=C2=A0 &lt;mailto:<a href=3D"mailto:nevin@eviloverlord.com" =
target=3D"_blank">nevin@eviloverlord.com</a>&gt;=C2=A0 (847) 691-1404
</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 />

--f46d0435c0046ec80a04f97404bf--

.


Author: Nevin Liber <nevin@eviloverlord.com>
Date: Thu, 15 May 2014 12:59:21 -0500
Raw View
--047d7bfcebc6e8505404f9741015
Content-Type: text/plain; charset=UTF-8

On 15 May 2014 01:03, Jeremy Maitin-Shepard <jeremy@jeremyms.com> wrote:

> Actually, type erasure does not require dynamic allocation if the function
> type does not have to be copyable.
>

Not true.  The only way it does not require dynamic allocation is if you
know all the types being erased (in which case you can just use something
like Boost.Variant).  How else can you calculate at compile time the
largest size the type erased object needs to be to hold all possible erased
types?
--
 Nevin ":-)" Liber  <mailto:nevin@eviloverlord.com>  (847) 691-1404

--

---
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/.

--047d7bfcebc6e8505404f9741015
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On 15 May 2014 01:03, Jeremy Maitin-Shepard <span dir=3D"l=
tr">&lt;<a href=3D"mailto:jeremy@jeremyms.com" target=3D"_blank">jeremy@jer=
emyms.com</a>&gt;</span> wrote:<br><div class=3D"gmail_extra"><div class=3D=
"gmail_quote">

<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div class=3D"">Actually, t=
ype erasure does not require dynamic allocation if the function type does n=
ot have to be copyable.=C2=A0</div>

</div></blockquote><div><br></div><div>Not true. =C2=A0The only way it does=
 not require dynamic allocation is if you know all the types being erased (=
in which case you can just use something like Boost.Variant). =C2=A0How els=
e can you calculate at compile time the largest size the type erased object=
 needs to be to hold all possible erased types?</div>

</div>-- <br>=C2=A0Nevin &quot;:-)&quot; Liber=C2=A0 &lt;mailto:<a href=3D"=
mailto:nevin@eviloverlord.com" target=3D"_blank">nevin@eviloverlord.com</a>=
&gt;=C2=A0 (847) 691-1404
</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 />

--047d7bfcebc6e8505404f9741015--

.


Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Thu, 15 May 2014 21:00:40 +0300
Raw View
On 15 May 2014 20:55, Nevin Liber <nevin@eviloverlord.com> wrote:
> As I understand it, this is just syntactic sugar for:
> template <typename F>
> void repeat(size_t n, F const& f) { while (n-- > 0) { f(); } }
> The latter is certainly more flexible (I don't have to use lambdas; I don't
> have to capture by reference, etc.) than your proposal.

Nitpick-time! :) You can't use that with a mutable lambda that captures this. ;)

> And as has already been pointed out, you really have to understand the
> callee to know what will happen to the caller's variables, especially with
> respect to exceptions being thrown.  That being said, it probably isn't that
> much worse than passing by non-const reference (which is why many of us
> prefer to return by value most of the time instead of passing in something
> to be modified).
>
> Other than the short circuit case, what are the other compelling use cases?


I have my doubts whether allowing short-circuiting in user-defined logical
operators _is_ a compelling use case.

--

---
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: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Thu, 15 May 2014 21:08:27 +0300
Raw View
On 15 May 2014 21:00, Ville Voutilainen <ville.voutilainen@gmail.com> wrote:
> Nitpick-time! :) You can't use that with a mutable lambda that captures this. ;)

Or actually with any capturing mutable lambda...

--

---
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: Jeremy Maitin-Shepard <jeremy@jeremyms.com>
Date: Thu, 15 May 2014 11:24:45 -0700
Raw View
--f46d0435c0045adade04f9746963
Content-Type: text/plain; charset=UTF-8

On Thu, May 15, 2014 at 10:59 AM, Nevin Liber <nevin@eviloverlord.com>wrote:

> On 15 May 2014 01:03, Jeremy Maitin-Shepard <jeremy@jeremyms.com> wrote:
>
>> Actually, type erasure does not require dynamic allocation if the
>> function type does not have to be copyable.
>>
>
> Not true.  The only way it does not require dynamic allocation is if you
> know all the types being erased (in which case you can just use something
> like Boost.Variant).  How else can you calculate at compile time the
> largest size the type erased object needs to be to hold all possible erased
> types?
>
> The functor can live in the stack frame of the caller (or elsewhere).  The
caller just supplies a pointer/reference to the functor.  If we assume that
the functor is not copyable, then the callee does not need to know how to
copy the functor or even its size.  The functor (possibly via a wrapper)
inherits from a base with a virtual operator(), or the caller also supplies
a function pointer for invoking the functor.

This is all easily implementable via a function_ref type which would be
safe for use as a function parameter type but which could easily result in
dangling references if used for other purposes.  Possibly it would be a
good addition to the standard library as a way to avoid the copying and
memory allocation of std::function in cases where value semantics are not
required.

--

---
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/.

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

<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On T=
hu, May 15, 2014 at 10:59 AM, Nevin Liber <span dir=3D"ltr">&lt;<a href=3D"=
mailto:nevin@eviloverlord.com" target=3D"_blank">nevin@eviloverlord.com</a>=
&gt;</span> wrote:<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-=
left:1px solid rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr"><div cla=
ss=3D"">On 15 May 2014 01:03, Jeremy Maitin-Shepard <span dir=3D"ltr">&lt;<=
a href=3D"mailto:jeremy@jeremyms.com" target=3D"_blank">jeremy@jeremyms.com=
</a>&gt;</span> wrote:<br>
</div><div class=3D"gmail_extra"><div class=3D"gmail_quote"><div class=3D""=
>

<blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-=
left:1px solid rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr"><div>Act=
ually, type erasure does not require dynamic allocation if the function typ=
e does not have to be copyable.=C2=A0</div>


</div></blockquote><div><br></div></div><div>Not true. =C2=A0The only way i=
t does not require dynamic allocation is if you know all the types being er=
ased (in which case you can just use something like Boost.Variant). =C2=A0H=
ow else can you calculate at compile time the largest size the type erased =
object needs to be to hold all possible erased types?</div>


</div><br></div></div></blockquote></div>The functor can live in the stack =
frame of the caller (or elsewhere).=C2=A0 The caller just supplies a pointe=
r/reference to the functor.=C2=A0 If we assume that the functor is not copy=
able, then the callee does not=20
need to know how to copy the functor or even its size.=C2=A0 The functor (p=
ossibly via a wrapper) inherits from a base with a virtual operator(), or t=
he caller also supplies a function pointer for invoking the functor.<br><br=
>
</div><div class=3D"gmail_extra">This is all easily implementable via a fun=
ction_ref<b> </b>type which would be safe for use as a function parameter t=
ype but which could easily result in dangling references if used for other =
purposes.=C2=A0 Possibly it would be a good addition to the standard librar=
y as a way to avoid the copying and memory allocation of std::function in c=
ases where value semantics are not required.<br>
</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 />

--f46d0435c0045adade04f9746963--

.


Author: =?UTF-8?Q?David_Rodr=C3=ADguez_Ibeas?= <dibeas@ieee.org>
Date: Thu, 15 May 2014 14:39:46 -0400
Raw View
--001a11c1317c119d0f04f9749f56
Content-Type: text/plain; charset=UTF-8

This is orthogonal to the thread, but you got me interested:

On Thu, May 15, 2014 at 2:24 PM, Jeremy Maitin-Shepard
<jeremy@jeremyms.com>wrote:

>
> This is all easily implementable via a function_ref type which would be
> safe for use as a function parameter type but which could easily result in
> dangling references if used for other purposes.  Possibly it would be a
> good addition to the standard library as a way to avoid the copying and
> memory allocation of std::function in cases where value semantics are not
> required.
>
> Can you not do this with 'std::ref' now?

--

---
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/.

--001a11c1317c119d0f04f9749f56
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">This is orthogonal to the thread, but you got me intereste=
d:<div class=3D"gmail_extra"><br><div class=3D"gmail_quote">On Thu, May 15,=
 2014 at 2:24 PM, Jeremy Maitin-Shepard <span dir=3D"ltr">&lt;<a href=3D"ma=
ilto:jeremy@jeremyms.com" target=3D"_blank">jeremy@jeremyms.com</a>&gt;</sp=
an> wrote:<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div class=3D"gmail_extra">=
<div class=3D""><div class=3D"gmail_quote"><br></div></div>
</div><div class=3D"gmail_extra">This is all easily implementable via a fun=
ction_ref<b> </b>type which would be safe for use as a function parameter t=
ype but which could easily result in dangling references if used for other =
purposes.=C2=A0 Possibly it would be a good addition to the standard librar=
y as a way to avoid the copying and memory allocation of std::function in c=
ases where value semantics are not required.<br>

</div></div><div class=3D"HOEnZb"><div class=3D"h5">

<p></p></div></div></blockquote></div>Can you not do this with &#39;std::re=
f&#39; now?</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 />

--001a11c1317c119d0f04f9749f56--

.


Author: Diggory Blake <diggsey@googlemail.com>
Date: Thu, 15 May 2014 11:41:12 -0700 (PDT)
Raw View
------=_Part_3229_24371475.1400179273036
Content-Type: text/plain; charset=UTF-8

On Thursday, 15 May 2014 19:24:45 UTC+1, Jeremy Maitin-Shepard wrote:
>
> On Thu, May 15, 2014 at 10:59 AM, Nevin Liber <ne...@eviloverlord.com<javascript:>
> > wrote:
>
>> On 15 May 2014 01:03, Jeremy Maitin-Shepard <jer...@jeremyms.com<javascript:>
>> > wrote:
>>
>>> Actually, type erasure does not require dynamic allocation if the
>>> function type does not have to be copyable.
>>>
>>
>> Not true.  The only way it does not require dynamic allocation is if you
>> know all the types being erased (in which case you can just use something
>> like Boost.Variant).  How else can you calculate at compile time the
>> largest size the type erased object needs to be to hold all possible erased
>> types?
>>
>> The functor can live in the stack frame of the caller (or elsewhere).
> The caller just supplies a pointer/reference to the functor.  If we assume
> that the functor is not copyable, then the callee does not need to know how
> to copy the functor or even its size.  The functor (possibly via a wrapper)
> inherits from a base with a virtual operator(), or the caller also supplies
> a function pointer for invoking the functor.
>
> This is all easily implementable via a function_ref type which would be
> safe for use as a function parameter type but which could easily result in
> dangling references if used for other purposes.  Possibly it would be a
> good addition to the standard library as a way to avoid the copying and
> memory allocation of std::function in cases where value semantics are not
> required.
>

You can't put it on the stack because the lambda may be used after the
function returns, putting it anywhere else requires an allocation (it can't
be static). There is the special case where the lambda will never be used
outside the function, in that case you could add a constructor to
std::function which would allow this:

auto f = <some lambda>;
std::function g(std::ref(f));

In this case it's clear that returning 'g' would be an error, but it can
still be used within the scope without a single allocation.

Having said that, you might just be able to do this:
auto f = <some lambda>;
std::function g(&f);

Although I'm not sure if the call operator would work properly though an
indirection, I suspect that the fact that it does so on function pointers
is just a special case.




--

---
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_3229_24371475.1400179273036
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Thursday, 15 May 2014 19:24:45 UTC+1, Jeremy Maitin-She=
pard  wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-lef=
t: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><=
div><div class=3D"gmail_quote">On Thu, May 15, 2014 at 10:59 AM, Nevin Libe=
r <span dir=3D"ltr">&lt;<a href=3D"javascript:" target=3D"_blank" gdf-obfus=
cated-mailto=3D"IMyRrUyTxrgJ" onmousedown=3D"this.href=3D'javascript:';retu=
rn true;" onclick=3D"this.href=3D'javascript:';return true;">ne...@evilover=
lord.com</a>&gt;</span> wrote:<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-=
left:1px solid rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr"><div>On =
15 May 2014 01:03, Jeremy Maitin-Shepard <span dir=3D"ltr">&lt;<a href=3D"j=
avascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"IMyRrUyTxrgJ" onmous=
edown=3D"this.href=3D'javascript:';return true;" onclick=3D"this.href=3D'ja=
vascript:';return true;">jer...@jeremyms.com</a>&gt;</span> wrote:<br>
</div><div><div class=3D"gmail_quote"><div>

<blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-=
left:1px solid rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr"><div>Act=
ually, type erasure does not require dynamic allocation if the function typ=
e does not have to be copyable.&nbsp;</div>


</div></blockquote><div><br></div></div><div>Not true. &nbsp;The only way i=
t does not require dynamic allocation is if you know all the types being er=
ased (in which case you can just use something like Boost.Variant). &nbsp;H=
ow else can you calculate at compile time the largest size the type erased =
object needs to be to hold all possible erased types?</div>


</div><br></div></div></blockquote></div>The functor can live in the stack =
frame of the caller (or elsewhere).&nbsp; The caller just supplies a pointe=
r/reference to the functor.&nbsp; If we assume that the functor is not copy=
able, then the callee does not=20
need to know how to copy the functor or even its size.&nbsp; The functor (p=
ossibly via a wrapper) inherits from a base with a virtual operator(), or t=
he caller also supplies a function pointer for invoking the functor.<br><br=
>
</div><div>This is all easily implementable via a function_ref<b> </b>type =
which would be safe for use as a function parameter type but which could ea=
sily result in dangling references if used for other purposes.&nbsp; Possib=
ly it would be a good addition to the standard library as a way to avoid th=
e copying and memory allocation of std::function in cases where value seman=
tics are not required.<br></div></div></blockquote><div><br>You can't put i=
t on the stack because the lambda may be used after the function returns, p=
utting it anywhere else requires an allocation (it can't be static). There =
is the special case where the lambda will never be used outside the functio=
n, in that case you could add a constructor to std::function which would al=
low this:<br><br><div class=3D"prettyprint" style=3D"background-color: rgb(=
250, 250, 250); border-color: rgb(187, 187, 187); border-style: solid; bord=
er-width: 1px; word-wrap: break-word;"><code class=3D"prettyprint"><div cla=
ss=3D"subprettyprint"><span style=3D"color: #008;" class=3D"styled-by-prett=
ify">auto</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> =
f </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">some </span><span style=3D"c=
olor: #008;" class=3D"styled-by-prettify">lambda</span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">&gt;;</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"><br>std</span><span style=3D"color: #660;"=
 class=3D"styled-by-prettify">::</span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">function</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> g</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify">std</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
::</span><span style=3D"color: #008;" class=3D"styled-by-prettify">ref</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify">f</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">));</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"><br></span></div></code></div><br>In thi=
s case it's clear that returning 'g' would be an error, but it can still be=
 used within the scope without a single allocation.<br><br>Having said that=
, you might just be able to do this:<br><div class=3D"prettyprint" style=3D=
"background-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187); bo=
rder-style: solid; 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">auto</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> f </span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">=3D</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: #000;" class=3D"styled-by-prettify">some =
</span><span style=3D"color: #008;" class=3D"styled-by-prettify">lambda</sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">&gt;;</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"><br>std</span><span=
 style=3D"color: #660;" class=3D"styled-by-prettify">::</span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">function</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> g</span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">(&amp;</span><span style=3D"color: #=
000;" 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"><br></span></div></code></div><br>Although I'm not sure i=
f the call operator would work properly though an indirection, I suspect th=
at the fact that it does so on function pointers is just a special case.<br=
><br><br><br><br></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_3229_24371475.1400179273036--

.


Author: Nevin Liber <nevin@eviloverlord.com>
Date: Thu, 15 May 2014 13:41:01 -0500
Raw View
--047d7ba97a88e9db9604f974a574
Content-Type: text/plain; charset=UTF-8

On 15 May 2014 13:24, Jeremy Maitin-Shepard <jeremy@jeremyms.com> wrote:

> On Thu, May 15, 2014 at 10:59 AM, Nevin Liber <nevin@eviloverlord.com>wrote:
>
>> On 15 May 2014 01:03, Jeremy Maitin-Shepard <jeremy@jeremyms.com> wrote:
>>
>>> Actually, type erasure does not require dynamic allocation if the
>>> function type does not have to be copyable.
>>>
>>
>> Not true.  The only way it does not require dynamic allocation is if you
>> know all the types being erased (in which case you can just use something
>> like Boost.Variant).  How else can you calculate at compile time the
>> largest size the type erased object needs to be to hold all possible erased
>> types?
>>
>> The functor can live in the stack frame of the caller (or elsewhere).
> The caller just supplies a pointer/reference to the functor.  If we assume
> that the functor is not copyable, then the callee does not need to know how
> to copy the functor or even its size.  The functor (possibly via a wrapper)
> inherits from a base with a virtual operator(), or the caller also supplies
> a function pointer for invoking the functor.
>
> This is all easily implementable via a function_ref type which would be
> safe for use as a function parameter type but which could easily result in
> dangling references if used for other purposes.  Possibly it would be a
> good addition to the standard library as a way to avoid the copying and
> memory allocation of std::function in cases where value semantics are not
> required.
>
> --
>
> ---
> 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/.
>



--
 Nevin ":-)" Liber  <mailto:nevin@eviloverlord.com>  (847) 691-1404

--

---
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/.

--047d7ba97a88e9db9604f974a574
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On 15 May 2014 13:24, Jeremy Maitin-Shepard <span dir=3D"l=
tr">&lt;<a href=3D"mailto:jeremy@jeremyms.com" target=3D"_blank">jeremy@jer=
emyms.com</a>&gt;</span> wrote:<br><div class=3D"gmail_extra"><div class=3D=
"gmail_quote">


<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div class=3D"gmail_extra">=
<div><div class=3D"gmail_quote">On Thu, May 15, 2014 at 10:59 AM, Nevin Lib=
er <span dir=3D"ltr">&lt;<a href=3D"mailto:nevin@eviloverlord.com" target=
=3D"_blank">nevin@eviloverlord.com</a>&gt;</span> wrote:<br>



<blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-=
left:1px solid rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr"><div>On =
15 May 2014 01:03, Jeremy Maitin-Shepard <span dir=3D"ltr">&lt;<a href=3D"m=
ailto:jeremy@jeremyms.com" target=3D"_blank">jeremy@jeremyms.com</a>&gt;</s=
pan> wrote:<br>



</div><div class=3D"gmail_extra"><div class=3D"gmail_quote"><div>

<blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-=
left:1px solid rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr"><div>Act=
ually, type erasure does not require dynamic allocation if the function typ=
e does not have to be copyable.=C2=A0</div>





</div></blockquote><div><br></div></div><div>Not true. =C2=A0The only way i=
t does not require dynamic allocation is if you know all the types being er=
ased (in which case you can just use something like Boost.Variant). =C2=A0H=
ow else can you calculate at compile time the largest size the type erased =
object needs to be to hold all possible erased types?</div>





</div><br></div></div></blockquote></div></div>The functor can live in the =
stack frame of the caller (or elsewhere).=C2=A0 The caller just supplies a =
pointer/reference to the functor.=C2=A0 If we assume that the functor is no=
t copyable, then the callee does not=20
need to know how to copy the functor or even its size.=C2=A0 The functor (p=
ossibly via a wrapper) inherits from a base with a virtual operator(), or t=
he caller also supplies a function pointer for invoking the functor.<br><br=
>



</div><div class=3D"gmail_extra">This is all easily implementable via a fun=
ction_ref<b> </b>type which would be safe for use as a function parameter t=
ype but which could easily result in dangling references if used for other =
purposes.=C2=A0 Possibly it would be a good addition to the standard librar=
y as a way to avoid the copying and memory allocation of std::function in c=
ases where value semantics are not required.<br>



</div></div><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" target=3D"_=
blank">std-proposals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br>
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/" target=3D"_blank">http://groups.google.com/a/isocpp.org/gro=
up/std-proposals/</a>.<br>
</div></div></blockquote></div><br><br clear=3D"all"><div><br></div>-- <br>=
=C2=A0Nevin &quot;:-)&quot; Liber=C2=A0 &lt;mailto:<a href=3D"mailto:nevin@=
eviloverlord.com" target=3D"_blank">nevin@eviloverlord.com</a>&gt;=C2=A0 <a=
 href=3D"tel:%28847%29%20691-1404" value=3D"+18476911404" target=3D"_blank"=
>(847) 691-1404</a>
</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 />

--047d7ba97a88e9db9604f974a574--

.


Author: Jeremy Maitin-Shepard <jeremy@jeremyms.com>
Date: Thu, 15 May 2014 11:59:43 -0700
Raw View
--f46d044288ca66acff04f974e635
Content-Type: text/plain; charset=UTF-8

On Thu, May 15, 2014 at 11:41 AM, Diggory Blake <diggsey@googlemail.com>wrote:

>
> You can't put it on the stack because the lambda may be used after the
> function returns, putting it anywhere else requires an allocation (it can't
> be static). There is the special case where the lambda will never be used
> outside the function, in that case you could add a constructor to
> std::function which would allow this:
>
> auto f = <some lambda>;
> std::function g(std::ref(f));
>
> In this case it's clear that returning 'g' would be an error, but it can
> still be used within the scope without a single allocation.
>

You have a good point.  Assuming a small buffer optimization, using
std::ref with std::function achieves the same thing as the hypothetical
function_ref.  However, a function_ref that can be constructed from an
rvalue would still be useful, as it would allow you to do:

void foo(function_ref<void ()> x);

foo([&] { /* ... */ });

instead of the less convenient

void foo(std::function<void ()> x);
auto f = [&] { /* ... */ };
foo(std::ref(f));

--

---
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/.

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

<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On T=
hu, May 15, 2014 at 11:41 AM, Diggory Blake <span dir=3D"ltr">&lt;<a href=
=3D"mailto:diggsey@googlemail.com" target=3D"_blank">diggsey@googlemail.com=
</a>&gt;</span> wrote:<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex"><div dir=3D"ltr"><br><div>You can&#39;t put =
it on the stack because the lambda may be used after the function returns, =
putting it anywhere else requires an allocation (it can&#39;t be static). T=
here is the special case where the lambda will never be used outside the fu=
nction, in that case you could add a constructor to std::function which wou=
ld allow this:<br>
<br><div style=3D"background-color:rgb(250,250,250);border-color:rgb(187,18=
7,187);border-style:solid;border-width:1px;word-wrap:break-word"><code><div=
><span style=3D"color:#008">auto</span><span style=3D"color:#000"> f </span=
><span style=3D"color:#660">=3D</span><span style=3D"color:#000"> </span><s=
pan style=3D"color:#660">&lt;</span><span style=3D"color:#000">some </span>=
<span style=3D"color:#008">lambda</span><span style=3D"color:#660">&gt;;</s=
pan><span style=3D"color:#000"><br>
std</span><span style=3D"color:#660">::</span><span style=3D"color:#008">fu=
nction</span><span style=3D"color:#000"> g</span><span style=3D"color:#660"=
>(</span><span style=3D"color:#000">std</span><span style=3D"color:#660">::=
</span><span style=3D"color:#008">ref</span><span style=3D"color:#660">(</s=
pan><span style=3D"color:#000">f</span><span style=3D"color:#660">));</span=
><span style=3D"color:#000"><br>
</span></div></code></div><br>In this case it&#39;s clear that returning &#=
39;g&#39; would be an error, but it can still be used within the scope with=
out a single allocation.<br></div></div></blockquote><div><br></div><div>
You have a good point.=C2=A0 Assuming a small buffer optimization, using st=
d::ref with std::function achieves the same thing as the hypothetical funct=
ion_ref.=C2=A0 However, a function_ref that can be constructed from an rval=
ue would still be useful, as it would allow you to do:<br>
<br></div><div>void foo(function_ref&lt;void ()&gt; x);<br><br></div><div>f=
oo([&amp;] { /* ... */ });<br><br></div><div>instead of the less convenient=
<br><br></div><div>void foo(std::function&lt;void ()&gt; x);<br></div><div>
auto f =3D [&amp;] { /* ... */ };<br></div><div>foo(std::ref(f));<br></div>=
</div></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 />

--f46d044288ca66acff04f974e635--

.


Author: Nicola Gigante <nicola.gigante@gmail.com>
Date: Thu, 15 May 2014 21:17:24 +0200
Raw View
Il giorno 14/mag/2014, alle ore 22:52, Hyman Rosen <hyman.rosen@gmail.com> =
ha scritto:

> I propose to allow function parameter declarations to be prefixed with [&=
].  Doing so would cause those parameters to be passed by lambda. That is, =
when the function is called, the argument expression for that parameter is =
not evaluated.  Instead, it is wrapped in a 0-parameter capture-by-referenc=
e lambda that returns that expression, and the lambda is passed to the func=
tion.  When the function would access the variable. it calls the lambda ins=
tead and uses its return value (and it may do so any number of times, inclu=
ding 0).
>=20
> Among other things, this could be used to finally implement user-defined =
operator&& and operator|| with proper short-circuiting:
>=20
> class A
> {
>     bool is() const;
>=20
>   public:
>     bool operator&&([&] A other) const { return is() && other.is(); }
>     bool operator||([&] A other) const { return is() || other.is(); }
> };
>=20
> A f();
> A g();
>=20
> void test()
> {
>     if (f() && g()) { ... }  // Calls g() only if f().is()
>     if (f() || g()) { ... }  // Calls g() only if !f().is()
> }
>=20
> The above code is equivalent to
>=20
> class A
> {
>     bool is() const;
>=20
>   public:
>     bool operator&&(A (*other)()) const { return is() && other().is(); }
>     bool operator||(A (*other)()) const { return is() || other().is(); }
> };
>=20
> A f();
> A g();
>=20
> void test()
> {
>     if (f().operator&&([&] { return g(); }) { ... }
>     if (f().operator||([&] { return g(); }) { ... }
> }
>=20
> Another example:
>=20
> template <typename T>
> void repeat(size_t n, [&] T t) { while (n-- > 0) { t; } }
>=20
> void test()
> {
>     int i =3D 1;
>=20
>     repeat(5, i +=3D 2);
>     assert(i =3D=3D 11);
>=20
>     repeat(0, i +=3D 2);
>     assert(i =3D=3D 11);
> }
>=20

Hi!

I have proposed something like this here before,
look at
http://thread.gmane.org/gmane.comp.lang.c++.isocpp.proposals/9988

In my opinion, it would be a great extension to the language, to enable=20
programmers to write even more functional-style code.
Regarding use cases, overloading && and || is not the only one.
Whoever has ever written code in some functional language knows
how lazy function calls can be useful.

As far as your proposal is concerned, with respect to mine, you
suggest to have explicit call syntax inside the function, while it
would be transparent at call site.

I have proposed something more transparent. In a few words,
the evaluation of the parameter lambda would happen at the
first use of the object, and the result stored in an actual local
variable. This ensure the side effects of the argument to happen
only once, if at all.

I exclude the possibility to evaluate the argument's side effects more
than once, because it could be difficult to take into account all the
corner cases. However, this can be debated.

Anyway, my idea have not been very much welcomed, but later
I've seen something like this have been proposed by other people
other times.

So if there is interest we can make up a paper formalizing our ideas.
Is there somebody interested?


Greetings,
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: Diggory Blake <diggsey@googlemail.com>
Date: Thu, 15 May 2014 12:20:43 -0700 (PDT)
Raw View
------=_Part_5715_30214315.1400181643957
Content-Type: text/plain; charset=UTF-8

That requires "foo" to be declared differently, which I think is
undesirable, std::function is supposed to be the most generic possible form
which you can use in any situation.

I'm not sufficiently familiar with the exact rules for when the lifetime of
a temporary is extended, but it seems unclear at exactly what point a
function_ref will become invalid. You're essentially creating a wrapper for
rvalue references, which I think is inherently unsafe, and the reason why
std::ref and reference_wrapper are incompatible with them. By storing the
lambda in a local variable it's completely unambiguous when its lifetime
ends, and when it will become invalid.

On Thursday, 15 May 2014 19:59:43 UTC+1, Jeremy Maitin-Shepard wrote:
>
> On Thu, May 15, 2014 at 11:41 AM, Diggory Blake <dig...@googlemail.com<javascript:>
> > wrote:
>
>>
>> You can't put it on the stack because the lambda may be used after the
>> function returns, putting it anywhere else requires an allocation (it can't
>> be static). There is the special case where the lambda will never be used
>> outside the function, in that case you could add a constructor to
>> std::function which would allow this:
>>
>> auto f = <some lambda>;
>> std::function g(std::ref(f));
>>
>> In this case it's clear that returning 'g' would be an error, but it can
>> still be used within the scope without a single allocation.
>>
>
> You have a good point.  Assuming a small buffer optimization, using
> std::ref with std::function achieves the same thing as the hypothetical
> function_ref.  However, a function_ref that can be constructed from an
> rvalue would still be useful, as it would allow you to do:
>
> void foo(function_ref<void ()> x);
>
> foo([&] { /* ... */ });
>
> instead of the less convenient
>
> void foo(std::function<void ()> x);
> auto f = [&] { /* ... */ };
> foo(std::ref(f));
>

--

---
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_5715_30214315.1400181643957
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">That requires "foo" to be declared differently, which I th=
ink is undesirable, std::function is supposed to be the most generic possib=
le form which you can use in any situation.<br><br>I'm not sufficiently fam=
iliar with the exact rules for when the lifetime of a temporary is extended=
, but it seems unclear at exactly what point a function_ref will become inv=
alid. You're essentially creating a wrapper for rvalue references, which I =
think is inherently unsafe, and the reason why std::ref and reference_wrapp=
er are incompatible with them. By storing the lambda in a local variable it=
's completely unambiguous when its lifetime ends, and when it will become i=
nvalid.<br><br>On Thursday, 15 May 2014 19:59:43 UTC+1, Jeremy Maitin-Shepa=
rd  wrote:<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"><di=
v><div class=3D"gmail_quote">On Thu, May 15, 2014 at 11:41 AM, Diggory Blak=
e <span dir=3D"ltr">&lt;<a href=3D"javascript:" target=3D"_blank" gdf-obfus=
cated-mailto=3D"6FYGeAwroz4J" onmousedown=3D"this.href=3D'javascript:';retu=
rn true;" onclick=3D"this.href=3D'javascript:';return true;">dig...@googlem=
ail.com</a>&gt;</span> wrote:<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex"><div dir=3D"ltr"><br><div>You can't put it o=
n the stack because the lambda may be used after the function returns, putt=
ing it anywhere else requires an allocation (it can't be static). There is =
the special case where the lambda will never be used outside the function, =
in that case you could add a constructor to std::function which would allow=
 this:<br>
<br><div style=3D"background-color:rgb(250,250,250);border-color:rgb(187,18=
7,187);border-style:solid;border-width:1px;word-wrap:break-word"><code><div=
><span style=3D"color:#008">auto</span><span style=3D"color:#000"> f </span=
><span style=3D"color:#660">=3D</span><span style=3D"color:#000"> </span><s=
pan style=3D"color:#660">&lt;</span><span style=3D"color:#000">some </span>=
<span style=3D"color:#008">lambda</span><span style=3D"color:#660">&gt;;</s=
pan><span style=3D"color:#000"><br>
std</span><span style=3D"color:#660">::</span><span style=3D"color:#008">fu=
nction</span><span style=3D"color:#000"> g</span><span style=3D"color:#660"=
>(</span><span style=3D"color:#000">std</span><span style=3D"color:#660">::=
</span><span style=3D"color:#008">ref</span><span style=3D"color:#660">(</s=
pan><span style=3D"color:#000">f</span><span style=3D"color:#660">));</span=
><span style=3D"color:#000"><br>
</span></div></code></div><br>In this case it's clear that returning 'g' wo=
uld be an error, but it can still be used within the scope without a single=
 allocation.<br></div></div></blockquote><div><br></div><div>
You have a good point.&nbsp; Assuming a small buffer optimization, using st=
d::ref with std::function achieves the same thing as the hypothetical funct=
ion_ref.&nbsp; However, a function_ref that can be constructed from an rval=
ue would still be useful, as it would allow you to do:<br>
<br></div><div>void foo(function_ref&lt;void ()&gt; x);<br><br></div><div>f=
oo([&amp;] { /* ... */ });<br><br></div><div>instead of the less convenient=
<br><br></div><div>void foo(std::function&lt;void ()&gt; x);<br></div><div>
auto f =3D [&amp;] { /* ... */ };<br></div><div>foo(std::ref(f));<br></div>=
</div></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_5715_30214315.1400181643957--

.


Author: Jeremy Maitin-Shepard <jeremy@jeremyms.com>
Date: Thu, 15 May 2014 12:38:33 -0700
Raw View
--047d7ba97a883f67a904f975714a
Content-Type: text/plain; charset=UTF-8

On Thu, May 15, 2014 at 12:20 PM, Diggory Blake <diggsey@googlemail.com>wrote:

> That requires "foo" to be declared differently, which I think is
> undesirable, std::function is supposed to be the most generic possible form
> which you can use in any situation.
>
> An alternative would be an rvalue_ref function that returns a
reference_wrapper for rvalues.  That could be used with std::function,
though it would be less convenient syntax at the call site.  However, the
advantage of function_ref is that it documents that reference semantics are
expected.

A related issue is that std::function does not support move-only functions;
this can be worked around by a wrapper as well.


> I'm not sufficiently familiar with the exact rules for when the lifetime
> of a temporary is extended, but it seems unclear at exactly what point a
> function_ref will become invalid. You're essentially creating a wrapper for
> rvalue references, which I think is inherently unsafe, and the reason why
> std::ref and reference_wrapper are incompatible with them. By storing the
> lambda in a local variable it's completely unambiguous when its lifetime
> ends, and when it will become invalid.
>
> The lifetime is valid until the end of the statement.  It isn't inherently
unsafe, it just requires care.  Passing by const reference has the same
potential for dangling references.  It would be somewhat dangerous to use
function_ref as a local variable, since it doesn't even do the lifetime
extension of temporaries that a true reference type would, though that is
still very error prone.

--

---
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/.

--047d7ba97a883f67a904f975714a
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On T=
hu, May 15, 2014 at 12:20 PM, Diggory Blake <span dir=3D"ltr">&lt;<a href=
=3D"mailto:diggsey@googlemail.com" target=3D"_blank">diggsey@googlemail.com=
</a>&gt;</span> wrote:<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex"><div dir=3D"ltr">That requires &quot;foo&quo=
t; to be declared differently, which I think is undesirable, std::function =
is supposed to be the most generic possible form which you can use in any s=
ituation.<br>
<br></div></blockquote><div>An alternative would be an rvalue_ref function =
that returns a reference_wrapper for rvalues.=C2=A0 That could be used with=
 std::function, though it would be less convenient syntax at the call site.=
=C2=A0 However, the advantage of function_ref is that it documents that ref=
erence semantics are expected.<br>
<br></div><div>A related issue is that std::function does not support move-=
only functions; this can be worked around by a wrapper as well.<br></div><d=
iv>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex=
;border-left:1px #ccc solid;padding-left:1ex">
<div dir=3D"ltr">I&#39;m not sufficiently familiar with the exact rules for=
 when the lifetime of a temporary is extended, but it seems unclear at exac=
tly what point a function_ref will become invalid. You&#39;re essentially c=
reating a wrapper for rvalue references, which I think is inherently unsafe=
, and the reason why std::ref and reference_wrapper are incompatible with t=
hem. By storing the lambda in a local variable it&#39;s completely unambigu=
ous when its lifetime ends, and when it will become invalid.<br>
<br></div></blockquote><div>The lifetime is valid until the end of the stat=
ement.=C2=A0 It isn&#39;t inherently unsafe, it just requires care.=C2=A0 P=
assing by const reference has the same potential for dangling references.=
=C2=A0 It would be somewhat dangerous to use function_ref as a local variab=
le, since it doesn&#39;t even do the lifetime extension of temporaries that=
 a true reference type would, though that is still very error prone.<br>
</div></div></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 />

--047d7ba97a883f67a904f975714a--

.


Author: Diggory Blake <diggsey@googlemail.com>
Date: Thu, 15 May 2014 12:47:08 -0700 (PDT)
Raw View
------=_Part_578_15575113.1400183228043
Content-Type: text/plain; charset=UTF-8



On Thursday, 15 May 2014 20:38:33 UTC+1, Jeremy Maitin-Shepard wrote:
>
> On Thu, May 15, 2014 at 12:20 PM, Diggory Blake <dig...@googlemail.com<javascript:>
> > wrote:
>
>> That requires "foo" to be declared differently, which I think is
>> undesirable, std::function is supposed to be the most generic possible form
>> which you can use in any situation.
>>
>> An alternative would be an rvalue_ref function that returns a
> reference_wrapper for rvalues.  That could be used with std::function,
> though it would be less convenient syntax at the call site.  However, the
> advantage of function_ref is that it documents that reference semantics are
> expected.
>
> A related issue is that std::function does not support move-only
> functions; this can be worked around by a wrapper as well.
>
>
>> I'm not sufficiently familiar with the exact rules for when the lifetime
>> of a temporary is extended, but it seems unclear at exactly what point a
>> function_ref will become invalid. You're essentially creating a wrapper for
>> rvalue references, which I think is inherently unsafe, and the reason why
>> std::ref and reference_wrapper are incompatible with them. By storing the
>> lambda in a local variable it's completely unambiguous when its lifetime
>> ends, and when it will become invalid.
>>
>> The lifetime is valid until the end of the statement.  It isn't
> inherently unsafe, it just requires care.  Passing by const reference has
> the same potential for dangling references.  It would be somewhat dangerous
> to use function_ref as a local variable, since it doesn't even do the
> lifetime extension of temporaries that a true reference type would, though
> that is still very error prone.
>

Yeah, I was mainly thinking of if you wanted to use function_ref as a local
variable.

Also, std::ref should just work in your example too, as long as the lambda
isn't mutable:
void foo(function<void ()> x);

foo(std::ref([&] { /* ... */ }));

It would just be a const reference.

If you want to use a mutable lambda, then perhaps it's better that you have
to provide your own storage for it?


--

---
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_578_15575113.1400183228043
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Thursday, 15 May 2014 20:38:33 UTC+1, Jeremy Ma=
itin-Shepard  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"><div><div class=3D"gmail_quote">On Thu, May 15, 2014 at 12:20 PM, =
Diggory Blake <span dir=3D"ltr">&lt;<a href=3D"javascript:" target=3D"_blan=
k" gdf-obfuscated-mailto=3D"C8uOjGO1GYEJ" onmousedown=3D"this.href=3D'javas=
cript:';return true;" onclick=3D"this.href=3D'javascript:';return true;">di=
g...@googlemail.com</a>&gt;</span> wrote:<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex"><div dir=3D"ltr">That requires "foo" to be d=
eclared differently, which I think is undesirable, std::function is suppose=
d to be the most generic possible form which you can use in any situation.<=
br>
<br></div></blockquote><div>An alternative would be an rvalue_ref function =
that returns a reference_wrapper for rvalues.&nbsp; That could be used with=
 std::function, though it would be less convenient syntax at the call site.=
&nbsp; However, the advantage of function_ref is that it documents that ref=
erence semantics are expected.<br>
<br></div><div>A related issue is that std::function does not support move-=
only functions; this can be worked around by a wrapper as well.<br></div><d=
iv>&nbsp;</div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex=
;border-left:1px #ccc solid;padding-left:1ex">
<div dir=3D"ltr">I'm not sufficiently familiar with the exact rules for whe=
n the lifetime of a temporary is extended, but it seems unclear at exactly =
what point a function_ref will become invalid. You're essentially creating =
a wrapper for rvalue references, which I think is inherently unsafe, and th=
e reason why std::ref and reference_wrapper are incompatible with them. By =
storing the lambda in a local variable it's completely unambiguous when its=
 lifetime ends, and when it will become invalid.<br>
<br></div></blockquote><div>The lifetime is valid until the end of the stat=
ement.&nbsp; It isn't inherently unsafe, it just requires care.&nbsp; Passi=
ng by const reference has the same potential for dangling references.&nbsp;=
 It would be somewhat dangerous to use function_ref as a local variable, si=
nce it doesn't even do the lifetime extension of temporaries that a true re=
ference type would, though that is still very error prone.<br></div></div><=
/div></div></blockquote><div><br>Yeah, I was mainly thinking of if you want=
ed to use function_ref as a local variable.<br><br>Also, std::ref should ju=
st work in your example too, as long as the lambda isn't mutable:<br><div c=
lass=3D"prettyprint" style=3D"background-color: rgb(250, 250, 250); border-=
color: rgb(187, 187, 187); border-style: solid; border-width: 1px; word-wra=
p: break-word;"><code class=3D"prettyprint"><div class=3D"subprettyprint"><=
span style=3D"color: #008;" class=3D"styled-by-prettify">void</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"> foo</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">(</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">void</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">()&gt;</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"> x</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">);</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br><=
br>foo</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify">std</span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">::</span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">ref</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">([&amp;]</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"> </span><span style=3D"color: #800;" 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"=
>}));</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br><=
/span></div></code></div><br>It would just be a const reference.<br><br>If =
you want to use a mutable lambda, then perhaps it's better that you have to=
 provide your own storage for it?<br><br><br></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_578_15575113.1400183228043--

.


Author: Jeremy Maitin-Shepard <jeremy@jeremyms.com>
Date: Thu, 15 May 2014 14:13:29 -0700
Raw View
--047d7bfceb6ac7a4e704f976c443
Content-Type: text/plain; charset=UTF-8

On Thu, May 15, 2014 at 12:47 PM, Diggory Blake <diggsey@googlemail.com>wrote:

>
> Also, std::ref should just work in your example too, as long as the lambda
> isn't mutable:
> void foo(function<void ()> x);
>
> foo(std::ref([&] { /* ... */ }));
>
> This doesn't work because std::ref explicitly deletes the rvalue overloads.

--

---
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/.

--047d7bfceb6ac7a4e704f976c443
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On T=
hu, May 15, 2014 at 12:47 PM, Diggory Blake <span dir=3D"ltr">&lt;<a href=
=3D"mailto:diggsey@googlemail.com" target=3D"_blank">diggsey@googlemail.com=
</a>&gt;</span> wrote:<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex"><div dir=3D"ltr"><br><div>Also, std::ref sho=
uld just work in your example too, as long as the lambda isn&#39;t mutable:=
<br>
<div style=3D"background-color:rgb(250,250,250);border-color:rgb(187,187,18=
7);border-style:solid;border-width:1px;word-wrap:break-word"><code><div><sp=
an style=3D"color:#008">void</span><span style=3D"color:#000"> foo</span><s=
pan style=3D"color:#660">(</span><span style=3D"color:#008">function</span>=
<span style=3D"color:#660">&lt;</span><span style=3D"color:#008">void</span=
><span style=3D"color:#000"> </span><span style=3D"color:#660">()&gt;</span=
><span style=3D"color:#000"> x</span><span style=3D"color:#660">);</span><s=
pan style=3D"color:#000"><br>
<br>foo</span><span style=3D"color:#660">(</span><span style=3D"color:#000"=
>std</span><span style=3D"color:#660">::</span><span style=3D"color:#008">r=
ef</span><span style=3D"color:#660">([&amp;]</span><span style=3D"color:#00=
0"> </span><span style=3D"color:#660">{</span><span style=3D"color:#000"> <=
/span><span style=3D"color:#800">/* ... */</span><span style=3D"color:#000"=
> </span><span style=3D"color:#660">}));</span><span style=3D"color:#000"><=
br>
</span></div></code></div><br></div></div></blockquote></div>This doesn&#39=
;t work because std::ref explicitly deletes the rvalue overloads.<br></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 />

--047d7bfceb6ac7a4e704f976c443--

.


Author: Diggory Blake <diggsey@googlemail.com>
Date: Thu, 15 May 2014 16:28:12 -0700 (PDT)
Raw View
------=_Part_12_9400197.1400196492696
Content-Type: text/plain; charset=UTF-8

But I can do this:
template<typename T> T const& test(T const& v) {
    return v;
}

int main()
{
   auto i = std::ref(test([](int a){ return a + 1; }));

   return 0;
}

It seems like there should be a way to tell ref/cref to use the const&
overload instead of trying to use the rvalue overload and failing.


On Thursday, 15 May 2014 22:13:29 UTC+1, Jeremy Maitin-Shepard wrote:
>
> On Thu, May 15, 2014 at 12:47 PM, Diggory Blake <dig...@googlemail.com<javascript:>
> > wrote:
>
>>
>> Also, std::ref should just work in your example too, as long as the
>> lambda isn't mutable:
>> void foo(function<void ()> x);
>>
>> foo(std::ref([&] { /* ... */ }));
>>
>> This doesn't work because std::ref explicitly deletes the rvalue
> overloads.
>

--

---
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_12_9400197.1400196492696
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">But I can do this:<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: #008;" cl=
ass=3D"styled-by-prettify">template</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">&lt;</span><span style=3D"color: #008;" class=3D"s=
tyled-by-prettify">typename</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> T</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">&gt;</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"> T </span><span style=3D"color: #008;" class=3D"styled-by-prettify">cons=
t</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&amp;</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"> test</span><s=
pan 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"colo=
r: #008;" class=3D"styled-by-prettify">const</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">&amp;</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> v</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: #660;" class=3D"styled-by-prettif=
y">{</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>&n=
bsp; &nbsp; </span><span style=3D"color: #008;" class=3D"styled-by-prettify=
">return</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> v=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">;</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"><br></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><br></span><span style=3D"colo=
r: #008;" class=3D"styled-by-prettify">int</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify"> main</span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">()</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"><br></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-by=
-prettify">auto</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"> i </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> std</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">::</span><spa=
n style=3D"color: #008;" class=3D"styled-by-prettify">ref</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify">test</span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">([](</span><span style=3D"color: #008;" cla=
ss=3D"styled-by-prettify">int</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-prettif=
y"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">return=
</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 sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"col=
or: #066;" class=3D"styled-by-prettify">1</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"style=
d-by-prettify">}));</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"><br>&nbsp; &nbsp;<br>&nbsp; &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"> </span><span style=3D"color: #066;" class=3D"=
styled-by-prettify">0</span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">;</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"><br></span><span style=3D"color: #660;" class=3D"styled-by-prettify">}</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span></=
div></code></div><br>It seems like there should be a way to tell ref/cref t=
o use the const&amp; overload instead of trying to use the rvalue overload =
and failing.<br><br><br>On Thursday, 15 May 2014 22:13:29 UTC+1, Jeremy Mai=
tin-Shepard  wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;mar=
gin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D=
"ltr"><div><div class=3D"gmail_quote">On Thu, May 15, 2014 at 12:47 PM, Dig=
gory Blake <span dir=3D"ltr">&lt;<a href=3D"javascript:" target=3D"_blank" =
gdf-obfuscated-mailto=3D"6-TlPTI19IQJ" onmousedown=3D"this.href=3D'javascri=
pt:';return true;" onclick=3D"this.href=3D'javascript:';return true;">dig..=
..@googlemail.com</a>&gt;</span> wrote:<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex"><div dir=3D"ltr"><br><div>Also, std::ref sho=
uld just work in your example too, as long as the lambda isn't mutable:<br>
<div style=3D"background-color:rgb(250,250,250);border-color:rgb(187,187,18=
7);border-style:solid;border-width:1px;word-wrap:break-word"><code><div><sp=
an style=3D"color:#008">void</span><span style=3D"color:#000"> foo</span><s=
pan style=3D"color:#660">(</span><span style=3D"color:#008">function</span>=
<span style=3D"color:#660">&lt;</span><span style=3D"color:#008">void</span=
><span style=3D"color:#000"> </span><span style=3D"color:#660">()&gt;</span=
><span style=3D"color:#000"> x</span><span style=3D"color:#660">);</span><s=
pan style=3D"color:#000"><br>
<br>foo</span><span style=3D"color:#660">(</span><span style=3D"color:#000"=
>std</span><span style=3D"color:#660">::</span><span style=3D"color:#008">r=
ef</span><span style=3D"color:#660">([&amp;]</span><span style=3D"color:#00=
0"> </span><span style=3D"color:#660">{</span><span style=3D"color:#000"> <=
/span><span style=3D"color:#800">/* ... */</span><span style=3D"color:#000"=
> </span><span style=3D"color:#660">}));</span><span style=3D"color:#000"><=
br>
</span></div></code></div><br></div></div></blockquote></div>This doesn't w=
ork because std::ref explicitly deletes the rvalue overloads.<br></div></di=
v>
</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_12_9400197.1400196492696--

.


Author: Brian Bi <bbi5291@gmail.com>
Date: Thu, 15 May 2014 19:36:04 -0400
Raw View
--001a1133d17aaa70c704f978c21d
Content-Type: text/plain; charset=UTF-8

But the lifetime of the temporary won't be extended, so even if you could
get a std::reference_wrapper to a temporary, it would be useless because
the temporary will have already been destroyed before the beginning of the
next full-expression.

--
*Brian Bi*


On Thu, May 15, 2014 at 7:28 PM, Diggory Blake <diggsey@googlemail.com>wrote:

> But I can do this:
> template<typename T> T const& test(T const& v) {
>     return v;
> }
>
> int main()
> {
>    auto i = std::ref(test([](int a){ return a + 1; }));
>
>    return 0;
> }
>
> It seems like there should be a way to tell ref/cref to use the const&
> overload instead of trying to use the rvalue overload and failing.
>
>
> On Thursday, 15 May 2014 22:13:29 UTC+1, Jeremy Maitin-Shepard wrote:
>
>> On Thu, May 15, 2014 at 12:47 PM, Diggory Blake <dig...@googlemail.com>wrote:
>>
>>>
>>> Also, std::ref should just work in your example too, as long as the
>>> lambda isn't mutable:
>>> void foo(function<void ()> x);
>>>
>>> foo(std::ref([&] { /* ... */ }));
>>>
>>> This doesn't work because std::ref explicitly deletes the rvalue
>> overloads.
>>
>  --
>
> ---
> 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/.

--001a1133d17aaa70c704f978c21d
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">But the lifetime of the temporary won&#39;t be extended, s=
o even if you could get a std::reference_wrapper to a temporary, it would b=
e useless because the temporary will have already been destroyed before the=
 beginning of the next full-expression.<br>
</div><div class=3D"gmail_extra"><br clear=3D"all"><div><div dir=3D"ltr"><f=
ont color=3D"#c0c0c0"><span style=3D"color:rgb(0,0,0)">--</span><i><br>Bria=
n Bi</i></font><br><div></div><div></div><div></div></div></div>
<br><br><div class=3D"gmail_quote">On Thu, May 15, 2014 at 7:28 PM, Diggory=
 Blake <span dir=3D"ltr">&lt;<a href=3D"mailto:diggsey@googlemail.com" targ=
et=3D"_blank">diggsey@googlemail.com</a>&gt;</span> wrote:<br><blockquote c=
lass=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;=
padding-left:1ex">
<div dir=3D"ltr">But I can do this:<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:#008">template</sp=
an><span style=3D"color:#660">&lt;</span><span style=3D"color:#008">typenam=
e</span><span style=3D"color:#000"> T</span><span style=3D"color:#660">&gt;=
</span><span style=3D"color:#000"> T </span><span style=3D"color:#008">cons=
t</span><span style=3D"color:#660">&amp;</span><span style=3D"color:#000"> =
test</span><span style=3D"color:#660">(</span><span style=3D"color:#000">T =
</span><span style=3D"color:#008">const</span><span style=3D"color:#660">&a=
mp;</span><span style=3D"color:#000"> v</span><span style=3D"color:#660">)<=
/span><span style=3D"color:#000"> </span><span style=3D"color:#660">{</span=
><span style=3D"color:#000"><br>
=C2=A0 =C2=A0 </span><span style=3D"color:#008">return</span><span style=3D=
"color:#000"> v</span><span style=3D"color:#660">;</span><span style=3D"col=
or:#000"><br></span><span style=3D"color:#660">}</span><span style=3D"color=
:#000"><br><br></span><span style=3D"color:#008">int</span><span style=3D"c=
olor:#000"> main</span><span style=3D"color:#660">()</span><span style=3D"c=
olor:#000"><br>
</span><span style=3D"color:#660">{</span><span style=3D"color:#000"><br>=
=C2=A0 =C2=A0</span><span style=3D"color:#008">auto</span><span style=3D"co=
lor:#000"> i </span><span style=3D"color:#660">=3D</span><span style=3D"col=
or:#000"> std</span><span style=3D"color:#660">::</span><span style=3D"colo=
r:#008">ref</span><span style=3D"color:#660">(</span><span style=3D"color:#=
000">test</span><span style=3D"color:#660">([](</span><span style=3D"color:=
#008">int</span><span style=3D"color:#000"> a</span><span style=3D"color:#6=
60">){</span><span style=3D"color:#000"> </span><span style=3D"color:#008">=
return</span><span style=3D"color:#000"> a </span><span style=3D"color:#660=
">+</span><span style=3D"color:#000"> </span><span style=3D"color:#066">1</=
span><span style=3D"color:#660">;</span><span style=3D"color:#000"> </span>=
<span style=3D"color:#660">}));</span><span style=3D"color:#000"><br>
=C2=A0 =C2=A0<br>=C2=A0 =C2=A0</span><span style=3D"color:#008">return</spa=
n><span style=3D"color:#000"> </span><span style=3D"color:#066">0</span><sp=
an style=3D"color:#660">;</span><span style=3D"color:#000"><br></span><span=
 style=3D"color:#660">}</span><span style=3D"color:#000"><br>
</span></div></code></div><br>It seems like there should be a way to tell r=
ef/cref to use the const&amp; overload instead of trying to use the rvalue =
overload and failing.<br><br><br>On Thursday, 15 May 2014 22:13:29 UTC+1, J=
eremy Maitin-Shepard  wrote:<div>
<div class=3D"h5"><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"ltr">=
<div><div class=3D"gmail_quote">On Thu, May 15, 2014 at 12:47 PM, Diggory B=
lake <span dir=3D"ltr">&lt;<a>dig...@googlemail.com</a>&gt;</span> wrote:<b=
r>

<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex"><div dir=3D"ltr"><br><div>Also, std::ref sho=
uld just work in your example too, as long as the lambda isn&#39;t mutable:=
<br>

<div style=3D"background-color:rgb(250,250,250);border-color:rgb(187,187,18=
7);border-style:solid;border-width:1px;word-wrap:break-word"><code><div><sp=
an style=3D"color:#008">void</span><span style=3D"color:#000"> foo</span><s=
pan style=3D"color:#660">(</span><span style=3D"color:#008">function</span>=
<span style=3D"color:#660">&lt;</span><span style=3D"color:#008">void</span=
><span style=3D"color:#000"> </span><span style=3D"color:#660">()&gt;</span=
><span style=3D"color:#000"> x</span><span style=3D"color:#660">);</span><s=
pan style=3D"color:#000"><br>

<br>foo</span><span style=3D"color:#660">(</span><span style=3D"color:#000"=
>std</span><span style=3D"color:#660">::</span><span style=3D"color:#008">r=
ef</span><span style=3D"color:#660">([&amp;]</span><span style=3D"color:#00=
0"> </span><span style=3D"color:#660">{</span><span style=3D"color:#000"> <=
/span><span style=3D"color:#800">/* ... */</span><span style=3D"color:#000"=
> </span><span style=3D"color:#660">}));</span><span style=3D"color:#000"><=
br>

</span></div></code></div><br></div></div></blockquote></div>This doesn&#39=
;t work because std::ref explicitly deletes the rvalue overloads.<br></div>=
</div>
</blockquote></div></div></div><div class=3D"HOEnZb"><div class=3D"h5">

<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" target=3D"_=
blank">std-proposals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br>
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/" target=3D"_blank">http://groups.google.com/a/isocpp.org/gro=
up/std-proposals/</a>.<br>
</div></div></blockquote></div><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 />

--001a1133d17aaa70c704f978c21d--

.


Author: Jeremy Maitin-Shepard <jeremy@jeremyms.com>
Date: Thu, 15 May 2014 16:52:24 -0700
Raw View
--047d7bd91b541c741404f978fd0d
Content-Type: text/plain; charset=UTF-8

On Thu, May 15, 2014 at 4:36 PM, Brian Bi <bbi5291@gmail.com> wrote:

> But the lifetime of the temporary won't be extended, so even if you could
> get a std::reference_wrapper to a temporary, it would be useless because
> the temporary will have already been destroyed before the beginning of the
> next full-expression.
>
> It would be useless to store the result in a local variable, but it is
fine to pass the result as a function argument directly.

--

---
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/.

--047d7bd91b541c741404f978fd0d
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On T=
hu, May 15, 2014 at 4:36 PM, Brian Bi <span dir=3D"ltr">&lt;<a href=3D"mail=
to:bbi5291@gmail.com" target=3D"_blank">bbi5291@gmail.com</a>&gt;</span> wr=
ote:<br><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border=
-left:1px #ccc solid;padding-left:1ex">
<div dir=3D"ltr">But the lifetime of the temporary won&#39;t be extended, s=
o even if you could get a std::reference_wrapper to a temporary, it would b=
e useless because the temporary will have already been destroyed before the=
 beginning of the next full-expression.<br>

</div><div class=3D"gmail_extra"><br clear=3D"all"></div></blockquote><div>=
It would be useless to store the result in a local variable, but it is fine=
 to pass the result as a function argument directly.<br></div></div><br></d=
iv>
</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 />

--047d7bd91b541c741404f978fd0d--

.


Author: =?UTF-8?Q?Ivan_=C4=8Cuki=C4=87?= <ivan.cukic@gmail.com>
Date: Fri, 16 May 2014 16:03:21 -0700 (PDT)
Raw View
------=_Part_724_7783701.1400281401644
Content-Type: text/plain; charset=UTF-8

Hi,

This does not really require any changes to the core language.

Doing lazy evaluation It is quite trivial and common (albeit not always
intentional*). You can write a templated class lazy<T> that would evaluate
any functor when the value is first requested, and cache the result for
future reference (a proper lazy evaluation).

Differences between
    [&] std::string s
    lazy std::string s
    lazy<std::string> s
are not really significant to warrant new syntax.

The class itself might be a nice addition to STL.

Cheerio,
Ivan

* Expression templates are based on lazy evaluation. Some people do find it
unexpected, especially since C++11 and 'auto'.

--

---
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_724_7783701.1400281401644
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Hi,<div><br></div><div>This does not really require any ch=
anges to the core language.</div><div><br></div><div>Doing lazy evaluation =
It is quite trivial and common (albeit not always intentional*). You can wr=
ite a templated class lazy&lt;T&gt; that would evaluate any functor when th=
e value is first requested, and cache the result for future reference (a pr=
oper lazy evaluation).<br><br>Differences between<br>&nbsp; &nbsp; [&amp;] =
std::string s</div><div>&nbsp; &nbsp; lazy std::string s</div><div>&nbsp; &=
nbsp; lazy&lt;std::string&gt; s</div><div>are not really significant to war=
rant new syntax.</div><div><br></div><div>The class itself might be a nice =
addition to STL.</div><div><br></div><div>Cheerio,</div><div>Ivan</div><div=
><br></div><div>* Expression templates are based on lazy evaluation. Some p=
eople do find it unexpected, especially since C++11 and 'auto'.</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_724_7783701.1400281401644--

.


Author: Diggory Blake <diggsey@googlemail.com>
Date: Fri, 16 May 2014 20:11:36 -0700 (PDT)
Raw View
------=_Part_866_176675.1400296296576
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

I think you're missing the point - the idea in the OP is that the caller=20
does not have to specify the lambda explicitly, instead they'd just pass in=
=20
a value as they would normally and the compiler would implicitly turn the=
=20
expression into a lambda.

On Saturday, 17 May 2014 00:03:21 UTC+1, Ivan =C4=8Cuki=C4=87 wrote:
>
> Hi,
>
> This does not really require any changes to the core language.
>
> Doing lazy evaluation It is quite trivial and common (albeit not always=
=20
> intentional*). You can write a templated class lazy<T> that would evaluat=
e=20
> any functor when the value is first requested, and cache the result for=
=20
> future reference (a proper lazy evaluation).
>
> Differences between
>     [&] std::string s
>     lazy std::string s
>     lazy<std::string> s
> are not really significant to warrant new syntax.
>
> The class itself might be a nice addition to STL.
>
> Cheerio,
> Ivan
>
> * Expression templates are based on lazy evaluation. Some people do find=
=20
> it unexpected, especially since C++11 and 'auto'.
>

--=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_866_176675.1400296296576
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">I think you're missing the point - the idea in the OP is t=
hat the caller does not have to specify the lambda explicitly, instead they=
'd just pass in a value as they would normally and the compiler would impli=
citly turn the expression into a lambda.<br><br>On Saturday, 17 May 2014 00=
:03:21 UTC+1, Ivan =C4=8Cuki=C4=87  wrote:<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">Hi,<div><br></div><div>This does not really re=
quire any changes to the core language.</div><div><br></div><div>Doing lazy=
 evaluation It is quite trivial and common (albeit not always intentional*)=
.. You can write a templated class lazy&lt;T&gt; that would evaluate any fun=
ctor when the value is first requested, and cache the result for future ref=
erence (a proper lazy evaluation).<br><br>Differences between<br>&nbsp; &nb=
sp; [&amp;] std::string s</div><div>&nbsp; &nbsp; lazy std::string s</div><=
div>&nbsp; &nbsp; lazy&lt;std::string&gt; s</div><div>are not really signif=
icant to warrant new syntax.</div><div><br></div><div>The class itself migh=
t be a nice addition to STL.</div><div><br></div><div>Cheerio,</div><div>Iv=
an</div><div><br></div><div>* Expression templates are based on lazy evalua=
tion. Some people do find it unexpected, especially since C++11 and 'auto'.=
</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_866_176675.1400296296576--

.


Author: =?UTF-8?Q?Ivan_=C4=8Cuki=C4=87?= <ivan.cukic@gmail.com>
Date: Sat, 17 May 2014 14:56:34 -0700 (PDT)
Raw View
------=_Part_443_6430830.1400363794830
Content-Type: text/plain; charset=UTF-8

> I think you're missing the point - the idea in the OP is that the caller
does not have to

True, got sidetracked by Nicola's proposal.

> specify the lambda explicitly, instead they'd just pass in a value as
they would

So, this would be only passing non-evaluated expressions to functions,
without wrapping them in lambda syntax.

While this could be (really) fun, I think it would open a can of worms.

If you can wrap an expression without free variables, people would want it
generalized to those with free vars, and we would get a truly great syntax
(like boost.phoenix) of std::accumulate(b, e, _1 * _2).

Unfortunately, these terse-syntax lambda proposals were rejected.

Cheers,
Ivan

--

---
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_443_6430830.1400363794830
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">&gt; I<span style=3D"font-size: 13px;">&nbsp;think you're =
missing the point - the idea in the OP is that the caller does not have to<=
/span><div><span style=3D"font-size: 13px;"><br></span></div><div><span sty=
le=3D"font-size: 13px;">True, got sidetracked by Nicola's proposal.</span><=
/div><div><span style=3D"font-size: 13px;"><br></span></div><div><span styl=
e=3D"font-size: 13px;">&gt; specify the lambda explicitly, instead they'd j=
ust pass in a value as they would</span></div><div><span style=3D"font-size=
: 13px;"><br></span></div><div>So, this would be only passing non-evaluated=
 expressions to functions, without wrapping them in lambda syntax.<br><br>W=
hile this could be (really) fun, I think it would open a can of worms.</div=
><div><br></div><div>If you can wrap an expression without free variables, =
people would want it generalized to those with free vars, and we would get =
a truly great syntax (like boost.phoenix) of std::accumulate(b, e, _1 * _2)=
..</div><div><br></div><div>Unfortunately, these terse-syntax lambda proposa=
ls were rejected.<br><br></div><div>Cheers,</div><div>Ivan</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_443_6430830.1400363794830--

.


Author: jgottman6@gmail.com
Date: Sun, 18 May 2014 19:35:59 -0700 (PDT)
Raw View
------=_Part_2192_20454217.1400466959989
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

This is implemented in the D programming language as  lazy parameters<http:=
//dlang.org/lazy-evaluation.html>.  The use case they use in their example =
is logging. Programmers often=20
want to log a message conditionally, depending on a global log level=20
variable (so they print all messages in debug mode, but only important ones=
=20
in release mode.  The naive way to write this function is:

void logMessage(int level, const std::string &message) {
   if (level < globalLogLevel) {
        std::cout << message;
    }
}

But, since the messages sent to a logger are often complicated string that=
=20
are the result of appending one or more strings to each otther, this naive=
=20
implementation can often end up constructing the temporary strings even=20
when the log level is such nothing will be printed.  To avoid this, users=
=20
often use logging macros to avoid creating the temporary. If we could=20
declare message as a lazy parameter we would not need to use a macro.


On Saturday, May 17, 2014 5:56:34 PM UTC-4, Ivan =C4=8Cuki=C4=87 wrote:
>
> > I think you're missing the point - the idea in the OP is that the=20
> caller does not have to
>
> True, got sidetracked by Nicola's proposal.
>
> > specify the lambda explicitly, instead they'd just pass in a value as=
=20
> they would
>
> So, this would be only passing non-evaluated expressions to functions,=20
> without wrapping them in lambda syntax.
>
> While this could be (really) fun, I think it would open a can of worms.
>
> If you can wrap an expression without free variables, people would want i=
t=20
> generalized to those with free vars, and we would get a truly great synta=
x=20
> (like boost.phoenix) of std::accumulate(b, e, _1 * _2).
>
> Unfortunately, these terse-syntax lambda proposals were rejected.
>
> Cheers,
> Ivan
>

--=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_2192_20454217.1400466959989
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">This is implemented in the D programming language as&nbsp;=
 <a href=3D"http://dlang.org/lazy-evaluation.html">lazy parameters</a> .&nb=
sp; The use case they use in their example is logging. Programmers often wa=
nt to log a message conditionally, depending on a global log level variable=
 (so they print all messages in debug mode, but only important ones in rele=
ase mode.&nbsp; The naive way to write this function is:<br><br><div class=
=3D"prettyprint" style=3D"background-color: rgb(250, 250, 250); border-colo=
r: rgb(187, 187, 187); border-style: solid; border-width: 1px; word-wrap: b=
reak-word;"><code class=3D"prettyprint"><div class=3D"subprettyprint"><span=
 style=3D"color: #008;" class=3D"styled-by-prettify">void</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> logMessage</span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"colo=
r: #008;" class=3D"styled-by-prettify">int</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify"> level</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-=
prettify">const</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: #008;" class=3D"styled-by-prettify">string</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span=
 style=3D"color: #660;" class=3D"styled-by-prettify">&amp;</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify">message</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">{</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"><br>&nbsp; &nbsp;</span><span style=3D"color: #008;" cl=
ass=3D"styled-by-prettify">if</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
>level </span><span style=3D"color: #660;" class=3D"styled-by-prettify">&lt=
;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> globalLo=
gLevel</span><span style=3D"color: #660;" class=3D"styled-by-prettify">)</s=
pan><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; &nbsp; &nbsp; &nbsp;=
 std</span><span style=3D"color: #660;" class=3D"styled-by-prettify">::</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify">cout </span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">&lt;&lt;</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"> message</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; </span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">}</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">}</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"><br></span></div></code></div><br>But, since the=
 messages sent to a logger are often complicated string that are the result=
 of appending one or more strings to each otther, this naive implementation=
 can often end up constructing the temporary strings even when the log leve=
l is such nothing will be printed.&nbsp; To avoid this, users often use log=
ging macros to avoid creating the temporary. If we could declare message as=
 a lazy parameter we would not need to use a macro.<br><br><br>On Saturday,=
 May 17, 2014 5:56:34 PM UTC-4, Ivan =C4=8Cuki=C4=87 wrote:<blockquote clas=
s=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #c=
cc solid;padding-left: 1ex;"><div dir=3D"ltr">&gt; I<span style=3D"font-siz=
e:13px">&nbsp;think you're missing the point - the idea in the OP is that t=
he caller does not have to</span><div><span style=3D"font-size:13px"><br></=
span></div><div><span style=3D"font-size:13px">True, got sidetracked by Nic=
ola's proposal.</span></div><div><span style=3D"font-size:13px"><br></span>=
</div><div><span style=3D"font-size:13px">&gt; specify the lambda explicitl=
y, instead they'd just pass in a value as they would</span></div><div><span=
 style=3D"font-size:13px"><br></span></div><div>So, this would be only pass=
ing non-evaluated expressions to functions, without wrapping them in lambda=
 syntax.<br><br>While this could be (really) fun, I think it would open a c=
an of worms.</div><div><br></div><div>If you can wrap an expression without=
 free variables, people would want it generalized to those with free vars, =
and we would get a truly great syntax (like boost.phoenix) of std::accumula=
te(b, e, _1 * _2).</div><div><br></div><div>Unfortunately, these terse-synt=
ax lambda proposals were rejected.<br><br></div><div>Cheers,</div><div>Ivan=
</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_2192_20454217.1400466959989--

.


Author: Jim Porter <jvp4846@g.rit.edu>
Date: Sun, 18 May 2014 21:22:55 -0700 (PDT)
Raw View
------=_Part_332_667366.1400473375761
Content-Type: text/plain; charset=UTF-8

On Wednesday, May 14, 2014 3:52:03 PM UTC-5, Hyman Rosen wrote:
>
> I propose to allow function parameter declarations to be prefixed with [&]*.
>  *Doing so would cause those parameters to be *passed by lambda*. That
> is, when the function is called, the argument expression for that parameter
> is not evaluated.  Instead, it is wrapped in a 0-parameter
> capture-by-reference lambda that returns that expression, and the lambda is
> passed to the function.  When the function would access the variable. it
> calls the lambda instead and uses its return value (and it may do so any
> number of times, including 0).
>

Overall, this seems at least moderately useful (it would allow
short-circuiting boolean operators and macro-free debug/logging functions),
but I'd much rather see the parameter be treated as a function object. This
is more explicit, and is consistent with other areas of C++ as well (e.g.
container.size() is a function, not a getter like in other languages*).
That would make it extremely obvious to the user of pass-by-lambda where
the passed expression is evaluated. I think that obviousness outweighs the
minor ugliness of the syntax:

struct A {
  bool is() const;

  bool operator &&([&] A rhs) {
    return is() && rhs().is();
  }
};

- Jim

* That's not to say that getters would be entirely bad in C++, but I'd
rather not see *arbitrary* expressions look like getters; only ones that
are explicitly written to be a getter.

--

---
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_332_667366.1400473375761
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Wednesday, May 14, 2014 3:52:03 PM UTC-5, Hyman Rosen w=
rote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8e=
x;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr">I propos=
e to allow function parameter declarations to be prefixed with <font style=
=3D"font-weight:bold" face=3D"courier new, monospace">[&amp;]</font><b styl=
e=3D"font-family:arial,sans-serif">. &nbsp;</b><font face=3D"arial, sans-se=
rif">Doing so would cause those parameters to be </font><i style=3D"font-fa=
mily:arial,sans-serif">passed by lambda</i><font face=3D"arial, sans-serif"=
>. That is, when the function is called, the argument expression for that p=
arameter is not evaluated. &nbsp;Instead, it is wrapped in a 0-parameter ca=
pture-by-reference lambda that returns that expression, and the lambda is p=
assed to the function. &nbsp;When the function would access</font><font fac=
e=3D"arial, sans-serif">&nbsp;the variable. it calls the lambda instead and=
 uses its return value (and it may do so any number of times, including 0).=
</font><br></div></blockquote><div><br>Overall, this seems at least moderat=
ely useful (it would allow short-circuiting boolean operators and macro-fre=
e debug/logging functions), but I'd much rather see the parameter be treate=
d as a function object. This is more explicit, and is consistent with other=
 areas of C++ as well (e.g. container.size() is a function, not a getter li=
ke in other languages*). That would make it extremely obvious to the user o=
f pass-by-lambda where the passed expression is evaluated. I think that obv=
iousness outweighs the minor ugliness of the syntax:<br><br>struct A {<br>&=
nbsp; bool is() const;<br><br>&nbsp; bool operator &amp;&amp;([&amp;] A rhs=
) {<br>&nbsp; &nbsp; return is() &amp;&amp; rhs().is();<br>&nbsp; }<br>};<b=
r><br>- Jim<br><br>* That's not to say that getters would be entirely bad i=
n C++, but I'd rather not see *arbitrary* expressions look like getters; on=
ly ones that are explicitly written to be a getter.<br></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_332_667366.1400473375761--

.


Author: David Krauss <potswa@gmail.com>
Date: Mon, 19 May 2014 12:32:07 +0800
Raw View
--Apple-Mail=_FA2642CD-184D-48D4-B8C6-2F327956433E
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=ISO-8859-1


On 2014-05-15, at 4:52 AM, Hyman Rosen <hyman.rosen@gmail.com> wrote:

> I propose to allow function parameter declarations to be prefixed with [&=
].  Doing so would cause those parameters to be passed by lambda. That is, =
when the function is called, the argument expression for that parameter is =
not evaluated.  Instead, it is wrapped in a 0-parameter capture-by-referenc=
e lambda that returns that expression, and the lambda is passed to the func=
tion.  When the function would access the variable. it calls the lambda ins=
tead and uses its return value (and it may do so any number of times, inclu=
ding 0).

This looks very similar to my recent proposal (only a thread here, see OP o=
n April 9) for inline variables. The inline keyword is proposed to set a va=
riable to refer to its initializer, which is not immediately evaluated. The=
 behavior is somewhat like a lambda functor. The difference from your propo=
sal is avoidance of the () function call operator.

I prohibited it for function parameters, but inline parameters may be permi=
ssible on inline functions -- which is a simple rule to remember.

If taken merely as a suggestion, as inline is for functions, this does not =
require templating. Such a system would allow evaluation either eagerly or =
lazily, and telling the difference would be UB, which is probably a very ba=
d thing. It would not (reliably) support short-circuit operator overloads a=
s you describe.

If inline expresses a requirement on parameters, then they behave like temp=
lates, and function recursion equates to template recursion. This seems lik=
e an equally bad thing. A workaround may be to special-case function calls =
where an inline variable is passed to an inline parameter, such that the in=
visible lambda is passed directly rather than being evaluated and then re-w=
rapped. The problem may be (maybe) minimized by avoiding specification of i=
mplicit templating.

The compromise viz. hidden templating is that an inline function with an in=
line parameter may not have its address taken. Does anyone see another gotc=
ha?

--=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=_FA2642CD-184D-48D4-B8C6-2F327956433E
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=ISO-8859-1

<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>On 2014&=
ndash;05&ndash;15, at 4:52 AM, Hyman Rosen &lt;<a href=3D"mailto:hyman.rose=
n@gmail.com">hyman.rosen@gmail.com</a>&gt; wrote:</div><br class=3D"Apple-i=
nterchange-newline"><blockquote type=3D"cite"><div dir=3D"ltr">I propose to=
 allow function parameter declarations to be prefixed with <font face=3D"co=
urier new, monospace" style=3D"font-weight: bold;">[&amp;]</font><b style=
=3D"font-family: arial, sans-serif;">. &nbsp;</b><font face=3D"arial, sans-=
serif">Doing so would cause those parameters to be </font><i style=3D"font-=
family: arial, sans-serif;">passed by lambda</i><font face=3D"arial, sans-s=
erif">. That is, when the function is called, the argument expression for t=
hat parameter is not evaluated. &nbsp;Instead, it is wrapped in a 0-paramet=
er capture-by-reference lambda that returns that expression, and the lambda=
 is passed to the function. &nbsp;When the function would access</font><fon=
t face=3D"arial, sans-serif">&nbsp;the variable. it calls the lambda instea=
d and uses its return value (and it may do so any number of times, includin=
g 0).</font><br></div></blockquote><div><br></div><div>This looks very simi=
lar to my recent proposal (only a thread here, see OP on April 9) for inlin=
e variables. The inline keyword is proposed to set a variable to refer to i=
ts initializer, which is not immediately evaluated. The behavior is somewha=
t like a lambda functor. The difference from your proposal is avoidance of =
the <font face=3D"Courier">()</font> function call operator.</div><div><br>=
</div><div>I prohibited it for function parameters, but inline parameters m=
ay be permissible on inline functions &mdash; which is a simple rule to rem=
ember.</div><div><br></div><div>If taken merely as a suggestion, as <font f=
ace=3D"Courier">inline</font> is for functions, this does not require templ=
ating. Such a system would allow evaluation either eagerly or lazily, and t=
elling the difference would be UB, which is probably a very bad thing. It w=
ould not (reliably) support short-circuit operator overloads as you describ=
e.</div><div><br></div><div>If <font face=3D"Courier">inline</font> express=
es a requirement on parameters, then they behave like templates, and functi=
on recursion equates to template recursion. This seems like an equally bad =
thing. A workaround may be to special-case function calls where an inline v=
ariable is passed to an inline parameter, such that the invisible lambda is=
 passed directly rather than being evaluated and then re-wrapped. The probl=
em may be (maybe) minimized by avoiding specification of implicit templatin=
g.</div></div><br><div>The compromise viz. hidden templating is that an inl=
ine function with an inline parameter may not have its address taken. Does =
anyone see another gotcha?</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=_FA2642CD-184D-48D4-B8C6-2F327956433E--

.


Author: David Krauss <potswa@gmail.com>
Date: Mon, 19 May 2014 12:40:40 +0800
Raw View
On 2014-05-19, at 12:32 PM, David Krauss <potswa@gmail.com> wrote:

> The compromise viz. hidden templating is that an inline function with an =
inline parameter may not have its address taken. Does anyone see another go=
tcha?

Oh, that's not a limitation, it's more subtle. A function with inline param=
eters may have a number of object code implementations, each with linkage, =
for its various non-inlined call sites. These would all be effectively anon=
ymous. Taking the address would effectively refer to a different object cod=
e with the inline specifiers discarded. This makes sense because inline doe=
s not form part of the type of a variable, and hence it's not part of the f=
unction signature either.

The inline specifier should be prohibited from parameters in function abstr=
act-declarators, that's all.

--=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, 21 May 2014 13:22:05 -0400
Raw View
On 2014-05-14 18:23, David Rodr=C3=ADguez Ibeas wrote:
> On Wed, May 14, 2014 at 4:52 PM, Hyman Rosen wrote:
>> I propose to allow function parameter declarations to be prefixed with [=
&]*.
>>  *Doing so would cause those parameters to be *passed by lambda*. That
>> is, when the function is called, the argument expression for that parame=
ter
>> is not evaluated.  Instead, it is wrapped in a 0-parameter
>> capture-by-reference lambda that returns that expression, and the lambda=
 is
>> passed to the function.  When the function would access the variable. it
>> calls the lambda instead and uses its return value (and it may do so any
>> number of times, including 0).

This has come up before, but this seems like a reasonable syntax for the
feature. I like!

However...

> From a user point of view, I am not too fond of the idea of the lambda
> being evaluated on each use inside the function.

I must strongly agree with this; if the lambda is evaluated at all, it
must be evaluated exactly once. In any other direction lies madness.

That said, the whole *point* of the feature is to allow that the side
effects are *not* evaluated. Provided the lambda is evaluated zero or
one time(s), I don't see a technical problem. (Functions using this will
of course need to be well documented, but that's not the standard's
problem.)

> This would break the use case for 'repeat'

IMO something like 'repeat' should take an explicit lambda.

> I am not sure how to properly encode const-volatile into the syntax.

I don't think there is an issue here; the type w/o '[&]' is the return
type of the lambda, which may have CV qualifiers as usual. All we're
doing is moving the execution point of the code from caller to callee.

As an aside... this is somewhat covered elsewhere, but I'd probably try
to implement this at the compiler level without having "traditional"
types defined for the "functor". IOW, the actual parameter passed would
be a pair of pointers providing an instruction address and an opaque
pointer (e.g. stack frame of the caller, pointer to a single variable
being manipulated, etc.); to evaluate the parameter, the callee provides
the stack address in a well known location (e.g. register) and jumps to
the instruction address. Further, the compiler would be free to elide
all of this if the callee is inlined. The use site is responsible for
ensuring the lambda is only evaluated once.

This assumes of course that the lambda is not copyable, but I'd say
that's a given. Use of a "lambda" is more of an implementation detail;
the feature is really that the code that provides the parameter value is
not executed immediately (or, possibly, at all).

IOW:

void foo([&] int bar)
{
  // This *evaluates* the lambda; no copying is allowed
  something =3D bar;
}

Similar with returning the parameter. (I'll leave open to discussion if
an inline function returning a delayed parameter value may delay
evaluation even further after the call site. But probably not.)

Relative to the above, I *do* think there is benefit to having this as a
language feature, especially if the dispatch uses a fast calling
convention (i.e. the "lambda" is responsible for all stack
manipulations, register saving, etc., which would allow these to be
elided entirely in some cases). This isn't possible with e.g. std::lazy,
both because the caller must explicitly pass a lambda (makes Boolean
operators especially ugly), and because there is a minimum overhead that
the compiler cannot elide.

--=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: Nicola Gigante <nicola.gigante@gmail.com>
Date: Thu, 22 May 2014 07:59:45 +0200
Raw View
Il giorno 21/mag/2014, alle ore 19:22, Matthew Woehlke <mw_triad@users.sour=
ceforge.net> ha scritto:
>=20
>> On 2014-05-14 18:23, David Rodr=C3=ADguez Ibeas wrote:
>>> On Wed, May 14, 2014 at 4:52 PM, Hyman Rosen wrote:
>>> I propose to allow function parameter declarations to be prefixed with =
[&]*.
>>> *Doing so would cause those parameters to be *passed by lambda*. That
>>> is, when the function is called, the argument expression for that param=
eter
>>> is not evaluated.  Instead, it is wrapped in a 0-parameter
>>> capture-by-reference lambda that returns that expression, and the lambd=
a is
>>> passed to the function.  When the function would access the variable. i=
t
>>> calls the lambda instead and uses its return value (and it may do so an=
y
>>> number of times, including 0).
> This has come up before, but this seems like a reasonable syntax for the
> feature. I like!

> However...
>=20
>> From a user point of view, I am not too fond of the idea of the lambda
>> being evaluated on each use inside the function.
>=20
> I must strongly agree with this; if the lambda is evaluated at all, it
> must be evaluated exactly once. In any other direction lies madness.
>=20

I agree! This is more in line with the functional spirit of such a proposal=
.. That's easy achievable by making sure that the wrapping lambda caches the=
 result in a local variable the first time it is called.=20

> That said, the whole *point* of the feature is to allow that the side
> effects are *not* evaluated. Provided the lambda is evaluated zero or
> one time(s), I don't see a technical problem. (Functions using this will
> of course need to be well documented, but that's not the standard's
> problem.)
>=20
>> This would break the use case for 'repeat'
>=20
> IMO something like 'repeat' should take an explicit lambda.
>=20
>> I am not sure how to properly encode const-volatile into the syntax.
>=20
> I don't think there is an issue here; the type w/o '[&]' is the return
> type of the lambda, which may have CV qualifiers as usual. All we're
> doing is moving the execution point of the code from caller to callee.
>=20

It can be not so simple, consider:

void log(std::string const& message) {
   if(have_logs)
      std::cerr << message;
}

This is fine while this is not:

void log(std::string const& [&] message) {
   if(have_logs)
      std::cerr << message;
}

This would mean that the implicit lambda is _returning_ a reference to a co=
nst string? inside the lambda it would be in 90% of cases a local temporary=
, and you're returning a dangling reference, unless temporaries of the argu=
ment expression don't get different rules for their lifetime.

> As an aside... this is somewhat covered elsewhere, but I'd probably try
> to implement this at the compiler level without having "traditional"
> types defined for the "functor". IOW, the actual parameter passed would
> be a pair of pointers providing an instruction address and an opaque
> pointer (e.g. stack frame of the caller, pointer to a single variable
> being manipulated, etc.); to evaluate the parameter, the callee provides
> the stack address in a well known location (e.g. register) and jumps to
> the instruction address. Further, the compiler would be free to elide
> all of this if the callee is inlined. The use site is responsible for
> ensuring the lambda is only evaluated once.
>=20
> This assumes of course that the lambda is not copyable, but I'd say
> that's a given. Use of a "lambda" is more of an implementation detail;
> the feature is really that the code that provides the parameter value is
> not executed immediately (or, possibly, at all).
>=20
> IOW:
>=20
> void foo([&] int bar)
> {
>  // This *evaluates* the lambda; no copying is allowed
>  something =3D bar;
> }
>=20
> Similar with returning the parameter. (I'll leave open to discussion if
> an inline function returning a delayed parameter value may delay
> evaluation even further after the call site. But probably not.)
>=20

If you allow "delayed" return values you should make sure local variables a=
re captured by value (while the ones in the case of a function argument can=
 and should be captured by reference). Maybe by allow the user to write [=
=3D] instead of [&].

Now, if a function has a delayed return value and returns a delayed paramet=
er, the parameter should not be evaluated, exactly as any other part of the=
 returning expression:

int [=3D] foo(int n) {
  return n * 2; // here n it's not evaluated
}

int [=3D] foo(int [&] n) {
  return n * 2; // here it shouldn't either
}

Note that here (IMHO) the delayed parameter would capture caller's variable=
s by reference, while the return value captures by value, in this case mean=
ing that it captures by value the variable 'n', but not the variables captu=
red by 'n' (this is in line with what would happen with an explicit lambda)

> Relative to the above, I *do* think there is benefit to having this as a
> language feature, especially if the dispatch uses a fast calling
> convention (i.e. the "lambda" is responsible for all stack
> manipulations, register saving, etc., which would allow these to be
> elided entirely in some cases). This isn't possible with e.g. std::lazy,
> both because the caller must explicitly pass a lambda (makes Boolean
> operators especially ugly), and because there is a minimum overhead that
> the compiler cannot elide.
>=20

It has to be considered the fact that a function taking explicitly a lambda=
 would be a template function, while if you allow such a delayed parameter =
in non-template functions then you have to implement the feature with a sor=
t of type erasure for the lambda, which disable a lot of optimizations. Of =
course this could be simply be an implementation problem, and restricting d=
elayed parameters to template functions for this reason seems artificial. N=
evertheless the standard wording should be clear that an implementation is =
allowed to make multiple instantiations of a function template with a delay=
ed parameter, to allow it to avoid type erasure when it's possible.

> --=20
> Matthew
>=20

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: Diggory Blake <diggsey@googlemail.com>
Date: Wed, 21 May 2014 23:29:07 -0700 (PDT)
Raw View
------=_Part_2279_16030932.1400740147338
Content-Type: text/plain; charset=UTF-8



On Thursday, 22 May 2014 06:59:45 UTC+1, Nicola Gigante wrote:

> It can be not so simple, consider:
>
> void log(std::string const& message) {
>    if(have_logs)
>       std::cerr << message;
> }
>
> This is fine while this is not:
>
> void log(std::string const& [&] message) {
>    if(have_logs)
>       std::cerr << message;
> }
>
> This would mean that the implicit lambda is _returning_ a reference to a
> const string? inside the lambda it would be in 90% of cases a local
> temporary, and you're returning a dangling reference, unless temporaries of
> the argument expression don't get different rules for their lifetime.
>

The compiler is free to generate whatever code it wants, it doesn't have to
be limited to the types of lambdas that are easy to write in C++. For
example:

lazy_func(a + b);

Instead of the compiler just wrapping the expression 'a + b' in a lambda,
you could specify that the compiler should generate a lambda which when
invoked will be equivalent to jumping out of the function "lazy_func",
evaluating "a + b" as though it was just a normal parameter, and then
jumping back into "lazy_func" at the point where it left off. It would be
exactly the inverse of how "yield return" works in C#.

In short, the lifetimes of expressions in the parameter list would end at
the same time as if they were not being lazily evaluated. Passing by
reference would still work correctly with no difference from before.

--

---
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_2279_16030932.1400740147338
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Thursday, 22 May 2014 06:59:45 UTC+1, Nicola Gi=
gante  wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin: 0;margi=
n-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">It can be not=
 so simple, consider:
<br>
<br>void log(std::string const&amp; message) {
<br>&nbsp; &nbsp;if(have_logs)
<br>&nbsp; &nbsp; &nbsp; std::cerr &lt;&lt; message;
<br>}
<br>
<br>This is fine while this is not:
<br>
<br>void log(std::string const&amp; [&amp;] message) {
<br>&nbsp; &nbsp;if(have_logs)
<br>&nbsp; &nbsp; &nbsp; std::cerr &lt;&lt; message;
<br>}
<br>
<br>This would mean that the implicit lambda is _returning_ a reference to =
a const string? inside the lambda it would be in 90% of cases a local tempo=
rary, and you're returning a dangling reference, unless temporaries of the =
argument expression don't get different rules for their lifetime.
<br></blockquote><div><br>The compiler is free to generate whatever code it=
 wants, it doesn't have to be limited to the types of lambdas that are easy=
 to write in C++. For example:<br><br>lazy_func(a + b);<br><br>Instead of t=
he compiler just wrapping the expression 'a + b' in a lambda, you could spe=
cify that the compiler should generate a lambda which when invoked will be =
equivalent to jumping out of the function "lazy_func", evaluating "a + b" a=
s though it was just a normal parameter, and then jumping back into "lazy_f=
unc" at the point where it left off. It would be exactly the inverse of how=
 "yield return" works in C#.<br><br>In short, the lifetimes of expressions =
in the parameter list would end at the same time as if they were not being =
lazily evaluated. Passing by reference would still work correctly with no d=
ifference from before.<br></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_2279_16030932.1400740147338--

.


Author: Nicola Gigante <nicola.gigante@gmail.com>
Date: Thu, 22 May 2014 09:27:52 +0200
Raw View
--Apple-Mail=_DCBFB9E2-0845-452E-82D4-D0261E772CC7
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=ISO-8859-1


Il giorno 22/mag/2014, alle ore 08:29, Diggory Blake <diggsey@googlemail.co=
m> ha scritto:

>=20
>=20
> On Thursday, 22 May 2014 06:59:45 UTC+1, Nicola Gigante wrote:
> It can be not so simple, consider:=20
>=20
> void log(std::string const& message) {=20
>    if(have_logs)=20
>       std::cerr << message;=20
> }=20
>=20
> This is fine while this is not:=20
>=20
> void log(std::string const& [&] message) {=20
>    if(have_logs)=20
>       std::cerr << message;=20
> }=20
>=20
> This would mean that the implicit lambda is _returning_ a reference to a =
const string? inside the lambda it would be in 90% of cases a local tempora=
ry, and you're returning a dangling reference, unless temporaries of the ar=
gument expression don't get different rules for their lifetime.=20
>=20
> The compiler is free to generate whatever code it wants, it doesn't have =
to be limited to the types of lambdas that are easy to write in C++. For ex=
ample:
>=20
> lazy_func(a + b);
>=20
> Instead of the compiler just wrapping the expression 'a + b' in a lambda,=
 you could specify that the compiler should generate a lambda which when in=
voked will be equivalent to jumping out of the function "lazy_func", evalua=
ting "a + b" as though it was just a normal parameter, and then jumping bac=
k into "lazy_func" at the point where it left off. It would be exactly the =
inverse of how "yield return" works in C#.
>=20
> In short, the lifetimes of expressions in the parameter list would end at=
 the same time as if they were not being lazily evaluated. Passing by refer=
ence would still work correctly with no difference from before.
>=20

Of course the compiler can do it, but I'm not sure it's exactly the right a=
pproach. Usually, temporaries' lifetime is that of their full expression,=
=20
and they get destroyed in the reverse order of creation, right? It seems to=
 me that this means that the caller has to run different cleanups for=20
the case where the callee has evaluated the parameter and the case where it=
 has not, which to me sounds weird and complex to implement.
It also adds complexity to the calling convention.

Rather than to state the temporaries' lifetime in terms of what could have =
happened if the argument were not passed by lambda, I'd make=20
them belong to the callee scope, which sounds more clear to me. Their lifet=
ime could be that of local variables of the callee (like any other argument=
). This seems to me more natural, and that's what I was suggesting in my la=
st email, I'm sorry if I've not explained myself very=20
clearly.

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=_DCBFB9E2-0845-452E-82D4-D0261E772CC7
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=ISO-8859-1

<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 22/mag/2014, alle ore 08:29, Diggory Blake &lt;<a href=3D"mailto:diggsey@=
googlemail.com">diggsey@googlemail.com</a>&gt; ha scritto:</div><br class=
=3D"Apple-interchange-newline"><blockquote type=3D"cite"><div dir=3D"ltr"><=
br><br>On Thursday, 22 May 2014 06:59:45 UTC+1, Nicola Gigante  wrote:<br><=
blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;bord=
er-left: 1px #ccc solid;padding-left: 1ex;">It can be not so simple, consid=
er:
<br>
<br>void log(std::string const&amp; message) {
<br>&nbsp; &nbsp;if(have_logs)
<br>&nbsp; &nbsp; &nbsp; std::cerr &lt;&lt; message;
<br>}
<br>
<br>This is fine while this is not:
<br>
<br>void log(std::string const&amp; [&amp;] message) {
<br>&nbsp; &nbsp;if(have_logs)
<br>&nbsp; &nbsp; &nbsp; std::cerr &lt;&lt; message;
<br>}
<br>
<br>This would mean that the implicit lambda is _returning_ a reference to =
a const string? inside the lambda it would be in 90% of cases a local tempo=
rary, and you're returning a dangling reference, unless temporaries of the =
argument expression don't get different rules for their lifetime.
<br></blockquote><div><br>The compiler is free to generate whatever code it=
 wants, it doesn't have to be limited to the types of lambdas that are easy=
 to write in C++. For example:<br><br>lazy_func(a + b);<br><br>Instead of t=
he compiler just wrapping the expression 'a + b' in a lambda, you could spe=
cify that the compiler should generate a lambda which when invoked will be =
equivalent to jumping out of the function "lazy_func", evaluating "a + b" a=
s though it was just a normal parameter, and then jumping back into "lazy_f=
unc" at the point where it left off. It would be exactly the inverse of how=
 "yield return" works in C#.<br><br>In short, the lifetimes of expressions =
in the parameter list would end at the same time as if they were not being =
lazily evaluated. Passing by reference would still work correctly with no d=
ifference from before.<br></div></div><div><br class=3D"webkit-block-placeh=
older"></div></blockquote><div><br></div><div>Of course the compiler can do=
 it, but I&rsquo;m not sure it&rsquo;s exactly the right approach. Usually,=
 temporaries&rsquo; lifetime is that of their full expression,&nbsp;</div><=
div>and they get destroyed in the reverse order of creation, right? It seem=
s to me that this means that the caller has to run different cleanups for&n=
bsp;</div><div>the case where the callee has evaluated the parameter and th=
e case where it has not, which to me sounds weird and complex to implement.=
</div><div>It also adds complexity to the calling convention.</div><div><br=
></div><div>Rather than to state the temporaries&rsquo; lifetime in terms o=
f what could have happened if the argument were not passed by lambda, I&rsq=
uo;d make&nbsp;</div><div>them belong to the callee scope, which sounds mor=
e clear to me. Their lifetime could be that of local variables of the calle=
e (like any other argument). This seems to me more natural, and that&rsquo;=
s what I was suggesting in my last email, I&rsquo;m sorry if I&rsquo;ve not=
 explained myself very&nbsp;</div><div>clearly.</div><div><br></div><div>By=
e,</div><div>Nicola</div><div><br></div><div><br></div><div><br></div><div>=
<br></div></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=_DCBFB9E2-0845-452E-82D4-D0261E772CC7--

.


Author: =?UTF-8?Q?David_Rodr=C3=ADguez_Ibeas?= <dibeas@ieee.org>
Date: Thu, 22 May 2014 11:18:20 -0400
Raw View
--001a11c1317c8bf94704f9fe9f26
Content-Type: text/plain; charset=UTF-8

I am trying to grasp all of the implications, but in the meantime just a
comment:


On Thu, May 22, 2014 at 1:59 AM, Nicola Gigante <nicola.gigante@gmail.com>wrote:

> This would mean that the implicit lambda is _returning_ a reference to a
> const string? inside the lambda it would be in 90% of cases a local
> temporary, and you're returning a dangling reference, unless temporaries of
> the argument expression don't get different rules for their lifetime.
>
>
The suggestion for guaranteeing the single evaluation of the function was
to have the lambda 'cache' the value on the first execution. The
(not-really-a) lambda would have a member (std::optional-like) holding the
value and return a reference to that.

[I meant the above to be the "just a comment", but I seem to have overdone
the "just" below]:

I am not sure this is the correct approach, I was thinking on a different
possible implementation: it is up to the function to evaluate the lambda
*once* and cache the result.

In both cases the cv-qualifiers and reference types are tricky to handle. I
guess part of the problem I am having here is that the syntax looks the
same as a lambda definition syntax, but the semantics must be different.
The function signature does not deal with how the arguments are created,
but how they are going to be used. That is, the [&] is unrelated to how the
compiler generated lazy evaluation will capture the environment. The type
and cv-qualifiers relate to how the function will use the result of the
lambda, not what the expression yields.

Given:

void f(std::string const & [&] arg);
std::string value();
std::string & reference();

For the use case 'f(value())', the generated code would have to call the
function, store the returned value inside the lambda and then return a
reference to that cached value. But in the case of 'f(reference())' the
generated code would have to store a pointer to the result of 'reference()'
and then return the result of dereferencing that pointer. Up to here it
seems sane enough.

Now if the function was:

void g(std::string [&] arg);

I imagine that in this case the generated code would have to be the same,
but return from the internal storage by value, which means that in the case
of 'g(value())' two copies of the string would have to be taken. (The
generated code not knowing how many times it is going to be called would
evaluate 'value()' and store it internally, the first evaluation would then
have to create a second copy from the cache into the context of 'g'). In
the case of 'g(reference())' the generated code could still store the
pointer, and do the copies on demand.

While this provides some sane semantics from the point of view of the
implementation of the generator for the lambda, it would be at the very
least surprising if the implementation of 'g' looked like this:

void g(std::string [&] arg) {
    arg = "the new value";
    std::cout << arg;                  // This is not "the new value"!!!
}

In the same way, it would be up for discussion whether this third option
should be allowed:

void h(std::string & [&] arg);
h(value());                              // compiler error?

Should that be allowed? The instinctive answer is that it should not, but
this case is not all that different from 'std::bind' with a bound object
for a non-const rvalue-reference argument:

void f(std::string &);
std::bind(&f, value());

Even though 'value()' yields an rvalue that cannot be bound by the
non-const l-value reference of 'f', the fact that it is *copied* into the
binder makes the above code legal. So what should it be? Since the
generated code will cache, do we follow 'std::bind' way and accept the
code? Or do we follow the somehow more intuitive path and fail to compile?

Going back to the basic syntax, I am not sure how we could take advantage
of the possibility of using [&] vs. [=] for the capture (1). Remember that
this is decided at the time that the function is defined, not at the
caller's site, so we don't have really any context as of whether the caller
wants to capture values, or references. That decision is taken away from
the caller, although they can still achieve the same results by externally
wrapping in a lambda:

void caller() {
   //...
   f([=]{ return a+b; }());    // captures copy
   f([&]{ return a+b; }());    // captures reference
   f(a+b);                        // whatever is decided if the feature is
accepted
}

In the first two cases, the expression being passed is the evaluation of
the lambda.

(1) Thought: Use [=] and [&] to determine whether the expression will be
evaluated multiple times. Allowing 'void repeat(int count, void [&] arg)'
and 'void single_evaluation(std::string const & [=] arg)'

There are other issues to be considered, like whether conversions from the
result of the expression to the type spelled in the argument to the
function should be done (most probably similar to 'std::function') and when
(for a lambda that caches the value, should the conversion be done from the
evaluation to the cache, or from the cache to the function?),  or what can
be done inside the function with the argument that is captured by lambda:

void f(std::string [&] arg) {
    functors.emplace_back([=]{ return arg; });  // (a)
    functors.emplace_back([&]{ return arg; });  // (b)
}

I can see this proposal as being useful in some cases, but there are quite
a bit of details that would have to be ironed out, and the end result has
to be a feature that is natural and hardly confusing (well, with some
meaning of 'confusing' in the context of the C++ standard...), or we risk
opening a new can of worms by providing an easy to misuse feature.

    David

P.S. I really meant to write a short comment, sorry for the flood for those
that believed the first paragraph.

--

---
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/.

--001a11c1317c8bf94704f9fe9f26
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">I am trying to grasp all of the implications, but in the m=
eantime just a comment:<div class=3D"gmail_extra"><br><br><div class=3D"gma=
il_quote">On Thu, May 22, 2014 at 1:59 AM, Nicola Gigante <span dir=3D"ltr"=
>&lt;<a href=3D"mailto:nicola.gigante@gmail.com" target=3D"_blank">nicola.g=
igante@gmail.com</a>&gt;</span> wrote:<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex">This would mean that the implicit lambda is =
_returning_ a reference to a const string? inside the lambda it would be in=
 90% of cases a local temporary, and you&#39;re returning a dangling refere=
nce, unless temporaries of the argument expression don&#39;t get different =
rules for their lifetime.<br>

<div class=3D""><br></div></blockquote><div><br>The suggestion for guarante=
eing the single evaluation of the function was to have the lambda &#39;cach=
e&#39; the value on the first execution. The (not-really-a) lambda would ha=
ve a member (std::optional-like) holding the value and return a reference t=
o that. <br>
<br>[I meant the above to be the &quot;just a comment&quot;, but I seem to =
have overdone the &quot;just&quot; below]:<br><br>I am not sure this is the=
 correct approach, I was thinking on a different possible implementation: i=
t is up to the function to evaluate the lambda *once* and cache the result.=
<br>
<br>In both cases the cv-qualifiers and reference types are tricky to handl=
e. I guess part of the problem I am having here is that the syntax looks th=
e same as a lambda definition syntax, but the semantics must be different. =
The function signature does not deal with how the arguments are created, bu=
t how they are going to be used. That is, the [&amp;] is unrelated to how t=
he compiler generated lazy evaluation will capture the environment. The typ=
e and cv-qualifiers relate to how the function will use the result of the l=
ambda, not what the expression yields.<br>
<br>Given:<br><br>void f(std::string const &amp; [&amp;] arg);<br>std::stri=
ng value();<br>std::string &amp; reference();<br><br>For the use case &#39;=
f(value())&#39;, the generated code would have to call the function, store =
the returned value inside the lambda and then return a reference to that ca=
ched value. But in the case of &#39;f(reference())&#39; the generated code =
would have to store a pointer to the result of &#39;reference()&#39; and th=
en return the result of dereferencing that pointer. Up to here it seems san=
e enough.<br>
<br>Now if the function was:<br><br>void g(std::string [&amp;] arg);<br><br=
>I imagine that in this case the generated code would have to be the same, =
but return from the internal storage by value, which means that in the case=
 of &#39;g(value())&#39; two copies of the string would have to be taken. (=
The generated code not knowing how many times it is going to be called woul=
d evaluate &#39;value()&#39; and store it internally, the first evaluation =
would then have to create a second copy from the cache into the context of =
&#39;g&#39;). In the case of &#39;g(reference())&#39; the generated code co=
uld still store the pointer, and do the copies on demand.<br>
<br>While this provides some sane semantics from the point of view of the i=
mplementation of the generator for the lambda, it would be at the very leas=
t surprising if the implementation of &#39;g&#39; looked like this:<br>
<br>void g(std::string [&amp;] arg) {<br>=C2=A0 =C2=A0 arg =3D &quot;the ne=
w value&quot;;<br>=C2=A0 =C2=A0 std::cout &lt;&lt; arg; =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0// This is not &quot;the new v=
alue&quot;!!!<br>}<br><br>In the same way, it would be up for discussion wh=
ether this third option should be allowed:<br>
<br>void h(std::string &amp; [&amp;] arg);<br>h(value()); =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0// compiler error?<br><br>Should that be allowed? The instinct=
ive answer is that it should not, but this case is not all that different f=
rom &#39;std::bind&#39; with a bound object for a non-const rvalue-referenc=
e argument:<br>
<br>void f(std::string &amp;);<br>std::bind(&amp;f, value());<br><br>Even t=
hough &#39;value()&#39; yields an rvalue that cannot be bound by the non-co=
nst l-value reference of &#39;f&#39;, the fact that it is *copied* into the=
 binder makes the above code legal. So what should it be? Since the generat=
ed code will cache, do we follow &#39;std::bind&#39; way and accept the cod=
e? Or do we follow the somehow more intuitive path and fail to compile?<br>
<br>Going back to the basic syntax, I am not sure how we could take advanta=
ge of the possibility of using [&amp;] vs. [=3D] for the capture (1). Remem=
ber that this is decided at the time that the function is defined, not at t=
he caller&#39;s site, so we don&#39;t have really any context as of whether=
 the caller wants to capture values, or references. That decision is taken =
away from the caller, although they can still achieve the same results by e=
xternally wrapping in a lambda:<br>
<br></div><div>void caller() {<br>=C2=A0 =C2=A0//...<br>=C2=A0 =C2=A0f([=3D=
]{ return a+b; }()); =C2=A0 =C2=A0// captures copy<br>=C2=A0 =C2=A0f([&amp;=
]{ return a+b; }()); =C2=A0 =C2=A0// captures reference<br>=C2=A0 =C2=A0f(a=
+b); =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0// whatever is decided if the feature is accepted<br>
}<br><br>In the first two cases, the expression being passed is the evaluat=
ion of the lambda.<br><br>(1) Thought: Use [=3D] and [&amp;] to determine w=
hether the expression will be evaluated multiple times. Allowing &#39;void =
repeat(int count, void [&amp;] arg)&#39; and &#39;void single_evaluation(st=
d::string const &amp; [=3D] arg)&#39;<br>
<br>There are other issues to be considered, like whether conversions from =
the result of the expression to the type spelled in the argument to the fun=
ction should be done (most probably similar to &#39;std::function&#39;) and=
 when (for a lambda that caches the value, should the conversion be done fr=
om the evaluation to the cache, or from the cache to the function?), =C2=A0=
or what can be done inside the function with the argument that is captured =
by lambda:<br>
<br>void f(std::string [&amp;] arg) {<br>=C2=A0 =C2=A0 functors.emplace_bac=
k([=3D]{ return arg; }); =C2=A0// (a)<br>=C2=A0 =C2=A0 functors.emplace_bac=
k([&amp;]{ return arg; }); =C2=A0// (b)<br>}<br><br>I can see this proposal=
 as being useful in some cases, but there are quite a bit of details that w=
ould have to be ironed out, and the end result has to be a feature that is =
natural and hardly confusing (well, with some meaning of &#39;confusing&#39=
; in the context of the C++ standard...), or we risk opening a new can of w=
orms by providing an easy to misuse feature.<br>
<br>=C2=A0 =C2=A0 David<br><br>P.S. I really meant to write a short comment=
, sorry for the flood for those that believed the first paragraph.</div></d=
iv></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 />

--001a11c1317c8bf94704f9fe9f26--

.


Author: Jean-Marc Bourguet <jm.bourguet@gmail.com>
Date: Thu, 22 May 2014 09:03:52 -0700 (PDT)
Raw View
------=_Part_148_28088141.1400774633098
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

Le mercredi 14 mai 2014 13:52:03 UTC-7, Hyman Rosen a =C3=A9crit :
>
> I propose to allow function parameter declarations to be prefixed with [&=
]
> *. *
>

Two references which may interest some:

- Algol call by name is quite similar to this "pass-by-lambda" if the=20
function is evaluated every time it is used.  If my memory is correct, that=
=20
behavior was due to an error in the specification (and thus was not=20
intended).  Yet it has been (ab)-used to pass anonymous functions (pass a=
=20
reference to a variable, pass an expression using that variable, modify the=
=20
variable, reevaluate the expression).  I see no interest in that as we have=
=20
better and clearer way to achieve this.

- Functional language lazy evaluations is quite similar if the function=20
result is memoized.  The major interest of lazy evaluation comes when you=
=20
can put unevalated reference in a data structure (giving infinite data=20
structure),  I think it would be interesting to see how far in that=20
direction it is possible to go.

Yours,



--=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_148_28088141.1400774633098
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Le mercredi 14 mai 2014 13:52:03 UTC-7, Hyman Rosen a =C3=
=A9crit&nbsp;:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-l=
eft: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"=
>I propose to allow function parameter declarations to be prefixed with <fo=
nt face=3D"courier new, monospace" style=3D"font-weight:bold">[&amp;]</font=
><b style=3D"font-family:arial,sans-serif">.&nbsp;</b></div></blockquote><d=
iv><br></div><div>Two references which may interest some:</div><div><br></d=
iv><div>- Algol call by name is quite similar to this "pass-by-lambda" if t=
he function is evaluated every time it is used. &nbsp;If my memory is corre=
ct, that behavior was due to an error in the specification (and thus was no=
t intended). &nbsp;Yet it has been (ab)-used to pass anonymous functions (p=
ass a reference to a variable, pass an expression using that variable, modi=
fy the variable, reevaluate the expression). &nbsp;I see no interest in tha=
t as we have better and clearer way to achieve this.</div><div><br></div><d=
iv>- Functional language lazy evaluations is quite similar if the function =
result is memoized. &nbsp;The major interest of lazy evaluation comes when =
you can put unevalated reference in a data structure (giving infinite data =
structure), &nbsp;I think it would be interesting to see how far in that di=
rection it is possible to go.</div><div><br></div><div>Yours,</div><div><br=
></div><div><br></div><div><br></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_148_28088141.1400774633098--

.


Author: Matthew Woehlke <mw_triad@users.sourceforge.net>
Date: Thu, 22 May 2014 12:42:23 -0400
Raw View
On 2014-05-22 01:59, Nicola Gigante wrote:
> Il giorno 21/mag/2014, alle ore 19:22, Matthew Woehlke ha scritto:
>> if the lambda is evaluated at all, it must be evaluated exactly
>> once.
>
> That's easy achievable by making sure that the wrapping lambda caches
> the result in a local variable the first time it is called.

I think it would be more performing to require that the compiler ensure
this at the use site. That way no extra code is needed if the lambda is
only ever used once anyway, or if the compiler is able to trivially
store the result in a local temporary without later having to check if
it has already done so or not. Else, if the compiler *does* need to add
guards, speculative branching can allow the lambda to be called
immediately, and the result thrown out if it was already called.
Otherwise you always have to wait on the call instruction before you can
continue.

That said, I'd be inclined to leave how this is enforced up to the
compiler writers, if feasible to do so.

>> I don't think there is an issue here; the type w/o '[&]' is the return
>> type of the lambda, which may have CV qualifiers as usual. All we're
>> doing is moving the execution point of the code from caller to callee.
>
> It can be not so simple, consider:
>
> void log(std::string const& message) {
>    if(have_logs)
>       std::cerr << message;
> }
>
> This is fine while this is not:
>
> void log(std::string const& [&] message) {
>    if(have_logs)
>       std::cerr << message;
> }
>
> This would mean that the implicit lambda is _returning_ a reference to a const string?

Yes.

> inside the lambda it would be in 90% of cases a local temporary, and
> you're returning a dangling reference, unless temporaries of the
> argument expression don't get different rules for their lifetime.

Hmm... normally this is not an issue as the lifetime of the parameter is
at least the lifetime of the function call. Maybe lazy parameters should
have an optional destructor?

Alternatively, the caller could execute an unconditional jump following
the call to an address that is initially set to bypass the cleanup code
as if the parameters were not delayed, which the "lambda" resets to call
the cleanup code.

Or reference types could simply be disallowed.

> If you allow "delayed" return values you should make sure local
> variables are captured by value (while the ones in the case of a
> function argument can and should be captured by reference).

....or like above, omit the clean-up code entirely and the return "value"
would be three instruction pointers; one to clean up already allocated
values if the return value is not used, one to clean up everything, and
of course one to evaluate the return value.

This likely would / should require that the delay is used only to short
circuit computation of a return value if the caller does not use it
(i.e. is not assigned to storage). That said... I know I've come across
cases where this is useful. (For example, the return iterator when
erasing from a container, if for some reason it is non-trivial to
compute the same, as the caller may not need it.)

> Now, if a function has a delayed return value and returns a delayed
> parameter, the parameter should not be evaluated, exactly as any
> other part of the returning expression:

Pedantic: if the delayed parameter is *only* involved in computing a
delayed return value, then yes.

> It has to be considered the fact that a function taking explicitly a
> lambda would be a template function, while if you allow such a delayed
> parameter in non-template functions then you have to implement the
> feature with a sort of type erasure for the lambda, which disable a lot
> of optimizations.

The way I envision this working is roughly like:

  void log_info([&] string const& msg)
  {
    if (log_level >= INFO)
      log(msg);
  }

  void foo()
  {
    log_info(complicated());
  }

....which is transformed to:

  void log_info(string const& ([[fastcall]] *_msg_ip)(void*),
                void* _msg_pp)
  {
    if (log_level >= INFO)
    {
      // 'msg' only used once; no need to guard against multiple calls
      log((*_msg_ip)(_msg_pp));
    }
  }

  void foo()
  {
    struct __s
    {
      void* next;
      char result[sizeof(string)];
    };

    [[fastcall]] string const& __i(void* p)
    {
      _p = (__s*)p;
      _p->next = &_cleanup;
      auto& s = new (_p->result) string(complicated());
      return s;
    }

    __s __p = {&_end}; // reserve stack space
    log_info(&__i, &__d, &__p);
    goto *_.next;

  _end:
    return;

  _cleanup:
    (string*)(_.result)->~string();
    goto _end;
  }

(Hopefully I got that right; please excuse any errors.)

I'm not sure how that is significantly preventing optimizations? Except
for a couple of additional jumps, the code should be similar to what
would be generated for a non-delayed parameter.

(Note: if reference types are disallowed, the above is essentially the
same except without the placement new and cleanup instruction pointer.)

--
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: Diggory Blake <diggsey@googlemail.com>
Date: Thu, 22 May 2014 09:57:06 -0700 (PDT)
Raw View
------=_Part_2845_15523975.1400777827135
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable



On Thursday, 22 May 2014 08:27:52 UTC+1, Nicola Gigante wrote:
>
>
> Of course the compiler can do it, but I=E2=80=99m not sure it=E2=80=99s e=
xactly the right=20
> approach. Usually, temporaries=E2=80=99 lifetime is that of their full ex=
pression,=20
> and they get destroyed in the reverse order of creation, right? It seems=
=20
> to me that this means that the caller has to run different cleanups for=
=20
> the case where the callee has evaluated the parameter and the case where=
=20
> it has not, which to me sounds weird and complex to implement.
> It also adds complexity to the calling convention.
>
> Rather than to state the temporaries=E2=80=99 lifetime in terms of what c=
ould have=20
> happened if the argument were not passed by lambda, I=E2=80=99d make=20
> them belong to the callee scope, which sounds more clear to me. Their=20
> lifetime could be that of local variables of the callee (like any other=
=20
> argument). This seems to me more natural, and that=E2=80=99s what I was s=
uggesting=20
> in my last email, I=E2=80=99m sorry if I=E2=80=99ve not explained myself =
very=20
> clearly.
>
> Bye,
> Nicola
>

 I don't think it would be that strange, here's one way I see it possibly=
=20
working:
- Space is reserved of the correct size and alignment for the parameter=20
type (let's use "Foo"). This can either be directly on the stack, or as a=
=20
field in the lambda (the advantage of the former being that the lambda=20
would only need to capture the stack pointer, and so should always be able=
=20
to take advantage of the small functor optimisation, regardless of=20
"sizeof(Foo)", but aside from performance the two are equivalent.
- This space is left unconstructed when the lambda is constructed, but when=
=20
the lambda is called for the first time, it evaluates the expression, and=
=20
the result of the expression is constructed directly in this empty space,=
=20
no copying or moving. This requires an extra boolean to track whether the=
=20
lambda has been evaluated or not.
- The lambda returns the newly constructed object, either by reference or=
=20
by value depending on the parameter qualifiers.
- In the lambda's destructor, it checks whether it was ever invoked, and if=
=20
so explicitly calls the destructor on the constructed object.

--=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_2845_15523975.1400777827135
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Thursday, 22 May 2014 08:27:52 UTC+1, Nicola Gi=
gante  wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-le=
ft: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div style=3D"wor=
d-wrap:break-word"><div><div><br></div><div>Of course the compiler can do i=
t, but I=E2=80=99m not sure it=E2=80=99s exactly the right approach. Usuall=
y, temporaries=E2=80=99 lifetime is that of their full expression,&nbsp;</d=
iv><div>and they get destroyed in the reverse order of creation, right? It =
seems to me that this means that the caller has to run different cleanups f=
or&nbsp;</div><div>the case where the callee has evaluated the parameter an=
d the case where it has not, which to me sounds weird and complex to implem=
ent.</div><div>It also adds complexity to the calling convention.</div><div=
><br></div><div>Rather than to state the temporaries=E2=80=99 lifetime in t=
erms of what could have happened if the argument were not passed by lambda,=
 I=E2=80=99d make&nbsp;</div><div>them belong to the callee scope, which so=
unds more clear to me. Their lifetime could be that of local variables of t=
he callee (like any other argument). This seems to me more natural, and tha=
t=E2=80=99s what I was suggesting in my last email, I=E2=80=99m sorry if I=
=E2=80=99ve not explained myself very&nbsp;</div><div>clearly.</div><div><b=
r></div><div>Bye,</div><div>Nicola</div></div></div></blockquote><div><br>&=
nbsp;I don't think it would be that strange, here's one way I see it possib=
ly working:<br>- Space is reserved of the correct size and alignment for th=
e parameter type (let's use "Foo"). This can either be directly on the stac=
k, or as a field in the lambda (the advantage of the former being that the =
lambda would only need to capture the stack pointer, and so should always b=
e able to take advantage of the small functor optimisation, regardless of "=
sizeof(Foo)", but aside from performance the two are equivalent.<br>- This =
space is left unconstructed when the lambda is constructed, but when the la=
mbda is called for the first time, it evaluates the expression, and the res=
ult of the expression is constructed directly in this empty space, no copyi=
ng or moving. This requires an extra boolean to track whether the lambda ha=
s been evaluated or not.<br>- The lambda returns the newly constructed obje=
ct, either by reference or by value depending on the parameter qualifiers.<=
br>- In the lambda's destructor, it checks whether it was ever invoked, and=
 if so explicitly calls the destructor on the constructed object.<br></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_2845_15523975.1400777827135--

.


Author: Matthew Woehlke <mw_triad@users.sourceforge.net>
Date: Thu, 22 May 2014 13:02:11 -0400
Raw View
On 2014-05-22 11:18, David Rodr=C3=ADguez Ibeas wrote:
> Given:
>=20
> std::string value();
> void g(std::string [&] arg);
>=20
> I imagine that in this case the generated code would have to be the same,
> but return from the internal storage by value, which means that in the ca=
se
> of 'g(value())' two copies of the string would have to be taken.

Why would RVO not kick in here? I certainly expect for value() to return
a moved (RVO'd) string; why wouldn't the "lambda" also do so?

> (The generated code not knowing how many times it is going to be=20
> called would evaluate 'value()' and store it internally, the first=20
> evaluation would then have to create a second copy from the cache
> into the context of 'g').

This is a great reason why it should be guaranteed that the "lambda"
itself is only ever called once, i.e. the function taking a delayed
parameter is responsible for ensuring that. (Besides the potential
optimization when the compiler can trivially ensure this without a guard
flag.)

> void g(std::string [&] arg) {
>     arg =3D "the new value";
>     std::cout << arg;                  // This is not "the new value"!!!
> }

If this doesn't print "the new value", IMHO the implementation is broken.

> void h(std::string & [&] arg);
> h(value());                              // compiler error?

Yes. IMO if you can't pass an expression through a regular parameter,
you can't through a delayed parameter either.

If the "lambda" doesn't need to do caching (IMO it shouldn't), these
issues don't exist. Delayed parameter evaluation should be exactly that;
*delayed evaluation*. Don't add additional logic (caching) to the logic
itself.

> Going back to the basic syntax, I am not sure how we could take advantage
> of the possibility of using [&] vs. [=3D] for the capture (1).

Maybe '[&]' is a bad syntax after all... maybe it should be
'[[delayed]]' (or '[[lazy]]', or what have you).

In fact, that might not be a bad thing... calling convention is
something of an issue, but at least you should get the same visible
behavior from a compiler that doesn't support delayed evaluation and
just silently does immediate evaluation. (For that matter, compilers
could provide both versions of such functions, which would allow code
built w/o delayed evaluation support to still link.)

> [The decision to capture by value or reference] is taken away from=20
> the caller, although they can still achieve the same results by
> externally wrapping in a lambda:

Why would you ever want to capture by value? The caller can neither
modify nor destroy the values itself while they are in scope of the
delayed parameter "lambda". Therefore I see no purpose to capturing by
value; at best, it just makes needless copies. (At worst, it prevents
the callee modifying the values in a way that is visible to the caller,
as would be the case for immediate evaluation.)

> (1) Thought: Use [=3D] and [&] to determine whether the expression will b=
e
> evaluated multiple times. Allowing 'void repeat(int count, void [&] arg)'
> and 'void single_evaluation(std::string const & [=3D] arg)'

Or, I'd be okay with this :-). (But then the semantics of '[=3D]' should
still be that the callee ensures single call.)

--=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: Diggory Blake <diggsey@googlemail.com>
Date: Thu, 22 May 2014 10:04:39 -0700 (PDT)
Raw View
------=_Part_312_24547713.1400778279807
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

On Thursday, 22 May 2014 16:18:20 UTC+1, David Rodr=C3=ADguez Ibeas wrote:
>
>
> void g(std::string [&] arg) {
>     arg =3D "the new value";
>     std::cout << arg;                  // This is not "the new value"!!!
> }
>
>
Personally I think it makes more sense for 'arg' to have the type of the=20
lambda within the function, you should have to explicitly use the call=20
operator to cause the lazy parameter to be evaluated. Assigning to it is=20
then not an issue, as the implicitness is only in the calling code.

--=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_312_24547713.1400778279807
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Thursday, 22 May 2014 16:18:20 UTC+1, David Rodr=C3=ADg=
uez Ibeas  wrote:<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"><br><div><div class=3D"gmail_quote"><div>void g(std::string [&amp;] arg=
) {<br>&nbsp; &nbsp; arg =3D "the new value";<br>&nbsp; &nbsp; std::cout &l=
t;&lt; arg; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;/=
/ This is not "the new value"!!!<br>}</div><br></div></div></div></blockquo=
te><div><br>Personally I think it makes more sense for 'arg' to have the ty=
pe of the lambda within the function, you should have to explicitly use the=
 call operator to cause the lazy parameter to be evaluated. Assigning to it=
 is then not an issue, as the implicitness is only in the calling code.<br>=
</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_312_24547713.1400778279807--

.


Author: Matthew Woehlke <mw_triad@users.sourceforge.net>
Date: Thu, 22 May 2014 13:21:03 -0400
Raw View
On 2014-05-22 12:57, Diggory Blake wrote:
> Here's one way I see it possibly working:
>
> - Space is reserved of the correct size and alignment for the parameter
> type (let's use "Foo"). This can either be directly on the stack, or as a
> field in the lambda (the advantage of the former being that the lambda
> would only need to capture the stack pointer, and so should always be able
> to take advantage of the small functor optimisation, regardless of
> "sizeof(Foo)", but aside from performance the two are equivalent.
>
> - This space is left unconstructed when the lambda is constructed, but when
> the lambda is called for the first time, it evaluates the expression, and
> the result of the expression is constructed directly in this empty space,
> no copying or moving. This requires an extra boolean to track whether the
> lambda has been evaluated or not.
>
> - The lambda returns the newly constructed object, either by reference or
> by value depending on the parameter qualifiers.
>
> - In the lambda's destructor, it checks whether it was ever invoked, and if
> so explicitly calls the destructor on the constructed object.

This is basically what I was thinking, but with the minor change that,
rather than store a bool, the "lambda" ("delayed evaluation context"
might be more accurate) stores the instruction pointer where to pick up
after the call dispatches. I'm not actually sure which is more
efficient, and anyway probably this should be an implementation detail
(I don't believe it matters to the callee how the caller implements
clean-up).

--
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: jgottman6@gmail.com
Date: Thu, 22 May 2014 19:45:08 -0700 (PDT)
Raw View
------=_Part_153_26491111.1400813108732
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable



On Wednesday, May 21, 2014 1:22:05 PM UTC-4, Matthew Woehlke wrote:
>
> On 2014-05-14 18:23, David Rodr=C3=ADguez Ibeas wrote:=20
>
>
> > From a user point of view, I am not too fond of the idea of the lambda=
=20
> > being evaluated on each use inside the function.=20
>
> I must strongly agree with this; if the lambda is evaluated at all, it=20
> must be evaluated exactly once. In any other direction lies madness.=20
>
> =20
>
What happens in the following case?

void foo([&] int x);  //Defined in another translation unit

void bar ([&] int x){
    foo(x);
}


 Is x evaluated in foo?  It depends on whether x is evaluated in bar.  Is=
=20
there any way for foo to know whether it is or isn't? If not, is this a=20
problem?

Joe Gottman

--=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_153_26491111.1400813108732
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Wednesday, May 21, 2014 1:22:05 PM UTC-4, Matth=
ew Woehlke wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margi=
n-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On 2014-05-14=
 18:23, David Rodr=C3=ADguez Ibeas wrote:
<br><br>
<br>&gt; From a user point of view, I am not too fond of the idea of the la=
mbda
<br>&gt; being evaluated on each use inside the function.
<br>
<br>I must strongly agree with this; if the lambda is evaluated at all, it
<br>must be evaluated exactly once. In any other direction lies madness.
<br>
<br>&nbsp;<br></blockquote><div>What happens in the following case?<br><br>=
<div class=3D"prettyprint" style=3D"background-color: rgb(250, 250, 250); b=
order-color: rgb(187, 187, 187); border-style: solid; border-width: 1px; wo=
rd-wrap: break-word;"><code class=3D"prettyprint"><div class=3D"subprettypr=
int"><span style=3D"color: #008;" class=3D"styled-by-prettify">void</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"> foo</span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">([&amp;]</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"col=
or: #008;" class=3D"styled-by-prettify">int</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"> x</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">);</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> &nbsp;</span><span style=3D"color: #800;" class=3D"styled=
-by-prettify">//Defined in another translation unit</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"><br><br></span><span style=3D"colo=
r: #008;" class=3D"styled-by-prettify">void</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"> bar </span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">([&amp;]</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"sty=
led-by-prettify">int</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"> x</span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">){</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>&n=
bsp; &nbsp; foo</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">x</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">);</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">}</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"><br><br></span></div></code></div><b=
r>&nbsp;Is x evaluated in foo?&nbsp; It depends on whether x is evaluated i=
n bar.&nbsp; Is there any way for foo to know whether it is or isn't? If no=
t, is this a problem?<br><br>Joe Gottman<br></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_153_26491111.1400813108732--

.


Author: Diggory Blake <diggsey@googlemail.com>
Date: Fri, 23 May 2014 02:58:13 -0700 (PDT)
Raw View
------=_Part_150_16206780.1400839093689
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

It's not a problem, the caller of 'foo' doesn't need to know if the=20
expression is evaluated, it just has to wrap up the expression in a lambda,=
=20
and then 'bar' decides whether or not to invoke it at runtime. The part=20
about only evaluating it at most once would be a runtime check (modulo any=
=20
optimisations the compiler might be able to do).

On Friday, 23 May 2014 03:45:08 UTC+1, jgot...@gmail.com wrote:
>
>
>
> On Wednesday, May 21, 2014 1:22:05 PM UTC-4, Matthew Woehlke wrote:
>>
>> On 2014-05-14 18:23, David Rodr=C3=ADguez Ibeas wrote:=20
>>
>>
>> > From a user point of view, I am not too fond of the idea of the lambda=
=20
>> > being evaluated on each use inside the function.=20
>>
>> I must strongly agree with this; if the lambda is evaluated at all, it=
=20
>> must be evaluated exactly once. In any other direction lies madness.=20
>>
>> =20
>>
> What happens in the following case?
>
> void foo([&] int x);  //Defined in another translation unit
>
> void bar ([&] int x){
>     foo(x);
> }
>
>
>  Is x evaluated in foo?  It depends on whether x is evaluated in bar.  Is=
=20
> there any way for foo to know whether it is or isn't? If not, is this a=
=20
> problem?
>
> Joe Gottman
>

--=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_150_16206780.1400839093689
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">It's not a problem, the caller of 'foo' doesn't need to kn=
ow if the expression is evaluated, it just has to wrap up the expression in=
 a lambda, and then 'bar' decides whether or not to invoke it at runtime. T=
he part about only evaluating it at most once would be a runtime check (mod=
ulo any optimisations the compiler might be able to do).<br><br>On Friday, =
23 May 2014 03:45:08 UTC+1, jgot...@gmail.com  wrote:<blockquote class=3D"g=
mail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc sol=
id;padding-left: 1ex;"><div dir=3D"ltr"><br><br>On Wednesday, May 21, 2014 =
1:22:05 PM UTC-4, Matthew Woehlke wrote:<blockquote class=3D"gmail_quote" s=
tyle=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:=
1ex">On 2014-05-14 18:23, David Rodr=C3=ADguez Ibeas wrote:
<br><br>
<br>&gt; From a user point of view, I am not too fond of the idea of the la=
mbda
<br>&gt; being evaluated on each use inside the function.
<br>
<br>I must strongly agree with this; if the lambda is evaluated at all, it
<br>must be evaluated exactly once. In any other direction lies madness.
<br>
<br>&nbsp;<br></blockquote><div>What happens in the following case?<br><br>=
<div style=3D"background-color:rgb(250,250,250);border-color:rgb(187,187,18=
7);border-style:solid;border-width:1px;word-wrap:break-word"><code><div><sp=
an style=3D"color:#008">void</span><span style=3D"color:#000"> foo</span><s=
pan style=3D"color:#660">([&amp;]</span><span style=3D"color:#000"> </span>=
<span style=3D"color:#008">int</span><span style=3D"color:#000"> x</span><s=
pan style=3D"color:#660">);</span><span style=3D"color:#000"> &nbsp;</span>=
<span style=3D"color:#800">//Defined in another translation unit</span><spa=
n style=3D"color:#000"><br><br></span><span style=3D"color:#008">void</span=
><span style=3D"color:#000"> bar </span><span style=3D"color:#660">([&amp;]=
</span><span style=3D"color:#000"> </span><span style=3D"color:#008">int</s=
pan><span style=3D"color:#000"> x</span><span style=3D"color:#660">){</span=
><span style=3D"color:#000"><br>&nbsp; &nbsp; foo</span><span style=3D"colo=
r:#660">(</span><span style=3D"color:#000">x</span><span style=3D"color:#66=
0">);</span><span style=3D"color:#000"><br></span><span style=3D"color:#660=
">}</span><span style=3D"color:#000"><br><br></span></div></code></div><br>=
&nbsp;Is x evaluated in foo?&nbsp; It depends on whether x is evaluated in =
bar.&nbsp; Is there any way for foo to know whether it is or isn't? If not,=
 is this a problem?<br><br>Joe Gottman<br></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_150_16206780.1400839093689--

.


Author: =?UTF-8?Q?David_Rodr=C3=ADguez_Ibeas?= <dibeas@ieee.org>
Date: Fri, 23 May 2014 10:22:45 -0400
Raw View
--001a11c12228a0475504fa11f6d3
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

Even if the forwarding of the functor argument did not involve wrapping in
another mechanism, we still need a boolean flag to determine whether we
need to cleanup or not (i.e. if it has been evaluated, the destructor needs
to be run over the created object). That boolean literally means: I have
already evaluated the expression, and can be used to avoid the evaluation.

The cost would be an additional branch in each function: where before we
could assume that the argument was unevaluated externally, the forwarding
case breaks that assumption. This should be an implementation detail, as
there are tradeoffs in both approaches. The one Diggory presented requires
an extra bool in memory and potentially an additional indirection to call
the expression, this approach doesn't, but every use pays for an extra
branch for the case where it might have been forwarded.


On Fri, May 23, 2014 at 5:58 AM, Diggory Blake <diggsey@googlemail.com>wrot=
e:

> It's not a problem, the caller of 'foo' doesn't need to know if the
> expression is evaluated, it just has to wrap up the expression in a lambd=
a,
> and then 'bar' decides whether or not to invoke it at runtime. The part
> about only evaluating it at most once would be a runtime check (modulo an=
y
> optimisations the compiler might be able to do).
>
>
> On Friday, 23 May 2014 03:45:08 UTC+1, jgot...@gmail.com wrote:
>>
>>
>>
>> On Wednesday, May 21, 2014 1:22:05 PM UTC-4, Matthew Woehlke wrote:
>>>
>>> On 2014-05-14 18:23, David Rodr=C3=ADguez Ibeas wrote:
>>>
>>>
>>> > From a user point of view, I am not too fond of the idea of the lambd=
a
>>> > being evaluated on each use inside the function.
>>>
>>> I must strongly agree with this; if the lambda is evaluated at all, it
>>> must be evaluated exactly once. In any other direction lies madness.
>>>
>>>
>>>
>> What happens in the following case?
>>
>> void foo([&] int x);  //Defined in another translation unit
>>
>> void bar ([&] int x){
>>     foo(x);
>> }
>>
>>
>>  Is x evaluated in foo?  It depends on whether x is evaluated in bar.  I=
s
>> there any way for foo to know whether it is or isn't? If not, is this a
>> problem?
>>
>> Joe Gottman
>>
>  --
>
> ---
> 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/.

--001a11c12228a0475504fa11f6d3
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Even if the forwarding of the functor argument did not inv=
olve wrapping in another mechanism, we still need a boolean flag to determi=
ne whether we need to cleanup or not (i.e. if it has been evaluated, the de=
structor needs to be run over the created object). That boolean literally m=
eans: I have already evaluated the expression, and can be used to avoid the=
 evaluation.<br>
<br>The cost would be an additional branch in each function: where before w=
e could assume that the argument was unevaluated externally, the forwarding=
 case breaks that assumption. This should be an implementation detail, as t=
here are tradeoffs in both approaches. The one Diggory presented requires a=
n extra bool in memory and potentially an additional indirection to call th=
e expression, this approach doesn&#39;t, but every use pays for an extra br=
anch for the case where it might have been forwarded.</div>
<div class=3D"gmail_extra"><br><br><div class=3D"gmail_quote">On Fri, May 2=
3, 2014 at 5:58 AM, Diggory Blake <span dir=3D"ltr">&lt;<a href=3D"mailto:d=
iggsey@googlemail.com" target=3D"_blank">diggsey@googlemail.com</a>&gt;</sp=
an> wrote:<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex"><div dir=3D"ltr">It&#39;s not a problem, the=
 caller of &#39;foo&#39; doesn&#39;t need to know if the expression is eval=
uated, it just has to wrap up the expression in a lambda, and then &#39;bar=
&#39; decides whether or not to invoke it at runtime. The part about only e=
valuating it at most once would be a runtime check (modulo any optimisation=
s the compiler might be able to do).<div>
<div class=3D"h5"><br><br>On Friday, 23 May 2014 03:45:08 UTC+1, <a href=3D=
"mailto:jgot...@gmail.com" target=3D"_blank">jgot...@gmail.com</a>  wrote:<=
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><br>On Wednesday, May 21, 2014 1:22:05 PM UTC-4, Matth=
ew 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-05-14 18:2=
3, David Rodr=C3=ADguez Ibeas wrote:
<br><br>
<br>&gt; From a user point of view, I am not too fond of the idea of the la=
mbda
<br>&gt; being evaluated on each use inside the function.
<br>
<br>I must strongly agree with this; if the lambda is evaluated at all, it
<br>must be evaluated exactly once. In any other direction lies madness.
<br>
<br>=C2=A0<br></blockquote><div>What happens in the following case?<br><br>=
<div style=3D"background-color:rgb(250,250,250);border-color:rgb(187,187,18=
7);border-style:solid;border-width:1px;word-wrap:break-word"><code><div><sp=
an style=3D"color:#008">void</span><span style=3D"color:#000"> foo</span><s=
pan style=3D"color:#660">([&amp;]</span><span style=3D"color:#000"> </span>=
<span style=3D"color:#008">int</span><span style=3D"color:#000"> x</span><s=
pan style=3D"color:#660">);</span><span style=3D"color:#000"> =C2=A0</span>=
<span style=3D"color:#800">//Defined in another translation unit</span><spa=
n style=3D"color:#000"><br>
<br></span><span style=3D"color:#008">void</span><span style=3D"color:#000"=
> bar </span><span style=3D"color:#660">([&amp;]</span><span style=3D"color=
:#000"> </span><span style=3D"color:#008">int</span><span style=3D"color:#0=
00"> x</span><span style=3D"color:#660">){</span><span style=3D"color:#000"=
><br>
=C2=A0 =C2=A0 foo</span><span style=3D"color:#660">(</span><span style=3D"c=
olor:#000">x</span><span style=3D"color:#660">);</span><span style=3D"color=
:#000"><br></span><span style=3D"color:#660">}</span><span style=3D"color:#=
000"><br><br></span></div>
</code></div><br>=C2=A0Is x evaluated in foo?=C2=A0 It depends on whether x=
 is evaluated in bar.=C2=A0 Is there any way for foo to know whether it is =
or isn&#39;t? If not, is this a problem?<br><br>Joe Gottman<br></div></div>=
</blockquote>
</div></div></div><div class=3D"HOEnZb"><div class=3D"h5">

<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" target=3D"_=
blank">std-proposals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br>
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/" target=3D"_blank">http://groups.google.com/a/isocpp.org/gro=
up/std-proposals/</a>.<br>
</div></div></blockquote></div><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 />

--001a11c12228a0475504fa11f6d3--

.


Author: Diggory Blake <diggsey@googlemail.com>
Date: Fri, 23 May 2014 07:48:40 -0700 (PDT)
Raw View
------=_Part_144_3527134.1400856520135
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

It would be possible to offer the choice of whether or not an indirection=
=20
is necessary with syntax like the following.

With indirection, but allowing implementation to be hidden:
void foo([[lazy]] std::function<string ()> arg) {
    cout << arg();
}

Without indirection (in this case arg() might not return a string, but that=
=20
can be enforced easily enough when concepts are implemented):
template<typename T>
void bar([[lazy]] T const& arg) {
    cout << arg();
}

In both cases the compiler would generate a functor at the call-site. In=20
the first case this would be wrapped in a std::function, in the second case=
=20
it would be inferred as the type T.

On Friday, 23 May 2014 15:22:47 UTC+1, David Rodr=C3=ADguez Ibeas wrote:
>
> Even if the forwarding of the functor argument did not involve wrapping i=
n=20
> another mechanism, we still need a boolean flag to determine whether we=
=20
> need to cleanup or not (i.e. if it has been evaluated, the destructor nee=
ds=20
> to be run over the created object). That boolean literally means: I have=
=20
> already evaluated the expression, and can be used to avoid the evaluation=
..
>
> The cost would be an additional branch in each function: where before we=
=20
> could assume that the argument was unevaluated externally, the forwarding=
=20
> case breaks that assumption. This should be an implementation detail, as=
=20
> there are tradeoffs in both approaches. The one Diggory presented require=
s=20
> an extra bool in memory and potentially an additional indirection to call=
=20
> the expression, this approach doesn't, but every use pays for an extra=20
> branch for the case where it might have been forwarded.
>
>
> On Fri, May 23, 2014 at 5:58 AM, Diggory Blake <dig...@googlemail.com<jav=
ascript:>
> > wrote:
>
>> It's not a problem, the caller of 'foo' doesn't need to know if the=20
>> expression is evaluated, it just has to wrap up the expression in a lamb=
da,=20
>> and then 'bar' decides whether or not to invoke it at runtime. The part=
=20
>> about only evaluating it at most once would be a runtime check (modulo a=
ny=20
>> optimisations the compiler might be able to do).
>>
>>
>> On Friday, 23 May 2014 03:45:08 UTC+1, jgot...@gmail.com wrote:
>>>
>>>
>>>
>>> On Wednesday, May 21, 2014 1:22:05 PM UTC-4, Matthew Woehlke wrote:
>>>>
>>>> On 2014-05-14 18:23, David Rodr=C3=ADguez Ibeas wrote:=20
>>>>
>>>>
>>>> > From a user point of view, I am not too fond of the idea of the=20
>>>> lambda=20
>>>> > being evaluated on each use inside the function.=20
>>>>
>>>> I must strongly agree with this; if the lambda is evaluated at all, it=
=20
>>>> must be evaluated exactly once. In any other direction lies madness.=
=20
>>>>
>>>> =20
>>>>
>>> What happens in the following case?
>>>
>>> void foo([&] int x);  //Defined in another translation unit
>>>
>>> void bar ([&] int x){
>>>     foo(x);
>>> }
>>>
>>>
>>>  Is x evaluated in foo?  It depends on whether x is evaluated in bar. =
=20
>>> Is there any way for foo to know whether it is or isn't? If not, is thi=
s a=20
>>> problem?
>>>
>>> Joe Gottman
>>>
>>  --=20
>>
>> ---=20
>> You received this message because you are subscribed to the Google Group=
s=20
>> "ISO C++ Standard - Future Proposals" group.
>> To unsubscribe from this group and stop receiving emails from it, send a=
n=20
>> email to std-proposal...@isocpp.org <javascript:>.
>> To post to this group, send email to std-pr...@isocpp.org <javascript:>.
>> Visit this group at=20
>> 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/.

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

<div dir=3D"ltr">It would be possible to offer the choice of whether or not=
 an indirection is necessary with syntax like the following.<br><br>With in=
direction, but allowing implementation to be hidden:<br><div class=3D"prett=
yprint" style=3D"background-color: rgb(250, 250, 250); border-color: rgb(18=
7, 187, 187); border-style: solid; 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">void</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"> foo</span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">([[</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify">lazy</span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">]]</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"> std</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">::</span><span style=3D"color: #008;" class=3D"styled-by-prettify">fun=
ction</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;<=
/span><span style=3D"color: #008;" class=3D"styled-by-prettify">string</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">()&gt;</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> arg</span><span style=3D"co=
lor: #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">{</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"><br>&nbsp; &nbsp; cout </span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">&lt;&lt;</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> arg</span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">();</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"><br></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></div></code></div><br>Without indirection (in this case arg() mig=
ht not return a string, but that can be enforced easily enough when concept=
s are implemented):<br><div class=3D"prettyprint" style=3D"background-color=
: rgb(250, 250, 250); border-color: rgb(187, 187, 187); border-style: solid=
; border-width: 1px; word-wrap: break-word;"><code class=3D"prettyprint"><d=
iv class=3D"subprettyprint"><span style=3D"color: #008;" class=3D"styled-by=
-prettify">template</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">&lt;</span><span style=3D"color: #008;" class=3D"styled-by-prettif=
y">typename</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
> T</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&gt;</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><s=
pan style=3D"color: #008;" class=3D"styled-by-prettify">void</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> bar</span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">([[</span><span style=3D"color:=
 #000;" class=3D"styled-by-prettify">lazy</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: #008;" class=3D"sty=
led-by-prettify">const</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">&amp;</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> arg</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">{</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"><br>&nbsp; &nbsp; cout </s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;&lt;</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"> arg</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">();</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">}</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify"><br></span></div></code></div><br>In both c=
ases the compiler would generate a functor at the call-site. In the first c=
ase this would be wrapped in a std::function, in the second case it would b=
e inferred as the type T.<br><br>On Friday, 23 May 2014 15:22:47 UTC+1, Dav=
id Rodr=C3=ADguez Ibeas  wrote:<blockquote class=3D"gmail_quote" style=3D"m=
argin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"=
><div dir=3D"ltr">Even if the forwarding of the functor argument did not in=
volve wrapping in another mechanism, we still need a boolean flag to determ=
ine whether we need to cleanup or not (i.e. if it has been evaluated, the d=
estructor needs to be run over the created object). That boolean literally =
means: I have already evaluated the expression, and can be used to avoid th=
e evaluation.<br>
<br>The cost would be an additional branch in each function: where before w=
e could assume that the argument was unevaluated externally, the forwarding=
 case breaks that assumption. This should be an implementation detail, as t=
here are tradeoffs in both approaches. The one Diggory presented requires a=
n extra bool in memory and potentially an additional indirection to call th=
e expression, this approach doesn't, but every use pays for an extra branch=
 for the case where it might have been forwarded.</div>
<div><br></div></blockquote><blockquote class=3D"gmail_quote" style=3D"marg=
in: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><d=
iv><br><div class=3D"gmail_quote">On Fri, May 23, 2014 at 5:58 AM, Diggory =
Blake <span dir=3D"ltr">&lt;<a href=3D"javascript:" target=3D"_blank" gdf-o=
bfuscated-mailto=3D"bQBOikbVIdUJ" onmousedown=3D"this.href=3D'javascript:';=
return true;" onclick=3D"this.href=3D'javascript:';return true;">dig...@goo=
glemail.com</a>&gt;</span> wrote:<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex"><div dir=3D"ltr">It's not a problem, the cal=
ler of 'foo' doesn't need to know if the expression is evaluated, it just h=
as to wrap up the expression in a lambda, and then 'bar' decides whether or=
 not to invoke it at runtime. The part about only evaluating it at most onc=
e would be a runtime check (modulo any optimisations the compiler might be =
able to do).<div>
<div><br><br>On Friday, 23 May 2014 03:45:08 UTC+1, <a>jgot...@gmail.com</a=
>  wrote:<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><br>On Wednesday, May 21, 2014 1:22:05 PM UTC-4, Matth=
ew 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-05-14 18:2=
3, David Rodr=C3=ADguez Ibeas wrote:
<br><br>
<br>&gt; From a user point of view, I am not too fond of the idea of the la=
mbda
<br>&gt; being evaluated on each use inside the function.
<br>
<br>I must strongly agree with this; if the lambda is evaluated at all, it
<br>must be evaluated exactly once. In any other direction lies madness.
<br>
<br>&nbsp;<br></blockquote><div>What happens in the following case?<br><br>=
<div style=3D"background-color:rgb(250,250,250);border-color:rgb(187,187,18=
7);border-style:solid;border-width:1px;word-wrap:break-word"><code><div><sp=
an style=3D"color:#008">void</span><span style=3D"color:#000"> foo</span><s=
pan style=3D"color:#660">([&amp;]</span><span style=3D"color:#000"> </span>=
<span style=3D"color:#008">int</span><span style=3D"color:#000"> x</span><s=
pan style=3D"color:#660">);</span><span style=3D"color:#000"> &nbsp;</span>=
<span style=3D"color:#800">//Defined in another translation unit</span><spa=
n style=3D"color:#000"><br>
<br></span><span style=3D"color:#008">void</span><span style=3D"color:#000"=
> bar </span><span style=3D"color:#660">([&amp;]</span><span style=3D"color=
:#000"> </span><span style=3D"color:#008">int</span><span style=3D"color:#0=
00"> x</span><span style=3D"color:#660">){</span><span style=3D"color:#000"=
><br>
&nbsp; &nbsp; foo</span><span style=3D"color:#660">(</span><span style=3D"c=
olor:#000">x</span><span style=3D"color:#660">);</span><span style=3D"color=
:#000"><br></span><span style=3D"color:#660">}</span><span style=3D"color:#=
000"><br><br></span></div>
</code></div><br>&nbsp;Is x evaluated in foo?&nbsp; It depends on whether x=
 is evaluated in bar.&nbsp; Is there any way for foo to know whether it is =
or isn't? If not, is this a problem?<br><br>Joe Gottman<br></div></div></bl=
ockquote>
</div></div></div><div><div>

<p></p>

-- <br>
<br>
--- <br>
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"=
bQBOikbVIdUJ" onmousedown=3D"this.href=3D'javascript:';return true;" onclic=
k=3D"this.href=3D'javascript:';return true;">std-proposal...@<wbr>isocpp.or=
g</a>.<br>
To post to this group, send email to <a href=3D"javascript:" target=3D"_bla=
nk" gdf-obfuscated-mailto=3D"bQBOikbVIdUJ" onmousedown=3D"this.href=3D'java=
script:';return true;" onclick=3D"this.href=3D'javascript:';return true;">s=
td-pr...@isocpp.org</a>.<br>
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/" target=3D"_blank" onmousedown=3D"this.href=3D'http://groups=
..google.com/a/isocpp.org/group/std-proposals/';return true;" onclick=3D"thi=
s.href=3D'http://groups.google.com/a/isocpp.org/group/std-proposals/';retur=
n true;">http://groups.google.com/a/<wbr>isocpp.org/group/std-<wbr>proposal=
s/</a>.<br>
</div></div></blockquote></div><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_144_3527134.1400856520135--

.


Author: Matthew Woehlke <mw_triad@users.sourceforge.net>
Date: Fri, 23 May 2014 11:42:35 -0400
Raw View
On 2014-05-22 22:45, jgottman6@gmail.com wrote:
> What happens in the following case?
>
> void foo([&] int x);  //Defined in another translation unit
>
> void bar ([&] int x){
>     foo(x);
> }
>
>  Is x evaluated in foo?  It depends on whether x is evaluated in bar.  Is
> there any way for foo to know whether it is or isn't? If not, is this a
> problem?

In this *specific* case (i.e. 'x' of same type and not otherwise used) I
would suspect/hope that the compiler can simply forward the delayed
expression to foo().

Otherwise, I'd say the compiler should generate a new delayed evaluation
context inside bar() that would either simply return an
already-evaluated 'x' (if it has already been evaluated), or have the
necessary logic to test if it has not been evaluated, do so (and mark it
so, storing the result locally for later use if applicable), and return
the result.

--
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: Hyman Rosen <hyman.rosen@gmail.com>
Date: Fri, 23 May 2014 13:37:53 -0400
Raw View
--001a11336154bdf2da04fa14b10d
Content-Type: text/plain; charset=UTF-8

I haven't chimed in since my original post.  I would just like to
explain/summarize my understanding of the salient points of the proposal.

1)  The annotation [&] of the parameter is a mnemonic to indicate that
evaluation of the parameter causes the side effects of the argument
expression when it is evaluated.  I don't anticipate needing other capture
forms.

2) I agree that the 0-or-1 evaluation model is better and easier to
understand than the multiple-evaluation model, and withdraw the latter.

3) For each [&] parameter, the called function contains reserved space on
the stack for the parameter, plus a boolean variable indicating whether the
argument expression has been evaluated. [User-accessible? Maybe!]  Upon
exit from the function, if the boolean variable is set, the destructor for
the parameter is called.

4) The first evaluation of the parameter in any context (even just having
its address taken, for example, but not in non-evaluated contexts such as
sizeof) causes the argument to be evaluated as if it had been an ordinary
function call argument and results in the reserved parameter space being
initialized as if it had been an ordinary parameter.

5) The "lambda" (or "thunk", to bring back an old term) used for this could
be a pointer to something as simple as
    struct { void (*f)(void *this_struct, void *parameter); };
The caller creates one of these objects on the stack with f pointing to the
argument evaluation code and passes a pointer to it to the callee, and the
callee calls this function passing back the pointer and the address of the
parameter to initialize.  Any extra data needed is placed immediately after
this struct (which is why the callee passes the pointer back).  There's no
need for the called function to be a template.  There's no need for the
thunk to be representable as an ordinary lambda.


On Fri, May 23, 2014 at 11:42 AM, Matthew Woehlke <
mw_triad@users.sourceforge.net> wrote:

> On 2014-05-22 22:45, jgottman6@gmail.com wrote:
> > What happens in the following case?
> >
> > void foo([&] int x);  //Defined in another translation unit
> >
> > void bar ([&] int x){
> >     foo(x);
> > }
> >
> >  Is x evaluated in foo?  It depends on whether x is evaluated in bar.  Is
> > there any way for foo to know whether it is or isn't? If not, is this a
> > problem?
>
> In this *specific* case (i.e. 'x' of same type and not otherwise used) I
> would suspect/hope that the compiler can simply forward the delayed
> expression to foo().
>
> Otherwise, I'd say the compiler should generate a new delayed evaluation
> context inside bar() that would either simply return an
> already-evaluated 'x' (if it has already been evaluated), or have the
> necessary logic to test if it has not been evaluated, do so (and mark it
> so, storing the result locally for later use if applicable), and return
> the result.
>
> --
> 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/.

--001a11336154bdf2da04fa14b10d
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">I haven&#39;t chimed in since my original post. =C2=A0I wo=
uld just like to explain/summarize my understanding of the salient points o=
f the proposal.<div><br></div><div>1) =C2=A0The annotation [&amp;] of the p=
arameter is a mnemonic to indicate that evaluation of the parameter causes =
the side effects of the argument expression when it is evaluated. =C2=A0I d=
on&#39;t anticipate needing other capture forms.</div>

<div><br></div><div>2) I agree that the 0-or-1 evaluation model is better a=
nd easier to understand than the multiple-evaluation model, and withdraw th=
e latter.</div><div><br></div><div>3) For each [&amp;] parameter, the calle=
d function contains reserved space on the stack for the parameter, plus a b=
oolean variable indicating whether the argument expression has been evaluat=
ed. [User-accessible? Maybe!] =C2=A0Upon exit from the function, if the boo=
lean variable is set, the destructor for the parameter is called.</div>

<div><br></div><div>4) The first evaluation of the parameter in any context=
 (even just having its address taken, for example, but not in non-evaluated=
 contexts such as sizeof) causes the argument to be evaluated as if it had =
been an ordinary function call argument and results in the reserved paramet=
er space being initialized as if it had been an ordinary parameter.</div>

<div><br></div><div>5) The &quot;lambda&quot; (or &quot;thunk&quot;, to bri=
ng back an old term) used for this could be a pointer to something as simpl=
e as<br>=C2=A0 =C2=A0 struct { void (*f)(void *this_struct, void *parameter=
); };</div>

<div>The caller creates one of these objects on the stack with f pointing t=
o the argument evaluation code and passes a pointer to it to the callee, an=
d the callee calls this function passing back the pointer and the address o=
f the parameter to initialize. =C2=A0Any extra data needed is placed immedi=
ately after this struct (which is why the callee passes the pointer back). =
=C2=A0There&#39;s no need for the called function to be a template. =C2=A0T=
here&#39;s no need for the thunk to be representable as an ordinary lambda.=
</div>

</div><div class=3D"gmail_extra"><br><br><div class=3D"gmail_quote">On Fri,=
 May 23, 2014 at 11:42 AM, Matthew Woehlke <span dir=3D"ltr">&lt;<a href=3D=
"mailto:mw_triad@users.sourceforge.net" target=3D"_blank">mw_triad@users.so=
urceforge.net</a>&gt;</span> wrote:<br>

<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex"><div class=3D"">On 2014-05-22 22:45, <a href=
=3D"mailto:jgottman6@gmail.com">jgottman6@gmail.com</a> wrote:<br>
&gt; What happens in the following case?<br>
&gt;<br>
&gt; void foo([&amp;] int x); =C2=A0//Defined in another translation unit<b=
r>
&gt;<br>
&gt; void bar ([&amp;] int x){<br>
&gt; =C2=A0 =C2=A0 foo(x);<br>
&gt; }<br>
&gt;<br>
&gt; =C2=A0Is x evaluated in foo? =C2=A0It depends on whether x is evaluate=
d in bar. =C2=A0Is<br>
&gt; there any way for foo to know whether it is or isn&#39;t? If not, is t=
his a<br>
&gt; problem?<br>
<br>
</div>In this *specific* case (i.e. &#39;x&#39; of same type and not otherw=
ise used) I<br>
would suspect/hope that the compiler can simply forward the delayed<br>
expression to foo().<br>
<br>
Otherwise, I&#39;d say the compiler should generate a new delayed evaluatio=
n<br>
context inside bar() that would either simply return an<br>
already-evaluated &#39;x&#39; (if it has already been evaluated), or have t=
he<br>
necessary logic to test if it has not been evaluated, do so (and mark it<br=
>
so, storing the result locally for later use if applicable), and return<br>
the result.<br>
<span class=3D"HOEnZb"><font color=3D"#888888"><br>
--<br>
Matthew<br>
</font></span><div class=3D"HOEnZb"><div class=3D"h5"><br>
--<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%2Bunsubscribe@isocpp.org">std-propo=
sals+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/" target=3D"_blank">http://groups.google.com/a/isocpp.org/gro=
up/std-proposals/</a>.<br>
</div></div></blockquote></div><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 />

--001a11336154bdf2da04fa14b10d--

.


Author: Diggory Blake <diggsey@googlemail.com>
Date: Fri, 23 May 2014 11:13:21 -0700 (PDT)
Raw View
------=_Part_695_18110240.1400868802118
Content-Type: text/plain; charset=UTF-8



On Friday, 23 May 2014 18:38:16 UTC+1, Hyman Rosen wrote:
>
> I haven't chimed in since my original post.  I would just like to
> explain/summarize my understanding of the salient points of the proposal.
>
> 1)  The annotation [&] of the parameter is a mnemonic to indicate that
> evaluation of the parameter causes the side effects of the argument
> expression when it is evaluated.  I don't anticipate needing other capture
> forms.
>
> 2) I agree that the 0-or-1 evaluation model is better and easier to
> understand than the multiple-evaluation model, and withdraw the latter.
>
> 3) For each [&] parameter, the called function contains reserved space on
> the stack for the parameter, plus a boolean variable indicating whether the
> argument expression has been evaluated. [User-accessible? Maybe!]  Upon
> exit from the function, if the boolean variable is set, the destructor for
> the parameter is called.
>
> 4) The first evaluation of the parameter in any context (even just having
> its address taken, for example, but not in non-evaluated contexts such as
> sizeof) causes the argument to be evaluated as if it had been an ordinary
> function call argument and results in the reserved parameter space being
> initialized as if it had been an ordinary parameter.
>

So you're suggesting having the parameter be evaluated implicitly just by
using the name?
- C++ has so far stayed away from having "hidden" method calls in the code.
Up until now it's always been clear what is a function call and might go
off and execute some other code, with this it wouldn't be.
- What do you expect the behaviour of this to be:
auto foo(string [&] arg) {
    return [=]() { return arg; };
}

- What about this:
auto foo(string [&] arg) {
    auto unused = arg;
    return [=]() { return arg; };
}

- Or this:
foo(1/0)
void foo(int [&] arg) {
    int a = arg; // Divide by zero???
}

IMHO, having the evaluation be implicit is a bad idea. It should be clear
to anyone reading the code that it's going off and evaluating some other
expression.



>
> 5) The "lambda" (or "thunk", to bring back an old term) used for this
> could be a pointer to something as simple as
>     struct { void (*f)(void *this_struct, void *parameter); };
> The caller creates one of these objects on the stack with f pointing to
> the argument evaluation code and passes a pointer to it to the callee, and
> the callee calls this function passing back the pointer and the address of
> the parameter to initialize.  Any extra data needed is placed immediately
> after this struct (which is why the callee passes the pointer back).
>  There's no need for the called function to be a template.  There's no need
> for the thunk to be representable as an ordinary lambda.
>
>
Lambdas are just anonymous structs like that, and the type erasure you are
describing is exactly the same as that done by std::function already. Seems
silly to duplicate the functionality. Templates would avoid the need for
the extra indirection, so it would be nice if it were possible to use them.

--

---
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_695_18110240.1400868802118
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Friday, 23 May 2014 18:38:16 UTC+1, Hyman Rosen=
  wrote:<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">I hav=
en't chimed in since my original post. &nbsp;I would just like to explain/s=
ummarize my understanding of the salient points of the proposal.<div><br></=
div><div>1) &nbsp;The annotation [&amp;] of the parameter is a mnemonic to =
indicate that evaluation of the parameter causes the side effects of the ar=
gument expression when it is evaluated. &nbsp;I don't anticipate needing ot=
her capture forms.</div>

<div><br></div><div>2) I agree that the 0-or-1 evaluation model is better a=
nd easier to understand than the multiple-evaluation model, and withdraw th=
e latter.</div><div><br></div><div>3) For each [&amp;] parameter, the calle=
d function contains reserved space on the stack for the parameter, plus a b=
oolean variable indicating whether the argument expression has been evaluat=
ed. [User-accessible? Maybe!] &nbsp;Upon exit from the function, if the boo=
lean variable is set, the destructor for the parameter is called.</div>

<div><br></div><div>4) The first evaluation of the parameter in any context=
 (even just having its address taken, for example, but not in non-evaluated=
 contexts such as sizeof) causes the argument to be evaluated as if it had =
been an ordinary function call argument and results in the reserved paramet=
er space being initialized as if it had been an ordinary parameter.</div></=
div></blockquote><div><br>So you're suggesting having the parameter be eval=
uated implicitly just by using the name?<br>- C++ has so far stayed away fr=
om having "hidden" method calls in the code. Up until now it's always been =
clear what is a function call and might go off and execute some other code,=
 with this it wouldn't be.<br>- What do you expect the behaviour of this to=
 be:<br><div class=3D"prettyprint" style=3D"background-color: rgb(250, 250,=
 250); border-color: rgb(187, 187, 187); border-style: solid; border-width:=
 1px; word-wrap: break-word;"><code class=3D"prettyprint"><div class=3D"sub=
prettyprint"><span style=3D"color: #008;" class=3D"styled-by-prettify">auto=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> foo</span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span st=
yle=3D"color: #008;" class=3D"styled-by-prettify">string</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">[&amp;]</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> arg</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">{</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"><br>&nbsp; &nbsp; </span><span style=3D"color: #008;" class=3D"styled-by-=
prettify">return</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">[=
=3D]()</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </s=
pan><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">return</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> arg</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">;</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">};</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"><br></span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">}</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></s=
pan></div></code></div><br>- What about this:<br><div class=3D"prettyprint"=
 style=3D"background-color: rgb(250, 250, 250); border-color: rgb(187, 187,=
 187); border-style: solid; border-width: 1px; word-wrap: break-word;"><cod=
e class=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"color:=
 #008;" class=3D"styled-by-prettify">auto</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"> foo</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">(</span><span style=3D"color: #008;" class=3D"styl=
ed-by-prettify">string</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">[&amp;]</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
 arg</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: #660;" class=3D"styled-by-prettify">{</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"><br>&nbsp; &nbsp; </span><span st=
yle=3D"color: #008;" class=3D"styled-by-prettify">auto</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"> unused </span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> arg</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; </span><span style=3D"color: #008;" c=
lass=3D"styled-by-prettify">return</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">[=3D]()</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">{</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </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"> arg</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">;</span><span style=3D"co=
lor: #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></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></span></div></code></div><br>- Or this:<br><div class=3D"pret=
typrint" style=3D"background-color: rgb(250, 250, 250); border-color: rgb(1=
87, 187, 187); border-style: solid; border-width: 1px; word-wrap: break-wor=
d;"><code class=3D"prettyprint"><div class=3D"subprettyprint"><span style=
=3D"color: #000;" class=3D"styled-by-prettify">foo</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #066;=
" class=3D"styled-by-prettify">1</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">/</span><span style=3D"color: #066;" class=3D"style=
d-by-prettify">0</span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">)</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br=
></span><span style=3D"color: #008;" class=3D"styled-by-prettify">void</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"> foo</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">int</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">[&amp;]</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"> arg</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">)</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">{</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br=
>&nbsp; &nbsp; </span><span style=3D"color: #008;" class=3D"styled-by-prett=
ify">int</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> a=
 </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"> arg</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: #=
800;" class=3D"styled-by-prettify">// Divide by zero???</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">}</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify"><br></span></div></code></div><br>IMHO, hav=
ing the evaluation be implicit is a bad idea. It should be clear to anyone =
reading the code that it's going off and evaluating some other expression.<=
br><br>&nbsp;</div><blockquote class=3D"gmail_quote" style=3D"margin: 0;mar=
gin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D=
"ltr">

<div><br></div><div>5) The "lambda" (or "thunk", to bring back an old term)=
 used for this could be a pointer to something as simple as<br>&nbsp; &nbsp=
; struct { void (*f)(void *this_struct, void *parameter); };</div>

<div>The caller creates one of these objects on the stack with f pointing t=
o the argument evaluation code and passes a pointer to it to the callee, an=
d the callee calls this function passing back the pointer and the address o=
f the parameter to initialize. &nbsp;Any extra data needed is placed immedi=
ately after this struct (which is why the callee passes the pointer back). =
&nbsp;There's no need for the called function to be a template. &nbsp;There=
's no need for the thunk to be representable as an ordinary lambda.</div>

</div><div><br></div></blockquote><div><br>Lambdas are just anonymous struc=
ts like that, and the type erasure you are describing is exactly the same a=
s that done by std::function already. Seems silly to duplicate the function=
ality. Templates would avoid the need for the extra indirection, so it woul=
d be nice if it were possible to use them.</div><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_695_18110240.1400868802118--

.


Author: Nicola Gigante <nicola.gigante@gmail.com>
Date: Fri, 23 May 2014 20:23:40 +0200
Raw View
Il giorno 23/mag/2014, alle ore 19:37, Hyman Rosen <hyman.rosen@gmail.com> =
ha scritto:

> I haven't chimed in since my original post.  I would just like to explain=
/summarize my understanding of the salient points of the proposal.
>=20
> 1)  The annotation [&] of the parameter is a mnemonic to indicate that ev=
aluation of the parameter causes the side effects of the argument expressio=
n when it is evaluated.  I don't anticipate needing other capture forms.
>=20
> 2) I agree that the 0-or-1 evaluation model is better and easier to under=
stand than the multiple-evaluation model, and withdraw the latter.
>=20
> 3) For each [&] parameter, the called function contains reserved space on=
 the stack for the parameter, plus a boolean variable indicating whether th=
e argument expression has been evaluated. [User-accessible? Maybe!]  Upon e=
xit from the function, if the boolean variable is set, the destructor for t=
he parameter is called.
>=20
> 4) The first evaluation of the parameter in any context (even just having=
 its address taken, for example, but not in non-evaluated contexts such as =
sizeof) causes the argument to be evaluated as if it had been an ordinary f=
unction call argument and results in the reserved parameter space being ini=
tialized as if it had been an ordinary parameter.
>=20
> 5) The "lambda" (or "thunk", to bring back an old term) used for this cou=
ld be a pointer to something as simple as
>     struct { void (*f)(void *this_struct, void *parameter); };
> The caller creates one of these objects on the stack with f pointing to t=
he argument evaluation code and passes a pointer to it to the callee, and t=
he callee calls this function passing back the pointer and the address of t=
he parameter to initialize.  Any extra data needed is placed immediately af=
ter this struct (which is why the callee passes the pointer back).  There's=
 no need for the called function to be a template.  There's no need for the=
 thunk to be representable as an ordinary lambda.
>=20

A great summary!

I think the interest and the consensus over this proposal are relatively hi=
gh, as well
as its feasibility.
I have some questions in my head:
1) is there a good way to specify and implement this in a way
that such a function can be linkable from code unaware of this new feature?
2) syntax: If we don't talk about captures, I don't like [&] very much. As
someone else has suggested, what about an attribute?=20

void foo([[lazy]] int n); // Although I don't know if an attribute can appe=
ar in that position
or
void foo(lazy int n); // context-sensitive keyword like final and override

3) can this be generalized to class members? Infinite data structures are a=
 strong
selling point of lazy languages like Haskell. Maybe we can find a way to su=
pport this feature.
What could happen if the language allowed the following?

template<typename T>
struct List {
   T _head;
   lazy List<T> _tail; // A member of type T inside of type T itself: allow=
ed because it's delayed

   List(T head, lazy List<T> const& tail) : _head(head), _tail(tail) { }
};

I would say that the member could be represented in a way similar to
the case of function parameters, and the first access to the member would
result in an evaluation.

What do you think?

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: Matthew Woehlke <mw_triad@users.sourceforge.net>
Date: Fri, 23 May 2014 14:39:04 -0400
Raw View
On 2014-05-23 13:37, Hyman Rosen wrote:
> 3) For each [&] parameter, the called function contains reserved space on
> the stack for the parameter, plus a boolean variable indicating whether t=
he
> argument expression has been evaluated.

Others may have expressed that desire. I still prefer that the callee
reserves space, but the caller is responsible for /ensuring/ (as an
implementation detail) that the lambda is only called once. The
mechanism for doing this shall not be specified. I think it's important
that the compiler be permitted to make this assurance simply by knowing
that no code path results in multiple evaluation, in which case no flag
would be needed.

> [User-accessible? Maybe!]

Please, no. :-) See also next comment.

> Upon exit from the function, if the boolean variable is set, the
> destructor for the parameter is called.

This requires that a clean-up code pointer is also passed to the callee.
That's an acceptable option, though as above, the callee should not be
required to use a flag if the compiler is able to determine that one is
not needed.

Another option is for the evaluation cope pointer to set a jump address
in the caller's stack context, such that on return, the caller
unconditionally jumps to this address (by default, the address would be
set to skip clean-up). Another advantage to this option that I just
realized is that, in the case of a single delayed parameter=C2=B9, this
"return address" can be the usual return address register, which
eliminates even the additional jump.

(=C2=B9 Actually, the first delayed parameter can always do this, and even
subsequent ones might be able to do so iff they are the first parameter
evaluated. Again... there are optimization possibilities, so how to
implement this is best left to the compilers.)

> 5) The "lambda" (or "thunk", to bring back an old term)

Heh. I was thinking about using "thunk" in the above :-). Given that I
don't see these being "lambdas" in the sense that "lambda" is a specific
object type in C++, it might be better to not call them such.

> used for this could be a pointer to something as simple as
>     struct { void (*f)(void *this_struct, void *parameter); };

Something like that, yes.

Basically, 2-3 things are needed; an instruction address to the thunk,
which should use some form of "fast" calling convention (i.e. if it
needs a full stack frame, it must set it up itself; hopefully most
*won't*) and takes a single parameter, which is a void pointer to data
space that the caller passes in. The meaning of the data pointer shall
be unspecified and left up to the caller/thunk, e.g. it might be a
pointer into the caller's stack, or a direct pointer to some class
member that is manipulated (e.g. '&i' in case of trivial thunks like '++i')=
..

The third is an instruction addresss to clean-up code, if the callee is
responsible for calling the same.

> The caller creates one of these objects on the stack

I wouldn't require this... especially if the caller handles clean-up,
we're talking about only two pointers. For a callee taking a single
parameter, it makes no sense not to just pass these in registers. (IOW,
leave it as an implementation detail how the necessary pointers are
passed to the callee.)

> and the callee calls this function passing back the pointer and the
> address of the parameter to initialize.

Why wouldn't the thunk return the result using the normal conventions
for doing so?

I could *possibly* see an argument for this. However, a major argument
*against* is that it precludes returning the result in a register, in
case the result is something simple (e.g. 'int'). Why require allocating
stack space for the result if not necessary?

> Any extra data needed is placed immediately after this struct (which
> is why the callee passes the pointer back).

Right; the 'data pointer' component is opaque to the callee and
references whatever the thunk needs to execute.

> There's no need for the called function to be a template. There's no
> need for the thunk to be representable as an ordinary lambda.

*Right*. I feel strongly on this point; trying to do either of these
makes the implementation less performing and reduces potential for
optimization, for no obvious benefit.

--=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, 23 May 2014 14:47:25 -0400
Raw View
On 2014-05-23 14:13, Diggory Blake wrote:
> On Friday, 23 May 2014 18:38:16 UTC+1, Hyman Rosen wrote:
>> 4) The first evaluation of the parameter in any context (even just having
>> its address taken, for example, but not in non-evaluated contexts such as
>> sizeof) causes the argument to be evaluated as if it had been an ordinary
>> function call argument and results in the reserved parameter space being
>> initialized as if it had been an ordinary parameter.
>
> So you're suggesting having the parameter be evaluated implicitly just by
> using the name?

What do you mean by "using the name"? If you need the value (or address)
of the parameter, then yes, it must be evaluated at that point.

> - C++ has so far stayed away from having "hidden" method calls in the code.
> Up until now it's always been clear what is a function call and might go
> off and execute some other code, with this it wouldn't be.

If this is just a matter of requiring that one write 'arg()' to get the
value of a delayed parameter, I could live with that.

> - What do you expect the behaviour of this to be:
> auto foo(string [&] arg) {
>     return [=]() { return arg; };
> }

Since you are binding by value, defining the lambda requires the value
of 'arg'. Therefore, your example is equivalent to:

  auto foo(string [&] arg) {
      auto const string __arg = arg;
      return [=]() { return __arg; };
  }

(Note that there is no flag in the above; the compiler knows that 'arg'
is only ever evaluated once, and so does not need to generate such code.)

> - What about this:
> auto foo(string [&] arg) {
>     auto unused = arg;
>     return [=]() { return arg; };
> }

Same as above, for the same reason.

> - Or this:
> foo(1/0)
> void foo(int [&] arg) {
>     int a = arg; // Divide by zero???
> }

Maybe not. Since 'a' is not used, I could imagine that the compiler
generates an empty body for foo().

This suggests that perhaps naming the argument forces evaluation, even
if the value is subsequently not used. In which case, yes, the above
would divide by zero. (It would for an immediate parameter, also; we've
only changed at what point the exception is generated.)

--
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: Fri, 23 May 2014 14:51:53 -0400
Raw View
On 2014-05-23 14:23, Nicola Gigante wrote:
> I have some questions in my head:
> 1) is there a good way to specify and implement this in a way
> that such a function can be linkable from code unaware of this new featur=
e?

I would expect it is trivial to have the compiler generate two forms for
a symbol, one with delayed paramaters, and one in which the parameters
are instead immediate, such that "old" compilers would be able to call
the immediate-parameters version. (I already suggested this where I
mentioned the possibility of using an attribute to denote delayed
evaluation rather than '[&]', which would also allow "old" compilers to
seamlessly=C2=B9 build code that otherwise uses this feature.)

I don't want to attempt to have "old" compilers able to generate code
that would ("correctly") call a function that takes delayed parameters.

(=C2=B9 ...but *ONLY* if the parameters are evaluated by being named; if we
make them look like functors instead, this falls apart.)

--=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: =?UTF-8?Q?David_Rodr=C3=ADguez_Ibeas?= <dibeas@ieee.org>
Date: Fri, 23 May 2014 14:55:34 -0400
Raw View
--001a11c20e7a4cc37904fa15c69e
Content-Type: text/plain; charset=UTF-8

Matthrew, yan you review this paragraph?

On Fri, May 23, 2014 at 2:39 PM, Matthew Woehlke <
mw_triad@users.sourceforge.net> wrote:

> Others may have expressed that desire. I still prefer that the callee
> reserves space, but the caller is responsible for /ensuring/ (as an
> implementation detail) that the lambda is only called once. The
> mechanism for doing this shall not be specified. I think it's important
> that the compiler be permitted to make this assurance simply by knowing
> that no code path results in multiple evaluation, in which case no flag
> would be needed.
>

I am not sure whether you really mean what you wrote, it seems to me that
the 'caller' cannot possibly ensure that the argument is evaluated at most
once, right?

--

---
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/.

--001a11c20e7a4cc37904fa15c69e
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Matthrew, yan you review this paragraph?<div class=3D"gmai=
l_extra"><br><div class=3D"gmail_quote">On Fri, May 23, 2014 at 2:39 PM, Ma=
tthew Woehlke <span dir=3D"ltr">&lt;<a href=3D"mailto:mw_triad@users.source=
forge.net" target=3D"_blank">mw_triad@users.sourceforge.net</a>&gt;</span> =
wrote:<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex"><div class=3D"">Others may have expressed th=
at desire. I still prefer that the callee<br></div>
reserves space, but the caller is responsible for /ensuring/ (as an<br>
implementation detail) that the lambda is only called once. The<br>
mechanism for doing this shall not be specified. I think it&#39;s important=
<br>
that the compiler be permitted to make this assurance simply by knowing<br>
that no code path results in multiple evaluation, in which case no flag<br>
would be needed.<br></blockquote><div><br>I am not sure whether you really =
mean what you wrote, it seems to me that the &#39;caller&#39; cannot possib=
ly ensure that the argument is evaluated at most once, right?</div></div>
</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 />

--001a11c20e7a4cc37904fa15c69e--

.


Author: =?UTF-8?Q?David_Rodr=C3=ADguez_Ibeas?= <dibeas@ieee.org>
Date: Fri, 23 May 2014 15:09:44 -0400
Raw View
--047d7bf0e204f1918104fa15f816
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

Sorry for the typo: Matthew. Ouch


On Fri, May 23, 2014 at 2:55 PM, David Rodr=C3=ADguez Ibeas <dibeas@ieee.or=
g>wrote:

> Matthrew, yan you review this paragraph?
>
> On Fri, May 23, 2014 at 2:39 PM, Matthew Woehlke <
> mw_triad@users.sourceforge.net> wrote:
>
>> Others may have expressed that desire. I still prefer that the callee
>> reserves space, but the caller is responsible for /ensuring/ (as an
>> implementation detail) that the lambda is only called once. The
>> mechanism for doing this shall not be specified. I think it's important
>> that the compiler be permitted to make this assurance simply by knowing
>> that no code path results in multiple evaluation, in which case no flag
>> would be needed.
>>
>
> I am not sure whether you really mean what you wrote, it seems to me that
> the 'caller' cannot possibly ensure that the argument is evaluated at mos=
t
> once, right?
>

--=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/.

--047d7bf0e204f1918104fa15f816
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Sorry for the typo: Matthew. Ouch</div><div class=3D"gmail=
_extra"><br><br><div class=3D"gmail_quote">On Fri, May 23, 2014 at 2:55 PM,=
 David Rodr=C3=ADguez Ibeas <span dir=3D"ltr">&lt;<a href=3D"mailto:dibeas@=
ieee.org" target=3D"_blank">dibeas@ieee.org</a>&gt;</span> wrote:<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex"><div dir=3D"ltr">Matthrew, yan you review th=
is paragraph?<div class=3D"gmail_extra"><br><div class=3D"gmail_quote"><div=
 class=3D"">
On Fri, May 23, 2014 at 2:39 PM, Matthew Woehlke <span dir=3D"ltr">&lt;<a h=
ref=3D"mailto:mw_triad@users.sourceforge.net" target=3D"_blank">mw_triad@us=
ers.sourceforge.net</a>&gt;</span> wrote:<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex"><div>Others may have expressed that desire. =
I still prefer that the callee<br></div>
reserves space, but the caller is responsible for /ensuring/ (as an<br>
implementation detail) that the lambda is only called once. The<br>
mechanism for doing this shall not be specified. I think it&#39;s important=
<br>
that the compiler be permitted to make this assurance simply by knowing<br>
that no code path results in multiple evaluation, in which case no flag<br>
would be needed.<br></blockquote></div><div><br>I am not sure whether you r=
eally mean what you wrote, it seems to me that the &#39;caller&#39; cannot =
possibly ensure that the argument is evaluated at most once, right?</div>
</div>
</div></div>
</blockquote></div><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 />

--047d7bf0e204f1918104fa15f816--

.


Author: Matthew Woehlke <mw_triad@users.sourceforge.net>
Date: Fri, 23 May 2014 16:32:20 -0400
Raw View
On 2014-05-23 14:55, David Rodr=C3=ADguez Ibeas wrote:
> On Fri, May 23, 2014 at 2:39 PM, Matthew Woehlke wrote:
>> Others may have expressed that desire. I still prefer that the callee
>> reserves space, but the caller is responsible for /ensuring/ (as an
>> implementation detail) that the lambda is only called once. The
>> mechanism for doing this shall not be specified. I think it's important
>> that the compiler be permitted to make this assurance simply by knowing
>> that no code path results in multiple evaluation, in which case no flag
>> would be needed.
>=20
> I am not sure whether you really mean what you wrote, it seems to me that
> the 'caller' cannot possibly ensure that the argument is evaluated at mos=
t
> once, right?

Oops, yes... good catch; thanks. Too many caller / callee to keep
straight :-).

(That should be "I still prefer that the *caller* reserves space, but
the *callee* is responsible for ensuring [...] that the [thunk] is only
called once.")

--=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: Diggory Blake <diggsey@googlemail.com>
Date: Fri, 23 May 2014 13:48:42 -0700 (PDT)
Raw View
------=_Part_841_2013226.1400878122380
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

I'm not sure it's a good thing for old compilers to be able to compile it=
=20
but just ignore the lazy part of the evaluation. Lazy evaluation changes=20
the behaviour of the program - a valid and useful program which relies on=
=20
lazy evaluation may not even terminate if parameters are evaluated early.=
=20
If code using lazy arguments is compiled on a compiler without support for=
=20
them it should error.

On Friday, 23 May 2014 19:55:06 UTC+1, Matthew Woehlke wrote:
>
> On 2014-05-23 14:23, Nicola Gigante wrote:=20
> > I have some questions in my head:=20
> > 1) is there a good way to specify and implement this in a way=20
> > that such a function can be linkable from code unaware of this new=20
> feature?=20
>
> I would expect it is trivial to have the compiler generate two forms for=
=20
> a symbol, one with delayed paramaters, and one in which the parameters=20
> are instead immediate, such that "old" compilers would be able to call=20
> the immediate-parameters version. (I already suggested this where I=20
> mentioned the possibility of using an attribute to denote delayed=20
> evaluation rather than '[&]', which would also allow "old" compilers to=
=20
> seamlessly=C2=B9 build code that otherwise uses this feature.)=20
>
> I don't want to attempt to have "old" compilers able to generate code=20
> that would ("correctly") call a function that takes delayed parameters.=
=20
>
> (=C2=B9 ...but *ONLY* if the parameters are evaluated by being named; if =
we=20
> make them look like functors instead, this falls apart.)=20
>
> --=20
> Matthew=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_841_2013226.1400878122380
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">I'm not sure it's a good thing for old compilers to be abl=
e to compile it but just ignore the lazy part of the evaluation. Lazy evalu=
ation changes the behaviour of the program - a valid and useful program whi=
ch relies on lazy evaluation may not even terminate if parameters are evalu=
ated early. If code using lazy arguments is compiled on a compiler without =
support for them it should error.<br><br>On Friday, 23 May 2014 19:55:06 UT=
C+1, Matthew Woehlke  wrote:<blockquote class=3D"gmail_quote" style=3D"marg=
in: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On=
 2014-05-23 14:23, Nicola Gigante wrote:
<br>&gt; I have some questions in my head:
<br>&gt; 1) is there a good way to specify and implement this in a way
<br>&gt; that such a function can be linkable from code unaware of this new=
 feature?
<br>
<br>I would expect it is trivial to have the compiler generate two forms fo=
r
<br>a symbol, one with delayed paramaters, and one in which the parameters
<br>are instead immediate, such that "old" compilers would be able to call
<br>the immediate-parameters version. (I already suggested this where I
<br>mentioned the possibility of using an attribute to denote delayed
<br>evaluation rather than '[&amp;]', which would also allow "old" compiler=
s to
<br>seamlessly=C2=B9 build code that otherwise uses this feature.)
<br>
<br>I don't want to attempt to have "old" compilers able to generate code
<br>that would ("correctly") call a function that takes delayed parameters.
<br>
<br>(=C2=B9 ...but *ONLY* if the parameters are evaluated by being named; i=
f we
<br>make them look like functors instead, this falls apart.)
<br>
<br>--=20
<br>Matthew
<br>
<br></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_841_2013226.1400878122380--

.


Author: Mikhail Semenov <mikhailsemenov1957@gmail.com>
Date: Sun, 25 May 2014 11:43:09 -0700 (PDT)
Raw View
------=_Part_96_2795105.1401043389476
Content-Type: text/plain; charset=UTF-8


The idea is quite simple if we look at the definition of the proposal in
terms of transformation.
If we have a function defined as follows:
void f([&] T x)
{
   if (b)
      a = x();
}



and is used like this:
f(e);


Then it is equivalent to the following program fragment:
The function f1 is defined as follows:
void f1(function<T()> expr)
{
   if (b)
      a = expr();
}


and is used as follows:

f1([&]()->T { return e;});


We can have a similar definition for other cases, g([=] T x), etc.

By the way it looks obvious that we may have even the case:
void p([&] void x)
{
    if (b)
       x(); // we are only interested in side effects, no need of the value.
}



It is good that we keep () after the parameter it makes it clear that it is
a function call.


On Friday, May 23, 2014 7:13:22 PM UTC+1, Diggory Blake wrote:

>
>
> On Friday, 23 May 2014 18:38:16 UTC+1, Hyman Rosen wrote:
>>
>> I haven't chimed in since my original post.  I would just like to
>> explain/summarize my understanding of the salient points of the proposal.
>>
>> 1)  The annotation [&] of the parameter is a mnemonic to indicate that
>> evaluation of the parameter causes the side effects of the argument
>> expression when it is evaluated.  I don't anticipate needing other capture
>> forms.
>>
>> 2) I agree that the 0-or-1 evaluation model is better and easier to
>> understand than the multiple-evaluation model, and withdraw the latter.
>>
>> 3) For each [&] parameter, the called function contains reserved space on
>> the stack for the parameter, plus a boolean variable indicating whether the
>> argument expression has been evaluated. [User-accessible? Maybe!]  Upon
>> exit from the function, if the boolean variable is set, the destructor for
>> the parameter is called.
>>
>> 4) The first evaluation of the parameter in any context (even just having
>> its address taken, for example, but not in non-evaluated contexts such as
>> sizeof) causes the argument to be evaluated as if it had been an ordinary
>> function call argument and results in the reserved parameter space being
>> initialized as if it had been an ordinary parameter.
>>
>
> So you're suggesting having the parameter be evaluated implicitly just by
> using the name?
> - C++ has so far stayed away from having "hidden" method calls in the
> code. Up until now it's always been clear what is a function call and might
> go off and execute some other code, with this it wouldn't be.
> - What do you expect the behaviour of this to be:
> auto foo(string [&] arg) {
>     return [=]() { return arg; };
> }
>
> - What about this:
> auto foo(string [&] arg) {
>     auto unused = arg;
>     return [=]() { return arg; };
> }
>
> - Or this:
> foo(1/0)
> void foo(int [&] arg) {
>     int a = arg; // Divide by zero???
> }
>
> IMHO, having the evaluation be implicit is a bad idea. It should be clear
> to anyone reading the code that it's going off and evaluating some other
> expression.
>
>
>
>>
>> 5) The "lambda" (or "thunk", to bring back an old term) used for this
>> could be a pointer to something as simple as
>>     struct { void (*f)(void *this_struct, void *parameter); };
>> The caller creates one of these objects on the stack with f pointing to
>> the argument evaluation code and passes a pointer to it to the callee, and
>> the callee calls this function passing back the pointer and the address of
>> the parameter to initialize.  Any extra data needed is placed immediately
>> after this struct (which is why the callee passes the pointer back).
>>  There's no need for the called function to be a template.  There's no need
>> for the thunk to be representable as an ordinary lambda.
>>
>>
> Lambdas are just anonymous structs like that, and the type erasure you are
> describing is exactly the same as that done by std::function already. Seems
> silly to duplicate the functionality. Templates would avoid the need for
> the extra indirection, so it would be nice if it were possible to use them.
>
>

--

---
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_96_2795105.1401043389476
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div><br></div><div>The idea is quite simple if we look at=
 the definition of the proposal in terms of transformation.</div><div>If we=
 have a function defined as follows:</div><div class=3D"prettyprint" style=
=3D"border: 1px solid rgb(187, 187, 187); border-image: none; -ms-word-wrap=
: break-word; background-color: rgb(250, 250, 250);"><code class=3D"prettyp=
rint"><div class=3D"subprettyprint"><span class=3D"styled-by-prettify" styl=
e=3D"color: rgb(0, 0, 136);">void</span><span class=3D"styled-by-prettify" =
style=3D"color: rgb(0, 0, 0);"> f</span><span class=3D"styled-by-prettify" =
style=3D"color: rgb(102, 102, 0);">([&amp;]</span><span class=3D"styled-by-=
prettify" style=3D"color: rgb(0, 0, 0);"> T x</span><span class=3D"styled-b=
y-prettify" style=3D"color: rgb(102, 102, 0);">)</span><span class=3D"style=
d-by-prettify" style=3D"color: rgb(0, 0, 0);"><br></span><span class=3D"sty=
led-by-prettify" style=3D"color: rgb(102, 102, 0);">{</span><span class=3D"=
styled-by-prettify" style=3D"color: rgb(0, 0, 0);"><br>&nbsp; &nbsp;</span>=
<span class=3D"styled-by-prettify" style=3D"color: rgb(0, 0, 136);">if</spa=
n><span class=3D"styled-by-prettify" style=3D"color: rgb(0, 0, 0);"> </span=
><span class=3D"styled-by-prettify" style=3D"color: rgb(102, 102, 0);">(</s=
pan><span class=3D"styled-by-prettify" style=3D"color: rgb(0, 0, 0);">b</sp=
an><span class=3D"styled-by-prettify" style=3D"color: rgb(102, 102, 0);">)<=
/span><span class=3D"styled-by-prettify" style=3D"color: rgb(0, 0, 0);"><br=
>&nbsp; &nbsp; &nbsp; a </span><span class=3D"styled-by-prettify" style=3D"=
color: rgb(102, 102, 0);">=3D</span><span class=3D"styled-by-prettify" styl=
e=3D"color: rgb(0, 0, 0);"> x</span><span class=3D"styled-by-prettify" styl=
e=3D"color: rgb(102, 102, 0);">();</span><span class=3D"styled-by-prettify"=
 style=3D"color: rgb(0, 0, 0);"><br></span><span class=3D"styled-by-prettif=
y" style=3D"color: rgb(102, 102, 0);">}</span><span class=3D"styled-by-pret=
tify" style=3D"color: rgb(0, 0, 0);"><br><br></span></div></code></div><br>=
<div><br></div><div>and&nbsp;is&nbsp;used like this:</div><div><font face=
=3D"courier new,monospace"><div class=3D"prettyprint" style=3D"border: 1px =
solid rgb(187, 187, 187); border-image: none; -ms-word-wrap: break-word; ba=
ckground-color: rgb(250, 250, 250);"><code class=3D"prettyprint"><div class=
=3D"subprettyprint"><span class=3D"styled-by-prettify" style=3D"color: rgb(=
0, 0, 0);">f</span><span class=3D"styled-by-prettify" style=3D"color: rgb(1=
02, 102, 0);">(</span><span class=3D"styled-by-prettify" style=3D"color: rg=
b(0, 0, 0);">e</span><span class=3D"styled-by-prettify" style=3D"color: rgb=
(102, 102, 0);">);</span></div></code></div><br></font></div><div><br></div=
><div>Then it is equivalent to the following program fragment:</div><div>Th=
e function f1 is defined as follows:</div><div><font face=3D"courier new,mo=
nospace"><div class=3D"prettyprint" style=3D"border: 1px solid rgb(187, 187=
, 187); border-image: none; -ms-word-wrap: break-word; background-color: rg=
b(250, 250, 250);"><code class=3D"prettyprint"><div class=3D"subprettyprint=
"><span class=3D"styled-by-prettify" style=3D"color: rgb(0, 0, 136);">void<=
/span><span class=3D"styled-by-prettify" style=3D"color: rgb(0, 0, 0);"> f1=
</span><span class=3D"styled-by-prettify" style=3D"color: rgb(102, 102, 0);=
">(</span><span class=3D"styled-by-prettify" style=3D"color: rgb(0, 0, 136)=
;">function</span><span class=3D"styled-by-prettify" style=3D"color: rgb(10=
2, 102, 0);">&lt;</span><span class=3D"styled-by-prettify" style=3D"color: =
rgb(0, 0, 0);">T</span><span class=3D"styled-by-prettify" style=3D"color: r=
gb(102, 102, 0);">()&gt;</span><span class=3D"styled-by-prettify" style=3D"=
color: rgb(0, 0, 0);"> expr</span><span class=3D"styled-by-prettify" style=
=3D"color: rgb(102, 102, 0);">)</span><span class=3D"styled-by-prettify" st=
yle=3D"color: rgb(0, 0, 0);"><br></span><span class=3D"styled-by-prettify" =
style=3D"color: rgb(102, 102, 0);">{</span><span class=3D"styled-by-prettif=
y" style=3D"color: rgb(0, 0, 0);"><br>&nbsp; &nbsp;</span><span class=3D"st=
yled-by-prettify" style=3D"color: rgb(0, 0, 136);">if</span><span class=3D"=
styled-by-prettify" style=3D"color: rgb(0, 0, 0);"> </span><span class=3D"s=
tyled-by-prettify" style=3D"color: rgb(102, 102, 0);">(</span><span class=
=3D"styled-by-prettify" style=3D"color: rgb(0, 0, 0);">b</span><span class=
=3D"styled-by-prettify" style=3D"color: rgb(102, 102, 0);">)</span><span cl=
ass=3D"styled-by-prettify" style=3D"color: rgb(0, 0, 0);"><br>&nbsp; &nbsp;=
 &nbsp; a </span><span class=3D"styled-by-prettify" style=3D"color: rgb(102=
, 102, 0);">=3D</span><span class=3D"styled-by-prettify" style=3D"color: rg=
b(0, 0, 0);"> expr</span><span class=3D"styled-by-prettify" style=3D"color:=
 rgb(102, 102, 0);">();</span><span class=3D"styled-by-prettify" style=3D"c=
olor: rgb(0, 0, 0);"><br></span><span class=3D"styled-by-prettify" style=3D=
"color: rgb(102, 102, 0);">}</span></div></code></div><br></font></div><div=
><br></div><div>and is used as follows:</div><div><br></div><div><div class=
=3D"prettyprint" style=3D"border: 1px solid rgb(187, 187, 187); border-imag=
e: none; -ms-word-wrap: break-word; background-color: rgb(250, 250, 250);">=
<code class=3D"prettyprint"><div class=3D"subprettyprint"><span class=3D"st=
yled-by-prettify" style=3D"color: rgb(0, 0, 0);">f1</span><span class=3D"st=
yled-by-prettify" style=3D"color: rgb(102, 102, 0);">([&amp;]()-&gt;</span>=
<span class=3D"styled-by-prettify" style=3D"color: rgb(0, 0, 0);">T </span>=
<span class=3D"styled-by-prettify" style=3D"color: rgb(102, 102, 0);">{</sp=
an><span class=3D"styled-by-prettify" style=3D"color: rgb(0, 0, 0);"> </spa=
n><span class=3D"styled-by-prettify" style=3D"color: rgb(0, 0, 136);">retur=
n</span><span class=3D"styled-by-prettify" style=3D"color: rgb(0, 0, 0);"> =
e</span><span class=3D"styled-by-prettify" style=3D"color: rgb(102, 102, 0)=
;">;});</span></div></code></div><font face=3D"courier new,monospace"><br><=
/font></div><div><br></div><div>We can have a similar definition for other =
cases, g([=3D] T x), etc.</div><div><br></div><div>By the way it looks obvi=
ous that we may have even the case:</div><div class=3D"prettyprint" style=
=3D"border: 1px solid rgb(187, 187, 187); border-image: none; -ms-word-wrap=
: break-word; background-color: rgb(250, 250, 250);"><code class=3D"prettyp=
rint"><div class=3D"subprettyprint"><span class=3D"styled-by-prettify" styl=
e=3D"color: rgb(0, 0, 136);">void</span><span class=3D"styled-by-prettify" =
style=3D"color: rgb(0, 0, 0);"> p</span><span class=3D"styled-by-prettify" =
style=3D"color: rgb(102, 102, 0);">([&amp;]</span><span class=3D"styled-by-=
prettify" style=3D"color: rgb(0, 0, 0);"> </span><span class=3D"styled-by-p=
rettify" style=3D"color: rgb(0, 0, 136);">void</span><span class=3D"styled-=
by-prettify" style=3D"color: rgb(0, 0, 0);"> x</span><span class=3D"styled-=
by-prettify" style=3D"color: rgb(102, 102, 0);">)</span><span class=3D"styl=
ed-by-prettify" style=3D"color: rgb(0, 0, 0);"><br></span><span class=3D"st=
yled-by-prettify" style=3D"color: rgb(102, 102, 0);">{</span><span class=3D=
"styled-by-prettify" style=3D"color: rgb(0, 0, 0);"><br>&nbsp; &nbsp; </spa=
n><span class=3D"styled-by-prettify" style=3D"color: rgb(0, 0, 136);">if</s=
pan><span class=3D"styled-by-prettify" style=3D"color: rgb(0, 0, 0);"> </sp=
an><span class=3D"styled-by-prettify" style=3D"color: rgb(102, 102, 0);">(<=
/span><span class=3D"styled-by-prettify" style=3D"color: rgb(0, 0, 0);">b</=
span><span class=3D"styled-by-prettify" style=3D"color: rgb(102, 102, 0);">=
)</span><span class=3D"styled-by-prettify" style=3D"color: rgb(0, 0, 0);"><=
br>&nbsp; &nbsp; &nbsp; &nbsp;x</span><span class=3D"styled-by-prettify" st=
yle=3D"color: rgb(102, 102, 0);">();</span><span class=3D"styled-by-prettif=
y" style=3D"color: rgb(0, 0, 0);"> </span><span class=3D"styled-by-prettify=
" style=3D"color: rgb(136, 0, 0);">// we are only interested in side effect=
s, no need of the value.</span><span class=3D"styled-by-prettify" style=3D"=
color: rgb(0, 0, 0);"><br></span><span class=3D"styled-by-prettify" style=
=3D"color: rgb(102, 102, 0);">}</span></div></code></div><div><br></div><di=
v><br></div><div><br></div><div><div>It is good that we keep () after the p=
arameter it makes it clear that it is a function call.</div></div><div><br>=
<br>On Friday, May 23, 2014 7:13:22 PM UTC+1, Diggory Blake wrote:</div><bl=
ockquote class=3D"gmail_quote" style=3D"margin: 0px 0px 0px 0.8ex; padding-=
left: 1ex; border-left-color: rgb(204, 204, 204); border-left-width: 1px; b=
order-left-style: solid;"><div dir=3D"ltr"><br><br>On Friday, 23 May 2014 1=
8:38:16 UTC+1, Hyman Rosen  wrote:<blockquote class=3D"gmail_quote" style=
=3D"margin: 0px 0px 0px 0.8ex; padding-left: 1ex; border-left-color: rgb(20=
4, 204, 204); border-left-width: 1px; border-left-style: solid;"><div dir=
=3D"ltr">I haven't chimed in since my original post. &nbsp;I would just lik=
e to explain/summarize my understanding of the salient points of the propos=
al.<div><br></div><div>1) &nbsp;The annotation [&amp;] of the parameter is =
a mnemonic to indicate that evaluation of the parameter causes the side eff=
ects of the argument expression when it is evaluated. &nbsp;I don't anticip=
ate needing other capture forms.</div>

<div><br></div><div>2) I agree that the 0-or-1 evaluation model is better a=
nd easier to understand than the multiple-evaluation model, and withdraw th=
e latter.</div><div><br></div><div>3) For each [&amp;] parameter, the calle=
d function contains reserved space on the stack for the parameter, plus a b=
oolean variable indicating whether the argument expression has been evaluat=
ed. [User-accessible? Maybe!] &nbsp;Upon exit from the function, if the boo=
lean variable is set, the destructor for the parameter is called.</div>

<div><br></div><div>4) The first evaluation of the parameter in any context=
 (even just having its address taken, for example, but not in non-evaluated=
 contexts such as sizeof) causes the argument to be evaluated as if it had =
been an ordinary function call argument and results in the reserved paramet=
er space being initialized as if it had been an ordinary parameter.</div></=
div></blockquote><div><br>So you're suggesting having the parameter be eval=
uated implicitly just by using the name?<br>- C++ has so far stayed away fr=
om having "hidden" method calls in the code. Up until now it's always been =
clear what is a function call and might go off and execute some other code,=
 with this it wouldn't be.<br>- What do you expect the behaviour of this to=
 be:<br><div style=3D"border: 1px solid rgb(187, 187, 187); border-image: n=
one; -ms-word-wrap: break-word; background-color: rgb(250, 250, 250);"><cod=
e><div><span style=3D"color: rgb(0, 0, 136);">auto</span><span style=3D"col=
or: rgb(0, 0, 0);"> foo</span><span style=3D"color: rgb(102, 102, 0);">(</s=
pan><span style=3D"color: rgb(0, 0, 136);">string</span><span style=3D"colo=
r: rgb(0, 0, 0);"> </span><span style=3D"color: rgb(102, 102, 0);">[&amp;]<=
/span><span style=3D"color: rgb(0, 0, 0);"> arg</span><span style=3D"color:=
 rgb(102, 102, 0);">)</span><span style=3D"color: rgb(0, 0, 0);"> </span><s=
pan style=3D"color: rgb(102, 102, 0);">{</span><span style=3D"color: rgb(0,=
 0, 0);"><br>&nbsp; &nbsp; </span><span style=3D"color: rgb(0, 0, 136);">re=
turn</span><span style=3D"color: rgb(0, 0, 0);"> </span><span style=3D"colo=
r: rgb(102, 102, 0);">[=3D]()</span><span style=3D"color: rgb(0, 0, 0);"> <=
/span><span style=3D"color: rgb(102, 102, 0);">{</span><span style=3D"color=
: rgb(0, 0, 0);"> </span><span style=3D"color: rgb(0, 0, 136);">return</spa=
n><span style=3D"color: rgb(0, 0, 0);"> arg</span><span style=3D"color: rgb=
(102, 102, 0);">;</span><span style=3D"color: rgb(0, 0, 0);"> </span><span =
style=3D"color: rgb(102, 102, 0);">};</span><span style=3D"color: rgb(0, 0,=
 0);"><br></span><span style=3D"color: rgb(102, 102, 0);">}</span><span sty=
le=3D"color: rgb(0, 0, 0);"><br></span></div></code></div><br>- What about =
this:<br><div style=3D"border: 1px solid rgb(187, 187, 187); border-image: =
none; -ms-word-wrap: break-word; background-color: rgb(250, 250, 250);"><co=
de><div><span style=3D"color: rgb(0, 0, 136);">auto</span><span style=3D"co=
lor: rgb(0, 0, 0);"> foo</span><span style=3D"color: rgb(102, 102, 0);">(</=
span><span style=3D"color: rgb(0, 0, 136);">string</span><span style=3D"col=
or: rgb(0, 0, 0);"> </span><span style=3D"color: rgb(102, 102, 0);">[&amp;]=
</span><span style=3D"color: rgb(0, 0, 0);"> arg</span><span style=3D"color=
: rgb(102, 102, 0);">)</span><span style=3D"color: rgb(0, 0, 0);"> </span><=
span style=3D"color: rgb(102, 102, 0);">{</span><span style=3D"color: rgb(0=
, 0, 0);"><br>&nbsp; &nbsp; </span><span style=3D"color: rgb(0, 0, 136);">a=
uto</span><span style=3D"color: rgb(0, 0, 0);"> unused </span><span style=
=3D"color: rgb(102, 102, 0);">=3D</span><span style=3D"color: rgb(0, 0, 0);=
"> arg</span><span style=3D"color: rgb(102, 102, 0);">;</span><span style=
=3D"color: rgb(0, 0, 0);"><br>&nbsp; &nbsp; </span><span style=3D"color: rg=
b(0, 0, 136);">return</span><span style=3D"color: rgb(0, 0, 0);"> </span><s=
pan style=3D"color: rgb(102, 102, 0);">[=3D]()</span><span style=3D"color: =
rgb(0, 0, 0);"> </span><span style=3D"color: rgb(102, 102, 0);">{</span><sp=
an style=3D"color: rgb(0, 0, 0);"> </span><span style=3D"color: rgb(0, 0, 1=
36);">return</span><span style=3D"color: rgb(0, 0, 0);"> arg</span><span st=
yle=3D"color: rgb(102, 102, 0);">;</span><span style=3D"color: rgb(0, 0, 0)=
;"> </span><span style=3D"color: rgb(102, 102, 0);">};</span><span style=3D=
"color: rgb(0, 0, 0);"><br></span><span style=3D"color: rgb(102, 102, 0);">=
}</span><span style=3D"color: rgb(0, 0, 0);"><br></span></div></code></div>=
<br>- Or this:<br><div style=3D"border: 1px solid rgb(187, 187, 187); borde=
r-image: none; -ms-word-wrap: break-word; background-color: rgb(250, 250, 2=
50);"><code><div><span style=3D"color: rgb(0, 0, 0);">foo</span><span style=
=3D"color: rgb(102, 102, 0);">(</span><span style=3D"color: rgb(0, 102, 102=
);">1</span><span style=3D"color: rgb(102, 102, 0);">/</span><span style=3D=
"color: rgb(0, 102, 102);">0</span><span style=3D"color: rgb(102, 102, 0);"=
>)</span><span style=3D"color: rgb(0, 0, 0);"><br></span><span style=3D"col=
or: rgb(0, 0, 136);">void</span><span style=3D"color: rgb(0, 0, 0);"> foo</=
span><span style=3D"color: rgb(102, 102, 0);">(</span><span style=3D"color:=
 rgb(0, 0, 136);">int</span><span style=3D"color: rgb(0, 0, 0);"> </span><s=
pan style=3D"color: rgb(102, 102, 0);">[&amp;]</span><span style=3D"color: =
rgb(0, 0, 0);"> arg</span><span style=3D"color: rgb(102, 102, 0);">)</span>=
<span style=3D"color: rgb(0, 0, 0);"> </span><span style=3D"color: rgb(102,=
 102, 0);">{</span><span style=3D"color: rgb(0, 0, 0);"><br>&nbsp; &nbsp; <=
/span><span style=3D"color: rgb(0, 0, 136);">int</span><span style=3D"color=
: rgb(0, 0, 0);"> a </span><span style=3D"color: rgb(102, 102, 0);">=3D</sp=
an><span style=3D"color: rgb(0, 0, 0);"> arg</span><span style=3D"color: rg=
b(102, 102, 0);">;</span><span style=3D"color: rgb(0, 0, 0);"> </span><span=
 style=3D"color: rgb(136, 0, 0);">// Divide by zero???</span><span style=3D=
"color: rgb(0, 0, 0);"><br></span><span style=3D"color: rgb(102, 102, 0);">=
}</span><span style=3D"color: rgb(0, 0, 0);"><br></span></div></code></div>=
<br>IMHO, having the evaluation be implicit is a bad idea. It should be cle=
ar to anyone reading the code that it's going off and evaluating some other=
 expression.<br><br>&nbsp;</div><blockquote class=3D"gmail_quote" style=3D"=
margin: 0px 0px 0px 0.8ex; padding-left: 1ex; border-left-color: rgb(204, 2=
04, 204); border-left-width: 1px; border-left-style: solid;"><div dir=3D"lt=
r">

<div><br></div><div>5) The "lambda" (or "thunk", to bring back an old term)=
 used for this could be a pointer to something as simple as<br>&nbsp; &nbsp=
; struct { void (*f)(void *this_struct, void *parameter); };</div>

<div>The caller creates one of these objects on the stack with f pointing t=
o the argument evaluation code and passes a pointer to it to the callee, an=
d the callee calls this function passing back the pointer and the address o=
f the parameter to initialize. &nbsp;Any extra data needed is placed immedi=
ately after this struct (which is why the callee passes the pointer back). =
&nbsp;There's no need for the called function to be a template. &nbsp;There=
's no need for the thunk to be representable as an ordinary lambda.</div>

</div><div><br></div></blockquote><div><br>Lambdas are just anonymous struc=
ts like that, and the type erasure you are describing is exactly the same a=
s that done by std::function already. Seems silly to duplicate the function=
ality. Templates would avoid the need for the extra indirection, so it woul=
d be nice if it were possible to use them.</div><br></div></blockquote></di=
v>

<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_96_2795105.1401043389476--

.


Author: Edward Catmur <ed@catmur.co.uk>
Date: Sun, 25 May 2014 13:13:11 -0700 (PDT)
Raw View
------=_Part_1645_22723100.1401048791332
Content-Type: text/plain; charset=UTF-8

I wonder if it might be a better idea to implement pass-by-lambda with a
special library type (class template), along the lines of
std::initializer_list.  Compared to a new parameter syntax this has the
advantage that no changes to core syntax or ABI are required, which is good
not only for compilers but also for tools that parse source code, analyze
symbols etc.

Using std::lazy_expression<T> as a tentative name for this class template,
the requirements are:

* Deleted default constructor; deleted copy and move constructors and
assignment operators (preventing such an object leaking out of the callee)
* Default destructor
* Exposition-only data members unspecified<T()> expression,
std::optional<T> value

For purposes of overload resolution, lazy_expression is considered to have
a non-explicit converting constructor lazy_expression(T) noexcept; however
the corresponding argument is not evaluated in place but instead captured
as though by a lambda-expression [&]() -> T { return e; }; the closure
object resulting from evaluation of the lambda-expression is used to
initialize the data member expression. [Note: the noexcept requirement
implies that the constructor of expression shall not perform memory
allocation. --end note]

For access to the lazy-initialized value, I think std::reference_wrapper<T>
is a good model as it balances implicit use via conversion operator with an
explicit get() member for those who want to be explicit or need to e.g.
access members of T through the dot operator:

* Conversion function operator T& () { if (!value) value = expression();
return *value; }
* Member function T& get() with the same behavior
* Invocation function call template operator()(ArgTypes&&...)
* Member types (again std::reference_wrapper is a good model here)

One emergent feature of this proposal is that (again as with
std::initializer_list) it is possible to construct a
std::lazy_expression<T> as a local variable, not only as a function
parameter. On balance I think this is a feature as I can think of cases
where this would simplify code (the same complex sub-expression appearing
in multiple branches).

--

---
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_1645_22723100.1401048791332
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">I wonder if it might be a better idea to implement pass-by=
-lambda with a special library type (class template), along the lines of st=
d::initializer_list. &nbsp;Compared to a new parameter syntax this has the =
advantage that no changes to core syntax or ABI are required, which is good=
 not only for compilers but also for tools that parse source code, analyze =
symbols etc.<div><br></div><div>Using std::lazy_expression&lt;T&gt; as a te=
ntative name for this class template, the requirements are:</div><div><br><=
/div><div>* Deleted default constructor; deleted copy and move constructors=
 and assignment operators (preventing such an object leaking out of the cal=
lee)</div><div>* Default destructor</div><div>* Exposition-only data member=
s unspecified&lt;T()&gt; expression, std::optional&lt;T&gt; value</div><div=
><br></div><div>For purposes of overload resolution, lazy_expression is con=
sidered to have a non-explicit converting constructor lazy_expression(T) no=
except; however the corresponding argument is not evaluated in place but in=
stead captured as though by a lambda-expression [&amp;]() -&gt; T { return =
e; }; the closure object resulting from evaluation of the lambda-expression=
 is used to initialize the data member expression. [Note: the noexcept requ=
irement implies that the constructor of expression shall not perform memory=
 allocation. --end note]</div><div><br></div><div>For access to the lazy-in=
itialized value, I think std::reference_wrapper&lt;T&gt; is a good model as=
 it balances implicit use via conversion operator with an explicit get() me=
mber for those who want to be explicit or need to e.g. access members of T =
through the dot operator:</div><div><br></div><div>*&nbsp;Conversion functi=
on operator T&amp; ()&nbsp;{ if (!value) value =3D expression(); return *va=
lue; }</div><div>* Member function T&amp; get() with the same behavior</div=
><div>* Invocation function call template operator()(ArgTypes&amp;&amp;...)=
</div><div>* Member types (again std::reference_wrapper is a good model her=
e)</div><div><br></div><div>One emergent feature of this proposal is that (=
again as with std::initializer_list) it is possible to construct a std::laz=
y_expression&lt;T&gt; as a local variable, not only as a function parameter=
.. On balance I think this is a feature as I can think of cases where this w=
ould simplify code (the same complex sub-expression appearing in multiple b=
ranches).</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_1645_22723100.1401048791332--

.


Author: David Krauss <potswa@gmail.com>
Date: Mon, 26 May 2014 12:04:39 +0800
Raw View
--Apple-Mail=_CC9F5478-09CD-4498-8165-134491A21ACA
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=ISO-8859-1

Another approach would be to pass a lambda (or equivalent entity like my pr=
oposed inline variable) directly, and then let the user idiomatically wrap =
this in something else according to desired semantics. The standard may def=
ine the wrappers generically, e.g. std::one_shot_functor which can only be =
called as an rvalue, std::memoized_functor which caches a return value and =
returns it on subsequent calls, etc. Without wrapping, the user gets multip=
le evaluation and repeated side effects.

Dynamic dispatching wrappers may enable definition of non-inline lazy funct=
ions. But the user would still have to define the inline trampoline functio=
n to wrap the naked lambda.

Although functional-style memoization may be the nicest semantic, I think i=
t's too complicated and too unlike the way the virtual machine generally op=
erates to define very well in core language terms. std::initializer_list is=
 a cautionary tale about meshing the core language and library with nontriv=
ial semantics... it even seems like it should be trivial!

Moreover the overhead of memoization is too high to give the user no altern=
ative.


On 2014-05-26, at 4:13 AM, Edward Catmur <ed@catmur.co.uk> wrote:

> I wonder if it might be a better idea to implement pass-by-lambda with a =
special library type (class template), along the lines of std::initializer_=
list.  Compared to a new parameter syntax this has the advantage that no ch=
anges to core syntax or ABI are required, which is good not only for compil=
ers but also for tools that parse source code, analyze symbols etc.

--=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=_CC9F5478-09CD-4498-8165-134491A21ACA
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=ISO-8859-1

<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;">Another approach would=
 be to pass a lambda (or equivalent entity like my proposed <font face=3D"C=
ourier">inline</font> variable) directly, and then let the user idiomatical=
ly wrap this in something else according to desired semantics. The standard=
 may define the wrappers generically, e.g. <font face=3D"Courier">std::one_=
shot_functor</font>&nbsp;which can only be called as an rvalue,&nbsp;<font =
face=3D"Courier">std::memoized_functor</font>&nbsp;which caches a return va=
lue and returns it on subsequent calls, etc. Without wrapping, the user get=
s multiple evaluation and repeated side effects.<div><br></div><div>Dynamic=
 dispatching wrappers may enable definition of non-inline lazy functions. B=
ut the user would still have to define the inline trampoline function to wr=
ap the naked lambda.</div><div><div><br></div><div>Although functional-styl=
e memoization may be the nicest semantic, I think it&rsquo;s too complicate=
d and too unlike the way the virtual machine generally operates to define v=
ery well in core language terms. <font face=3D"Courier">std::initializer_li=
st</font>&nbsp;is a cautionary tale about meshing the core language and lib=
rary with nontrivial semantics&hellip; it even seems like it should be triv=
ial!</div><div><br></div><div>Moreover the overhead of memoization is too h=
igh to give the user no alternative.<br><div><br></div><div><br><div><div>O=
n 2014&ndash;05&ndash;26, at 4:13 AM, Edward Catmur &lt;<a href=3D"mailto:e=
d@catmur.co.uk">ed@catmur.co.uk</a>&gt; wrote:</div><br class=3D"Apple-inte=
rchange-newline"><blockquote type=3D"cite"><div dir=3D"ltr">I wonder if it =
might be a better idea to implement pass-by-lambda with a special library t=
ype (class template), along the lines of std::initializer_list. &nbsp;Compa=
red to a new parameter syntax this has the advantage that no changes to cor=
e syntax or ABI are required, which is good not only for compilers but also=
 for tools that parse source code, analyze symbols etc.</div></blockquote><=
/div><br></div></div></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=_CC9F5478-09CD-4498-8165-134491A21ACA--

.


Author: David Krauss <potswa@gmail.com>
Date: Mon, 26 May 2014 12:07:46 +0800
Raw View
On 2014-05-26, at 12:04 PM, David Krauss <potswa@gmail.com> wrote:

> Dynamic dispatching wrappers may enable definition of non-inline lazy functions. But the user would still have to define the inline trampoline function to wrap the naked lambda.

Well, I suppose it could be done by the caller, by an implicit conversion constructor of the wrapper. Such use of implicit conversions needs to be studied carefully, but this might be appropriate.

--

---
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: Mikhail Semenov <mikhailsemenov1957@gmail.com>
Date: Mon, 26 May 2014 02:52:46 -0700 (PDT)
Raw View
------=_Part_1904_20577235.1401097967255
Content-Type: text/plain; charset=UTF-8


There is no problem with multiple evaluations of the lambda parameter. In
some way, the proposed mechanism is similar to one of the uses of the Lisp
eval: you pass an expression as a parameter and then evaluate it inside the
function.  You can evaluate it many times. it can be used for multiple
evaluations, and inside the function it is clear what the code is doing.
But when you call a function it may not be clear at all.

x = 0;
f(y/x); // but if it is used as a lambda parameter, it may be changed
inside:

int f([&] int expr)
{
    int sum = 0;
    for (x = 1; x <= 10; x++)
    {
        sum += expr();
    }
    return sum;
};

--

---
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_1904_20577235.1401097967255
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div><br></div><div>There is no problem with multiple eval=
uations of the lambda parameter. In some way, the proposed mechanism is sim=
ilar to one of the uses of the Lisp eval: you pass an expression as a param=
eter and then evaluate it inside the function.&nbsp; You can evaluate it ma=
ny times. it can be used for multiple evaluations, and inside the function =
it is clear what the code is doing. But when you call a function it may not=
 be clear at all.</div><div><br></div><div>x =3D 0; </div><div>f(y/x); // b=
ut if it is used as a lambda parameter, it may be changed inside:</div><div=
><br></div><div>int&nbsp;f([&amp;] int expr)</div><div>{</div><div>&nbsp;&n=
bsp;&nbsp;&nbsp;int sum =3D 0;</div><div>&nbsp;&nbsp;&nbsp; for (x =3D 1; x=
 &lt;=3D 10; x++)</div><div>&nbsp;&nbsp;&nbsp; {</div><div>&nbsp;&nbsp;&nbs=
p;&nbsp;&nbsp;&nbsp;&nbsp; sum +=3D expr();</div><div>&nbsp;&nbsp;&nbsp; }<=
/div><div>&nbsp;&nbsp;&nbsp; return sum;</div><div>};</div><div><br></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_1904_20577235.1401097967255--

.


Author: Matthew Woehlke <mw_triad@users.sourceforge.net>
Date: Mon, 26 May 2014 13:27:56 -0400
Raw View
On 2014-05-25 16:13, Edward Catmur wrote:
> I wonder if it might be a better idea to implement pass-by-lambda with a
> special library type (class template), along the lines of
> std::initializer_list.  Compared to a new parameter syntax this has the
> advantage that no changes to core syntax or ABI are required, which is good
> not only for compilers but also for tools that parse source code, analyze
> symbols etc.

If we used instead '[[delayed]]' (or '[[lazy]]', but TBH I like
'delayed' better), and don't apply the need to use ()'s when using such
parameter, then code tools don't need to change *at all* (assuming they
already recognize generic attributes, and don't need to do anything
special for delayed parameters).

As a further (albeit admittedly debatable) bonus, compilers that don't
support this feature will still compile the code.

I don't see this working very well as only a library-level feature. At
best, the compiler will optimize it at the language level anyway. At
worst, you'll lose all sorts of opportunity for optimization, which is
rather counter to the objective of the feature.

> One emergent feature of this proposal is that (again as with
> std::initializer_list) it is possible to construct a
> std::lazy_expression<T> as a local variable, not only as a function
> parameter.

Why would a language-based implementation preclude this possibility?

   [[delayed]] auto x = complicated_expr(); // what's wrong with this?

This would have the same semantics as a delayed parameter; 'x' is
initialized on first use. Again, doing this at the *language level*
allows for much better optimization. For example:

  [[delayed]] auto x = complicated_expr();
  if (cond)
  {
    do_something(x);
    ...
  }
  else if (cond)
  {
    ...stuff not using 'x'...
  }
  else
  {
    do_something_else(x)
    ...
  }

....can be transformed by the compiler to:

  if (cond)
  {
    do_something(complicated_expr());
    ... // assume this didn't use 'x'
  }
  else if (cond)
  {
    ...
  }
  else
  {
    auto x = complicated_expr();
    do_something_else(x)
    ... // e.g. this does use 'x'
  }

Note that in this case there is *ZERO* overhead to using [[delayed]];
basically the feature has allowed us to move an otherwise-duplicated
expression up out of a conditional tree, but still elide the code to
initialize the variable in case of the branch where it isn't used.

I'd like to see that same zero overhead (both in instructions and stack
usage) with a library level feature.



The big "gotcha" in both cases is when the expression has observable
side effects. Though I would argue that (except in case of implementing
proper short-circuiting Boolean operators) one should look at the
feature as a performance optimization, and generally avoid such cases.
(Or else let it be on the users' heads to take necessary steps to ensure
that all compilers in use support the feature.)

--
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: Mikhail Semenov <mikhailsemenov1957@gmail.com>
Date: Mon, 26 May 2014 11:13:17 -0700 (PDT)
Raw View
------=_Part_461_32474810.1401127997047
Content-Type: text/plain; charset=UTF-8


Why would a language-based implementation preclude this possibility?

   [[delayed]] auto x = complicated_expr(); // what's wrong with this?

Are you suggesting that we can define a parameter:

void f([[delayed]] T x)
{
    if(cond)
          send(x); // evaluates x;
}

I think the problem with "lazy evaluation" is that it is not obvious when
the variable is going to be evaluated. It is not a clear syntax.
My understanding is that it is much clearer to write:

void f([&] T x) // the parameter specification is OK
{
    if(cond)
          send(x()); // evaluates x; the syntax is clearer here
}

It's interesting that Algol was mentioned. It was in Algol-60 that
introduced a function parameter that could pick up any expression as an
actual parameter, which could be evaluated inside a function body. But I am
not aware of any implementation that used that feature.



--

---
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_461_32474810.1401127997047
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div><br></div><div><font color=3D"#0000ff">Why would a la=
nguage-based implementation preclude this possibility? <br><br>&nbsp; &nbsp=
;[[delayed]] auto x =3D complicated_expr(); // what's wrong with this? </fo=
nt></div><div><font color=3D"#0000ff"><br></font></div><div><font color=3D"=
#000000">Are you suggesting that we can define a parameter:</font></div><di=
v><font color=3D"#000000"><br></font></div><div><font color=3D"#000000">voi=
d f([[delayed]] T x)</font></div><div><font color=3D"#000000">{</font></div=
><div><font color=3D"#000000">&nbsp;&nbsp;&nbsp; if(cond)</font></div><div>=
<font color=3D"#000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp; send(x); // evaluates x;</font></div><div><font color=3D"#000000">}</fo=
nt></div><div><font color=3D"#000000"><br></font></div><div><font color=3D"=
#000000">I think the problem with "lazy evaluation" is that it is not obvio=
us when the variable is going to be evaluated. It is not a clear syntax.</f=
ont></div><div><font color=3D"#000000">My understanding is that it is much =
clearer to write:</font></div><div><font color=3D"#000000"><br></font></div=
><div><font color=3D"#000000"><div><font color=3D"#000000">void f([&amp;] T=
 x) // the parameter specification is OK</font></div><div><font color=3D"#0=
00000">{</font></div><div><font color=3D"#000000">&nbsp;&nbsp;&nbsp; if(con=
d)</font></div><div><font color=3D"#000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&=
nbsp;&nbsp;&nbsp;&nbsp; send(x()); // evaluates x; the syntax is clearer he=
re</font></div><div><font color=3D"#000000">}</font></div><div><br></div><d=
iv>It's interesting that Algol was mentioned. It was in Algol-60 that intro=
duced a function parameter that could pick up any expression as an actual p=
arameter, which could be evaluated inside a function body. But I am not awa=
re of any implementation that used that feature. </div></font></div><div><f=
ont color=3D"#000000"><br></font></div><div><font color=3D"#000000"><br></f=
ont></div><div><br></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_461_32474810.1401127997047--

.


Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Mon, 26 May 2014 21:31:29 +0300
Raw View
On 26 May 2014 20:27, Matthew Woehlke <mw_triad@users.sourceforge.net> wrote:
> Why would a language-based implementation preclude this possibility?
>
>    [[delayed]] auto x = complicated_expr(); // what's wrong with this?
>
> This would have the same semantics as a delayed parameter; 'x' is
> initialized on first use. Again, doing this at the *language level*
> allows for much better optimization. For example:

You want that to have semantics? Then get rid of the attribute and replace it
with something else.

--

---
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: Edward Catmur <ed@catmur.co.uk>
Date: Mon, 26 May 2014 11:41:32 -0700 (PDT)
Raw View
------=_Part_2291_5025531.1401129693021
Content-Type: text/plain; charset=UTF-8

On Monday, 26 May 2014 19:31:30 UTC+1, Ville Voutilainen wrote:

> On 26 May 2014 20:27, Matthew Woehlke <mw_t...@users.sourceforge.net<javascript:>>
> wrote:
> > Why would a language-based implementation preclude this possibility?
> >
> >    [[delayed]] auto x = complicated_expr(); // what's wrong with this?
> >
> > This would have the same semantics as a delayed parameter; 'x' is
> > initialized on first use. Again, doing this at the *language level*
> > allows for much better optimization. For example:
>
> You want that to have semantics? Then get rid of the attribute and replace
> it
> with something else.
>

Other issues with an attribute:
* new ABI (need some way to mark parameters as delayed)
* how do you take a pointer to a function with a delayed parameter (it
needs to appear in the function pointer type)

It seems to me that delayed parameters are going to leak out into the type
system, which means that it's best for them to be part of the type system
to start with. I suppose a new reference class could do the job, but I'd be
wary of something that powerful.

--

---
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_2291_5025531.1401129693021
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Monday, 26 May 2014 19:31:30 UTC+1, Ville Voutilainen  =
wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left:=
 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On 26 May 2014 20:27=
, Matthew Woehlke &lt;<a href=3D"javascript:" target=3D"_blank" gdf-obfusca=
ted-mailto=3D"b-LBWhQMTWgJ" onmousedown=3D"this.href=3D'javascript:';return=
 true;" onclick=3D"this.href=3D'javascript:';return true;">mw_t...@users.so=
urceforge.<wbr>net</a>&gt; wrote:
<br>&gt; Why would a language-based implementation preclude this possibilit=
y?
<br>&gt;
<br>&gt; &nbsp; &nbsp;[[delayed]] auto x =3D complicated_expr(); // what's =
wrong with this?
<br>&gt;
<br>&gt; This would have the same semantics as a delayed parameter; 'x' is
<br>&gt; initialized on first use. Again, doing this at the *language level=
*
<br>&gt; allows for much better optimization. For example:
<br>
<br>You want that to have semantics? Then get rid of the attribute and repl=
ace it
<br>with something else.
<br></blockquote><div><br></div><div>Other issues with an attribute:</div><=
div>* new ABI (need some way to mark parameters as delayed)&nbsp;</div><div=
>* how do you take a pointer to a function with a delayed parameter (it nee=
ds to appear in the function pointer type)</div><div><br></div><div>It seem=
s to me that delayed parameters are going to leak out into the type system,=
 which means that it's best for them to be part of the type system to start=
 with. I suppose a new reference class could do the job, but I'd be wary of=
 something that powerful.</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_2291_5025531.1401129693021--

.


Author: Matthew Woehlke <mw_triad@users.sourceforge.net>
Date: Mon, 26 May 2014 14:45:18 -0400
Raw View
On 2014-05-26 14:31, Ville Voutilainen wrote:
> On 26 May 2014 20:27, Matthew Woehlke <mw_triad@users.sourceforge.net> wrote:
>> Why would a language-based implementation preclude this possibility?
>>
>>    [[delayed]] auto x = complicated_expr(); // what's wrong with this?
>>
>> This would have the same semantics as a delayed parameter; 'x' is
>> initialized on first use. Again, doing this at the *language level*
>> allows for much better optimization. For example:
>
> You want that to have semantics? Then get rid of the attribute and replace it
> with something else.

Again, I'm looking at this *mostly* from the perspective of
optimization. IOW, '[[delayed]] x' and the substitution of 'expr' for x
(be it assignment or parameter passing) is a promise to the compiler
that neither the construction or destruction of 'x', nor the evaluation
of 'expr', has side effects, and that the order in which those
operations are performed (or indeed, if they are performed at all) may
be modified accordingly. In that sense, the level of semantic meaning is
similar to [[likely]].

(For that mapper, OMP attributes aren't exactly semantic free either,
especially if the code in an OMP loop has any degree of thread awareness
or execution order dependency.)

Again, the main benefit to using an attribute is that it is transparent
to code tools and even old compilers... code using it will still
*compile* on a compiler that doesn't support the feature. (It may be
wrong, but then, I could also write OMP code that is wrong - or at least
behaves differently - when build w/o OMP support.)

If that possibility is unacceptable, than some other syntax (e.g. '[=]',
or adding a keyword) can be used, but then code tools must learn about
the feature in order to still work. (Conversely, it's getting
increasingly impractical to parse C++ with anything short of a
full-blown compiler, e.g. libclang, which may substantially mitigate
that cost.)

--
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: Mon, 26 May 2014 14:48:01 -0400
Raw View
On 2014-05-26 14:41, Edward Catmur wrote:
> Other issues with an attribute:
> * new ABI (need some way to mark parameters as delayed)
> * how do you take a pointer to a function with a delayed parameter (it
> needs to appear in the function pointer type)

I fail to see what either of these have to do with using an attribute
vs. some other decoration. The ABI of a delayed vs. immediate parameter
is different. That's just a given. (In fact it's true even using a
library-only implementation, except that there is no compiler change
needed since 'int' vs. e.g. 'std::delayed<int>' are already different
types.)

--
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: Mon, 26 May 2014 14:48:10 -0400
Raw View
On 2014-05-26 14:13, Mikhail Semenov wrote:
> Are you suggesting that we can define a parameter:
>
> void f([[delayed]] T x)
> {
>     if(cond)
>           send(x); // evaluates x;
> }

Yes. Note however that the reasons to do so are more for backwards
compatibility. That said...

> I think the problem with "lazy evaluation" is that it is not obvious when
> the variable is going to be evaluated. It is not a clear syntax.
> My understanding is that it is much clearer to write:
>
> void f([&] T x) // the parameter specification is OK
> {
>     if(cond)
>           send(x()); // evaluates x; the syntax is clearer here
> }

....it's not necessarily more obvious that 'x' will be evaluated here
than the above. If send() also uses [[delayed]] on the parameter, then
there is still no evaluation occurring (yet). (Furthermore, one hopes
that the compiler is able - in some cases anyway - to avoid generating a
second thunk here and rather just pass along the thunk that was passed in.)

I also don't entirely buy the importance of knowing in the *callee*
where evaluation happens. Especially as the callee has no idea what (if,
indeed, anything at all) "evaluation" entails. In the callee, all the
user should need to know is that the caller's thunk is evaluated if the
parameter is "used".

Delayed evaluation is of *much* more interest to the *caller*, which
cannot know at what point, or even if, the expression is evaluated.
However I see this being exactly as a big (or not) of an issue as
existing short circuit evaluation.

--
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: Edward Catmur <ecatmur@googlemail.com>
Date: Mon, 26 May 2014 20:02:48 +0100
Raw View
--001a11c2e7a0a3a51904fa523965
Content-Type: text/plain; charset=UTF-8

On 26 May 2014 19:50, "Matthew Woehlke" <mw_triad@users.sourceforge.net>
wrote:
> I fail to see what either of these have to do with using an attribute
> vs. some other decoration. The ABI of a delayed vs. immediate parameter
> is different. That's just a given. (In fact it's true even using a
> library-only implementation, except that there is no compiler change
> needed since 'int' vs. e.g. 'std::delayed<int>' are already different
> types.)

If you need the attribute to form a function pointer, then how can that be
deduced by a template? I worry that semantic attributes will produce a
category of second-class functions that can't be metaprogrammed correctly.

--

---
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/.

--001a11c2e7a0a3a51904fa523965
Content-Type: text/html; charset=UTF-8

<p dir="ltr">On 26 May 2014 19:50, &quot;Matthew Woehlke&quot; &lt;<a href="mailto:mw_triad@users.sourceforge.net">mw_triad@users.sourceforge.net</a>&gt; wrote:<br>
&gt; I fail to see what either of these have to do with using an attribute<br>
&gt; vs. some other decoration. The ABI of a delayed vs. immediate parameter<br>
&gt; is different. That&#39;s just a given. (In fact it&#39;s true even using a<br>
&gt; library-only implementation, except that there is no compiler change<br>
&gt; needed since &#39;int&#39; vs. e.g. &#39;std::delayed&lt;int&gt;&#39; are already different<br>
&gt; types.)</p>
<p dir="ltr">If you need the attribute to form a function pointer, then how can that be deduced by a template? I worry that semantic attributes will produce a category of second-class functions that can&#39;t be metaprogrammed correctly. </p>

<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 />

--001a11c2e7a0a3a51904fa523965--

.


Author: Edward Catmur <ecatmur@googlemail.com>
Date: Mon, 26 May 2014 20:14:02 +0100
Raw View
--001a11c2e7a0d3079404fa5261de
Content-Type: text/plain; charset=UTF-8

On 26 May 2014 05:04, "David Krauss" <potswa@gmail.com> wrote:
>
> Another approach would be to pass a lambda (or equivalent entity like my
proposed inline variable) directly, and then let the user idiomatically
wrap this in something else according to desired semantics. The standard
may define the wrappers generically, e.g. std::one_shot_functor which can
only be called as an rvalue, std::memoized_functor which caches a return
value and returns it on subsequent calls, etc. Without wrapping, the user
gets multiple evaluation and repeated side effects.

I'm inclined to agree; SRP demands that memoization be orthogonal to other
aspects of the proposal. I'd still like a way to assure the caller that
memoization occurs so that the expression is evaluated at most once.

It does seem that separating type erasure from implicit expression would be
a good idea as well, though I'm not sure how that would work. You'd need a
way to specify that a parameter is deduced as an expression capture, which
implies a way to write that in the type system.

--

---
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/.

--001a11c2e7a0d3079404fa5261de
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<p dir=3D"ltr"><br>
On 26 May 2014 05:04, &quot;David Krauss&quot; &lt;<a href=3D"mailto:potswa=
@gmail.com">potswa@gmail.com</a>&gt; wrote:<br>
&gt;<br>
&gt; Another approach would be to pass a lambda (or equivalent entity like =
my proposed inline variable) directly, and then let the user idiomatically =
wrap this in something else according to desired semantics. The standard ma=
y define the wrappers generically, e.g. std::one_shot_functor=C2=A0which ca=
n only be called as an rvalue,=C2=A0std::memoized_functor=C2=A0which caches=
 a return value and returns it on subsequent calls, etc. Without wrapping, =
the user gets multiple evaluation and repeated side effects.</p>

<p dir=3D"ltr">I&#39;m inclined to agree; SRP demands that memoization be o=
rthogonal to other aspects of the proposal. I&#39;d still like a way to ass=
ure the caller that memoization occurs so that the expression is evaluated =
at most once.</p>

<p dir=3D"ltr">It does seem that separating type erasure from implicit expr=
ession would be a good idea as well, though I&#39;m not sure how that would=
 work. You&#39;d need a way to specify that a parameter is deduced as an ex=
pression capture, which implies a way to write that in the type system. </p=
>

<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 />

--001a11c2e7a0d3079404fa5261de--

.


Author: Mikhail Semenov <mikhailsemenov1957@gmail.com>
Date: Tue, 27 May 2014 01:36:26 -0700 (PDT)
Raw View
------=_Part_82_20817279.1401179786844
Content-Type: text/plain; charset=UTF-8


>
> I'm inclined to agree; SRP demands that memoization be orthogonal to other
> aspects of the proposal. I'd still like a way to assure the caller that
> memoization occurs so that the expression is evaluated at most once.
>
> It does seem that separating type erasure from implicit expression would
> be a good idea as well, though I'm not sure how that would work. You'd need
> a way to specify that a parameter is deduced as an expression capture,
> which implies a way to write that in the type system.
>
 The point is that "passing-by-lambda" parameter mechanism (as initially
proposed) is rather clear and allows the user to control the evaluation in
the callee, whereas lazy-evaluation involves unclear definition of when the
parameter is going to be evaluated. I don't see a problem with multiple
evaluations of the same parameter. If you don't want to evaluate it many
times, don't do it: assign it to a variable.

The passing-by-lambda mechanism is very clear: just allow the compiler to
transform an expression into a lambda-expression in the caller: all the
necessary information is available anyway.  The callee picks up this lambda
expression and uses it as a function: that's all. There are know sematic or
syntactic pitfalls. The only thing the implementation has to do is to pass
the lambda expression as a parameter efficiently.


--

---
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_82_20817279.1401179786844
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><blockquote class=3D"gmail_quote" style=3D"margin: 0px 0px=
 0px 0.8ex; padding-left: 1ex; border-left-color: rgb(204, 204, 204); borde=
r-left-width: 1px; border-left-style: solid;"><p dir=3D"ltr">I'm inclined t=
o agree; SRP demands that memoization be orthogonal to other aspects of the=
 proposal. I'd still like a way to assure the caller that memoization occur=
s so that the expression is evaluated at most once.</p>

<p dir=3D"ltr">It does seem that separating type erasure from implicit expr=
ession would be a good idea as well, though I'm not sure how that would wor=
k. You'd need a way to specify that a parameter is deduced as an expression=
 capture, which implies a way to write that in the type system. </p></block=
quote><div>&nbsp;The point is that "passing-by-lambda" parameter mechanism =
(as initially proposed) is rather clear and allows the user to control the =
evaluation in the callee, whereas lazy-evaluation involves unclear definiti=
on of when the parameter is going to be evaluated. I don't see a problem wi=
th multiple evaluations of the same parameter. If you don't want to evaluat=
e it many times, don't do it: assign it to a variable. </div><div>&nbsp;</d=
iv><div>The passing-by-lambda mechanism is very clear: just allow the compi=
ler to transform an expression into a lambda-expression in the caller: all =
the necessary information is available&nbsp;anyway.&nbsp;&nbsp;The callee p=
icks up this lambda expression and uses it as a function: that's all. There=
 are know sematic or syntactic pitfalls. The only thing the implementation =
has to do is to pass the lambda expression as a parameter efficiently.</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_82_20817279.1401179786844--

.


Author: Edward Catmur <ed@catmur.co.uk>
Date: Tue, 27 May 2014 03:55:51 -0700 (PDT)
Raw View
------=_Part_7_28683938.1401188151392
Content-Type: text/plain; charset=UTF-8

On Tuesday, 27 May 2014 09:36:27 UTC+1, Mikhail Semenov wrote:
>
> The passing-by-lambda mechanism is very clear: just allow the compiler to
> transform an expression into a lambda-expression in the caller: all the
> necessary information is available anyway.  The callee picks up this lambda
> expression and uses it as a function: that's all. There are know sematic or
> syntactic pitfalls. The only thing the implementation has to do is to pass
> the lambda expression as a parameter efficiently.
>

Closure types are unique, which would imply that a pass-by-lambda function
would have to be templated on the closure type of its pass-by-lambda
parameter.  If the closure type is erased, then we need a type to perform
the erasure efficiently, avoiding memory allocation and as transparent as
possible to optimization, which precludes the use of std::function<T()>.
This type could be hidden behind a special syntax, but exposing it allows
pass-by-lambda functions to be treated normally by existing metaprogramming
facilities.

I'm leaning towards a 3-level solution:

   1. Template syntax to specify that a deduced functor parameter performs
   implicit lambda capture
   2. Efficient, non-allocating type-erased wrapper templated on the result
   type
   3. Evaluation-semantic wrappers (for memoization etc.)

Strawman for level 1:

template<typename F>
std::enable_if_t<std::is_convertible_v<std::result_of_t<F()>, int>, int>
passed_by_lambda([&] F f) {
  return f();
}

Note that any instantiation of passed_by_lambda will necessarily have F the
type of the implicitly-generated lambda, which is unnamed.

--

---
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_7_28683938.1401188151392
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Tuesday, 27 May 2014 09:36:27 UTC+1, Mikhail Semenov  w=
rote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8e=
x;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div>The=
 passing-by-lambda mechanism is very clear: just allow the compiler to tran=
sform an expression into a lambda-expression in the caller: all the necessa=
ry information is available&nbsp;anyway.&nbsp;&nbsp;The callee picks up thi=
s lambda expression and uses it as a function: that's all. There are know s=
ematic or syntactic pitfalls. The only thing the implementation has to do i=
s to pass the lambda expression as a parameter efficiently.<br></div></div>=
</blockquote><div>&nbsp;</div><div>Closure types are unique, which would im=
ply that a pass-by-lambda function would have to be templated on the closur=
e type of its pass-by-lambda parameter. &nbsp;If the closure type is erased=
, then we need a type to perform the erasure efficiently, avoiding memory a=
llocation and as transparent as possible to optimization, which precludes t=
he use of <font face=3D"courier new, monospace">std::function&lt;T()&gt;</f=
ont>. This type could be hidden behind a special syntax, but exposing it al=
lows pass-by-lambda functions to be treated normally by existing metaprogra=
mming facilities.</div><div><br></div><div>I'm leaning towards a 3-level so=
lution:</div><div><ol><li><span style=3D"line-height: normal;">Template syn=
tax to specify that a deduced functor parameter performs implicit lambda ca=
pture</span></li><li><span style=3D"line-height: normal;">Efficient, non-al=
locating type-erased wrapper templated on the result type</span></li><li><s=
pan style=3D"line-height: normal;">Evaluation-semantic wrappers (for memoiz=
ation etc.)</span></li></ol><div>Strawman for level 1:</div></div><div><br>=
</div><div class=3D"prettyprint" style=3D"background-color: rgb(250, 250, 2=
50); border: 1px solid rgb(187, 187, 187); word-wrap: break-word;"><code cl=
ass=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"color: #00=
8;" class=3D"styled-by-prettify">template</span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">&lt;</span><span style=3D"color: #008;" clas=
s=3D"styled-by-prettify">typename</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> F</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">&gt;</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"><br>std</span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">::</span><span style=3D"color: #000;" class=3D"styled-by-prettify">e=
nable_if_t</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
&lt;</span><span style=3D"color: #000;" class=3D"styled-by-prettify">std</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">::</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify">is_convertible_v</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify">std</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">::</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify">result_of_t</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">&lt;</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify">F</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">()&gt;,</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"style=
d-by-prettify">int</span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">&gt;,</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">int</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">&gt;</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"><br>passed_by_lambd=
a</span><span style=3D"color: #660;" class=3D"styled-by-prettify">([&amp;]<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"> F f</span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">)</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"col=
or: #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">return</span><span style=3D"color: #000;" c=
lass=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"><br></span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">}</span></div></code></div><div><br></div><div>Note that any instant=
iation of <font face=3D"courier new, monospace">passed_by_lambda</font>&nbs=
p;will necessarily have <font face=3D"courier new, monospace">F</font> the =
type of the implicitly-generated lambda, which is unnamed.</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_7_28683938.1401188151392--

.


Author: =?UTF-8?Q?David_Rodr=C3=ADguez_Ibeas?= <dibeas@ieee.org>
Date: Tue, 27 May 2014 08:45:14 -0400
Raw View
--001a11c1317c397ba004fa6111c1
Content-Type: text/plain; charset=UTF-8

I think this was addressed before:


On Sun, May 25, 2014 at 2:43 PM, Mikhail Semenov <
mikhailsemenov1957@gmail.com> wrote:

>
> We can have a similar definition for other cases, g([=] T x), etc.
>
>
The problem here is that when the user creates a lambda, at the place of
creation, she can control how she wants the capture to be done. All the
information is available to the one making the decision. In this case, the
"capture" syntax is not at the place of call, but in the function
declaration. The programmer defining the function cannot possibly know if
the caller is going to capture anything at all or whether it makes sense to
capture by value/reference.

--

---
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/.

--001a11c1317c397ba004fa6111c1
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">I think this was addressed before:<div class=3D"gmail_extr=
a"><br><br><div class=3D"gmail_quote">On Sun, May 25, 2014 at 2:43 PM, Mikh=
ail Semenov <span dir=3D"ltr">&lt;<a href=3D"mailto:mikhailsemenov1957@gmai=
l.com" target=3D"_blank">mikhailsemenov1957@gmail.com</a>&gt;</span> wrote:=
<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div><br></div><div>We can =
have a similar definition for other cases, g([=3D] T x), etc.<br></div><div=
><br>
</div></div></blockquote><div><br>The problem here is that when the user cr=
eates a lambda, at the place of creation, she can control how she wants the=
 capture to be done. All the information is available to the one making the=
 decision. In this case, the &quot;capture&quot; syntax is not at the place=
 of call, but in the function declaration. The programmer defining the func=
tion cannot possibly know if the caller is going to capture anything at all=
 or whether it makes sense to capture by value/reference.</div>
</div></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 />

--001a11c1317c397ba004fa6111c1--

.


Author: Mikhail Semenov <mikhailsemenov1957@gmail.com>
Date: Tue, 27 May 2014 05:54:23 -0700 (PDT)
Raw View
------=_Part_37_10533744.1401195263853
Content-Type: text/plain; charset=UTF-8



We can have a similar definition for other cases, g([=] T x), etc.
>>
>>
> The problem here is that when the user creates a lambda, at the place of
> creation, she can control how she wants the capture to be done. All the
> information is available to the one making the decision. In this case, the
> "capture" syntax is not at the place of call, but in the function
> declaration. The programmer defining the function cannot possibly know if
> the caller is going to capture anything at all or whether it makes sense to
> capture by value/reference.
>

The user who writes the function knows what the function is doing:
(1) in most cases it would probably be [&];
(2) [=] special cases when the parameter in the called function is passed
to other functions without being evaluated.


--

---
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_37_10533744.1401195263853
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br><blockquote class=3D"gmail_quote" style=3D"margin:=
 0px 0px 0px 0.8ex; padding-left: 1ex; border-left-color: rgb(204, 204, 204=
); border-left-width: 1px; border-left-style: solid;"><div dir=3D"ltr"><div=
><div class=3D"gmail_quote"><blockquote class=3D"gmail_quote" style=3D"marg=
in: 0px 0px 0px 0.8ex; padding-left: 1ex; border-left-color: rgb(204, 204, =
204); border-left-width: 1px; border-left-style: solid;"><div dir=3D"ltr"><=
div>We can have a similar definition for other cases, g([=3D] T x), etc.<br=
></div><div><br>
</div></div></blockquote><div><br>The problem here is that when the user cr=
eates a lambda, at the place of creation, she can control how she wants the=
 capture to be done. All the information is available to the one making the=
 decision. In this case, the "capture" syntax is not at the place of call, =
but in the function declaration. The programmer defining the function canno=
t possibly know if the caller is going to capture anything at all or whethe=
r it makes sense to capture by value/reference.</div></div></div></div></bl=
ockquote><div>&nbsp;</div><div>The user who writes the function knows what =
the function is doing: </div><div>(1) in most cases it would probably be [&=
amp;];</div><div>(2)&nbsp;[=3D] special cases when the parameter in the cal=
led function is passed to other functions without being evaluated.</div><di=
v>&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_37_10533744.1401195263853--

.


Author: Mikhail Semenov <mikhailsemenov1957@gmail.com>
Date: Tue, 27 May 2014 07:05:15 -0700 (PDT)
Raw View
------=_Part_354_27764022.1401199515441
Content-Type: text/plain; charset=UTF-8

On second thought: there might be the following approach:

f(lazy int x) // lazy, eval, expr  or whatever
{
     if (cond)
         send(x); // basically evaluated when first used or every time it
is used.
}

It is very similar (or probably the same) as has been mentioned  during
this discussion: the parameter is evaluated on first call (it does not
really matter whether it is evaluated
once or many times - it may actually depend in implementation).

In terms of how many times it is evaluated we may discuss/vote do.

In some way this mechanism is equivalent to

f([&] int x) // lazy, eval or whatever
{
     if (cond)
         send(x());
}

In principle, I don't see much difference: either approach will.





--

---
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_354_27764022.1401199515441
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div>On second thought: there might be the following appro=
ach:</div><div>&nbsp;</div><div>f(lazy int x) // lazy, eval, expr &nbsp;or =
whatever</div><div>{</div><div>&nbsp;&nbsp;&nbsp;&nbsp; if (cond)</div><div=
>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; send(x); // basically eva=
luated when first used or every time it is used.</div><div>}<br>&nbsp;</div=
><div>It is very similar (or probably the same) as&nbsp;has been&nbsp;menti=
oned&nbsp;&nbsp;during this discussion: the parameter is evaluated on first=
 call (it does not really matter whether it is evaluated</div><div>once or =
many times - it may actually depend in implementation). <div>&nbsp;</div><d=
iv>In terms of how many times it is evaluated we may discuss/vote do.</div>=
</div><div>&nbsp;</div><div>In some way this mechanism is equivalent to</di=
v><div><div>&nbsp;</div><div>f([&amp;] int x) // lazy, eval or whatever</di=
v><div>{</div><div>&nbsp;&nbsp;&nbsp;&nbsp; if (cond)</div><div>&nbsp;&nbsp=
;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; send(x()); </div><div>}</div><div>&nb=
sp;</div><div>In principle, I don't see much difference: either approach wi=
ll.</div><div><br>&nbsp;</div></div><div>&nbsp;</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_354_27764022.1401199515441--

.


Author: Matthew Woehlke <mw_triad@users.sourceforge.net>
Date: Tue, 27 May 2014 11:07:59 -0400
Raw View
On 2014-05-27 08:45, David Rodr=C3=ADguez Ibeas wrote:
> The problem here is that when the user creates a lambda, at the place of
> creation, she can control how she wants the capture to be done. All the
> information is available to the one making the decision. In this case, th=
e
> "capture" syntax is not at the place of call, but in the function
> declaration. The programmer defining the function cannot possibly know if
> the caller is going to capture anything at all or whether it makes sense =
to
> capture by value/reference.

The thunk cannot be propagated beyond the call (i.e. cannot be copied or
assigned, though it can be passed to a deeper call), thus, there is no
reason to capture by value. (More accurately, the thunk shall be
permitted to access the stack context of the caller.)

--=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: Tue, 27 May 2014 11:13:20 -0400
Raw View
On 2014-05-26 15:02, Edward Catmur wrote:
> On 26 May 2014 19:50, "Matthew Woehlke" <mw_triad@users.sourceforge.net>
> wrote:
>> I fail to see what either of these have to do with using an attribute
>> vs. some other decoration. The ABI of a delayed vs. immediate parameter
>> is different. That's just a given. (In fact it's true even using a
>> library-only implementation, except that there is no compiler change
>> needed since 'int' vs. e.g. 'std::delayed<int>' are already different
>> types.)
>
> If you need the attribute to form a function pointer, then how can that be
> deduced by a template? I worry that semantic attributes will produce a
> category of second-class functions that can't be metaprogrammed correctly.

It's effectively a type modifier that applies to the whole type, similar
to e.g. volatile (except volatile, like const, would apply to part of
the type, e.g. 'int* volatile*' vs. 'int volatile**'). That being the
case, I don't understand what is a problem?

Can you give an example of something you're seeing as being a problem?

--
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: Edward Catmur <ed@catmur.co.uk>
Date: Tue, 27 May 2014 08:33:10 -0700 (PDT)
Raw View
------=_Part_2990_28760815.1401204790488
Content-Type: text/plain; charset=UTF-8

On Tuesday, 27 May 2014 16:13:42 UTC+1, Matthew Woehlke wrote:
>
> On 2014-05-26 15:02, Edward Catmur wrote:
> > If you need the attribute to form a function pointer, then how can that
> be
> > deduced by a template? I worry that semantic attributes will produce a
> > category of second-class functions that can't be metaprogrammed
> correctly.
>
> It's effectively a type modifier that applies to the whole type, similar
> to e.g. volatile (except volatile, like const, would apply to part of
> the type, e.g. 'int* volatile*' vs. 'int volatile**'). That being the
> case, I don't understand what is a problem?
>
> Can you give an example of something you're seeing as being a problem?
>

void foo([[delayed]] int x);
using T = typename std::function<decltype(foo)>::argument_type;
// what is T?

Presumably T is [[delayed]] int; if so, where else is this type permitted
to appear?

--

---
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_2990_28760815.1401204790488
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Tuesday, 27 May 2014 16:13:42 UTC+1, Matthew Woehlke  w=
rote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8e=
x;border-left: 1px #ccc solid;padding-left: 1ex;">On 2014-05-26 15:02, Edwa=
rd Catmur wrote:
<br>&gt; If you need the attribute to form a function pointer, then how can=
 that be
<br>&gt; deduced by a template? I worry that semantic attributes will produ=
ce a
<br>&gt; category of second-class functions that can't be metaprogrammed co=
rrectly.
<br>
<br>It's effectively a type modifier that applies to the whole type, simila=
r
<br>to e.g. volatile (except volatile, like const, would apply to part of
<br>the type, e.g. 'int* volatile*' vs. 'int volatile**'). That being the
<br>case, I don't understand what is a problem?
<br>
<br>Can you give an example of something you're seeing as being a problem?
<br></blockquote><div><br></div><div class=3D"prettyprint" style=3D"backgro=
und-color: rgb(250, 250, 250); border: 1px solid rgb(187, 187, 187); word-w=
rap: break-word;"><code class=3D"prettyprint"><div class=3D"subprettyprint"=
><span style=3D"color: #008;" class=3D"styled-by-prettify">void</span><span=
 style=3D"color: #000;" class=3D"styled-by-prettify"> foo</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">([[</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify">delayed</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">int</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"> x</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">);</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br=
></span><span style=3D"color: #008;" class=3D"styled-by-prettify">using</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"> T </span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">=3D</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;" class=3D"styled-by-prettify"> std</span><span style=3D"color: #660;"=
 class=3D"styled-by-prettify">::</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"st=
yled-by-prettify">decltype</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify">foo</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
)&gt;::</span><span style=3D"color: #000;" class=3D"styled-by-prettify">arg=
ument_type</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></spa=
n><span style=3D"color: #800;" class=3D"styled-by-prettify">// what is T?</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><=
/div></code></div><div><br>Presumably <font face=3D"courier new, monospace"=
>T</font> is <font face=3D"courier new, monospace">[[delayed]] int</font>; =
if so, where else is this type permitted to appear?</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_2990_28760815.1401204790488--

.


Author: Mikhail Semenov <mikhailsemenov1957@gmail.com>
Date: Tue, 27 May 2014 08:56:25 -0700 (PDT)
Raw View
------=_Part_3787_4715467.1401206185458
Content-Type: text/plain; charset=UTF-8



void foo([[delayed]] int x);
> using T = typename std::function<decltype(foo)>::argument_type;
> // what is T?
>

> Presumably T is [[delayed]] int; if so, where else is this type permitted
> to appear?
>

If you look from the point of view of code transformation, every appearance
of x can be treated as calling a function of type std::function<int()>: x
looks like a variable but in fact it is a function call.





--

---
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_3787_4715467.1401206185458
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br><code><blockquote class=3D"gmail_quote" style=3D"m=
argin: 0px 0px 0px 0.8ex; padding-left: 1ex; border-left-color: rgb(204, 20=
4, 204); border-left-width: 1px; border-left-style: solid;"><div dir=3D"ltr=
"><div style=3D"border: 1px solid rgb(187, 187, 187); word-wrap: break-word=
; background-color: rgb(250, 250, 250);"><div><span style=3D"color: rgb(0, =
0, 136);">void</span><span style=3D"color: rgb(0, 0, 0);"> foo</span><span =
style=3D"color: rgb(102, 102, 0);">([[</span><span style=3D"color: rgb(0, 0=
, 0);">delayed</span><span style=3D"color: rgb(102, 102, 0);">]]</span><spa=
n style=3D"color: rgb(0, 0, 0);"> </span><span style=3D"color: rgb(0, 0, 13=
6);">int</span><span style=3D"color: rgb(0, 0, 0);"> x</span><span style=3D=
"color: rgb(102, 102, 0);">);</span><span style=3D"color: rgb(0, 0, 0);"><b=
r></span><span style=3D"color: rgb(0, 0, 136);">using</span><span style=3D"=
color: rgb(0, 0, 0);"> T </span><span style=3D"color: rgb(102, 102, 0);">=
=3D</span><span style=3D"color: rgb(0, 0, 0);"> </span><span style=3D"color=
: rgb(0, 0, 136);">typename</span><span style=3D"color: rgb(0, 0, 0);"> std=
</span><span style=3D"color: rgb(102, 102, 0);">::</span><span style=3D"col=
or: rgb(0, 0, 136);">function</span><span style=3D"color: rgb(102, 102, 0);=
">&lt;</span><span style=3D"color: rgb(0, 0, 136);">decltype</span><span st=
yle=3D"color: rgb(102, 102, 0);">(</span><span style=3D"color: rgb(0, 0, 0)=
;">foo</span><span style=3D"color: rgb(102, 102, 0);">)&gt;::</span><span s=
tyle=3D"color: rgb(0, 0, 0);"><wbr>argument_type</span><span style=3D"color=
: rgb(102, 102, 0);">;</span><span style=3D"color: rgb(0, 0, 0);"><br></spa=
n><span style=3D"color: rgb(136, 0, 0);">// what is T?</span><span style=3D=
"color: rgb(0, 0, 0);"><br></span></div></div></div></blockquote></code><bl=
ockquote class=3D"gmail_quote" style=3D"margin: 0px 0px 0px 0.8ex; padding-=
left: 1ex; border-left-color: rgb(204, 204, 204); border-left-width: 1px; b=
order-left-style: solid;"><div dir=3D"ltr"><div style=3D"border: 1px solid =
rgb(187, 187, 187); word-wrap: break-word; background-color: rgb(250, 250, =
250);"></div><div><br>Presumably <font face=3D"courier new, monospace">T</f=
ont> is <font face=3D"courier new, monospace">[[delayed]] int</font>; if so=
, where else is this type permitted to appear?</div></div></blockquote><div=
>&nbsp;</div><div>If you look from the point of view of code transformation=
, every appearance of x can be treated as calling a function of type std<sp=
an style=3D"color: rgb(102, 102, 0);">::</span><span style=3D"color: rgb(0,=
 0, 136);">function</span><span style=3D"color: rgb(102, 102, 0);">&lt;int<=
/span><span style=3D"color: rgb(102, 102, 0);">(</span><span style=3D"color=
: rgb(102, 102, 0);">)&gt;: x looks like a variable but in fact it is a fun=
ction call.&nbsp;</span></div><div><span style=3D"color: rgb(102, 102, 0);"=
></span>&nbsp;</div><div><span style=3D"color: rgb(102, 102, 0);"></span>&n=
bsp;</div><div><span style=3D"color: rgb(102, 102, 0);"></span>&nbsp;</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_3787_4715467.1401206185458--

.


Author: Matthew Woehlke <mw_triad@users.sourceforge.net>
Date: Tue, 27 May 2014 12:12:38 -0400
Raw View
On 2014-05-27 11:33, Edward Catmur wrote:
> On Tuesday, 27 May 2014 16:13:42 UTC+1, Matthew Woehlke wrote:
>> On 2014-05-26 15:02, Edward Catmur wrote:
>>> If you need the attribute to form a function pointer, then how
>>> can that be deduced by a template? I worry that semantic
>>> attributes will produce a category of second-class functions
>>> that can't be metaprogrammed correctly.
>>
>> Can you give an example of something you're seeing as being a problem?
>
> void foo([[delayed]] int x);
> using T = typename std::function<decltype(foo)>::argument_type;
> // what is T?
>
> Presumably T is [[delayed]] int;

('void([[delayed]] int)'?)

> if so, where else is this type permitted to appear?

Probably the same places as 'volatile', e.g. I would expect that
'template <typename T> void foo([[delayed]] T)' is legal, just like
'const T' would be legal in the same context. I would also expect it to
be stripped in the manner of 'const', e.g.:

  void foo([[delayed]] int bar)
  {
    [[delayed]] auto _bar = bar; // _bar has type '[[delayed]] int'
    auto __bar = _bar; // __bar has type 'int'
    ...
  }

  template <typename T> chase(T prey);
  // 'chase([[delayed]] T prey)' would be legal

  void cat_and_mouse(Cat cat, [[delayed]] Mouse mouse)
  {
    chase(mouse); // calls chase<Mouse>, not chase<[[delayed]] Mouse>
    // also legal: chase<[[delayed]] Mouse>(mouse);
  }

--
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: walter1234 <walter2bz@gmail.com>
Date: Thu, 3 Jul 2014 01:51:45 -0700 (PDT)
Raw View
------=_Part_38_1080740.1404377505226
Content-Type: text/plain; charset=UTF-8

Rust's situation is interesting here: They don't have pass by lambda, but
what they do have is very compact syntax for lambda expressions.
`|args..|{ lambda block..}   |args|expression    ||expression`

their reasoning is you see costs explicitly at the call site.

e.g.  `do_something(regular_args,||something_to_lazy_eval)`

Could we get any closer to that in C++?   a shortcut for single expressions
e.g. [](..)expr  is sugar for [](..){ return expr}`  and in turn `[]expr`
 or `()expr` perhaps

--

---
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_38_1080740.1404377505226
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Rust's situation is interesting here: They don't have pass=
 by lambda, but what they do have is very compact syntax for lambda express=
ions. &nbsp; `|args..|{ lambda block..} &nbsp; |args|expression &nbsp; &nbs=
p;||expression`<div><br><div>their reasoning is you see costs explicitly at=
 the call site.</div><div><br><div>e.g. &nbsp;`do_something(regular_args,||=
something_to_lazy_eval)`</div><div><br></div><div>Could we get any closer t=
o that in C++? &nbsp; a shortcut for single expressions e.g. [](..)expr &nb=
sp;is sugar for [](..){ return expr}` &nbsp;and in turn `[]expr` &nbsp;or `=
()expr` perhaps</div></div></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_38_1080740.1404377505226--

.


Author: David Krauss <potswa@gmail.com>
Date: Thu, 3 Jul 2014 16:53:49 +0800
Raw View
On 2014-07-03, at 4:51 PM, walter1234 <walter2bz@gmail.com> wrote:

> Rust's situation is interesting here: They don't have pass by lambda, but what they do have is very compact syntax for lambda expressions.   `|args..|{ lambda block..}   |args|expression    ||expression`
>
> their reasoning is you see costs explicitly at the call site.
>
> e.g.  `do_something(regular_args,||something_to_lazy_eval)`
>
> Could we get any closer to that in C++?   a shortcut for single expressions e.g. [](..)expr  is sugar for [](..){ return expr}`  and in turn `[]expr`  or `()expr` perhaps

You're proposing to eliminate only the curly braces? Is it worth it?

Note that the parens are already optional.

--

---
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: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Thu, 3 Jul 2014 12:06:06 +0300
Raw View
On 3 July 2014 11:53, David Krauss <potswa@gmail.com> wrote:
>
> On 2014-07-03, at 4:51 PM, walter1234 <walter2bz@gmail.com> wrote:
>
>> Rust's situation is interesting here: They don't have pass by lambda, but what they do have is very compact syntax for lambda expressions.   `|args..|{ lambda block..}   |args|expression    ||expression`
>>
>> their reasoning is you see costs explicitly at the call site.
>>
>> e.g.  `do_something(regular_args,||something_to_lazy_eval)`
>>
>> Could we get any closer to that in C++?   a shortcut for single expressions e.g. [](..)expr  is sugar for [](..){ return expr}`  and in turn `[]expr`  or `()expr` perhaps
>
> You're proposing to eliminate only the curly braces? Is it worth it?
>
> Note that the parens are already optional.


How does one invoke the lambda immediately when the braces are omitted? With
the current syntax, I can do
for_each(vec.begin(), vec.end(), []{/*code here*/}()/* it's not the
lambda I'll use as the functor but its result*/);

Also, this more-terse syntax was already proposed in
http://open-std.org/JTC1/SC22/WG21/docs/papers/2012/n3418.pdf
but was rejected, mostly due to readability concerns.

--

---
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: David Krauss <potswa@gmail.com>
Date: Thu, 3 Jul 2014 17:11:44 +0800
Raw View
On 2014-07-03, at 5:06 PM, Ville Voutilainen <ville.voutilainen@gmail.com> =
wrote:

> How does one invoke the lambda immediately when the braces are omitted? W=
ith
> the current syntax, I can do
> for_each(vec.begin(), vec.end(), []{/*code here*/}()/* it's not the
> lambda I'll use as the functor but its result*/);

Well, you would simply parenthesize the lambda :P

> Also, this more-terse syntax was already proposed in
> http://open-std.org/JTC1/SC22/WG21/docs/papers/2012/n3418.pdf
> but was rejected, mostly due to readability concerns.


As probably mentioned earlier in this thread, I plan on proposing decoratio=
n-free, lambda-like behavior with inline variables, but I've been procrasti=
nating and now missed post-Rapperswil, in part because I anticipate such ba=
cklash. The proposal will need to be written with extreme care and politica=
l spin.

--=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: inkwizytoryankes@gmail.com
Date: Thu, 3 Jul 2014 09:28:00 -0700 (PDT)
Raw View
------=_Part_696_30145469.1404404880567
Content-Type: text/plain; charset=UTF-8

What is point of calling one expression labda inplace? You should remove
`[]` than trying add `()`.

Syntax `[](...)exp` is error prone, args and exp should be separated, `:`
could do that:
int x;
auto f = [=]:(long)x; //long()
auto g = [=](long):x; //int(long)
auto h = [=]mutable:++x; //int()



On Thursday, July 3, 2014 11:06:08 AM UTC+2, Ville Voutilainen wrote:
>
> On 3 July 2014 11:53, David Krauss <pot...@gmail.com <javascript:>>
> wrote:
> >
> > On 2014-07-03, at 4:51 PM, walter1234 <walt...@gmail.com <javascript:>>
> wrote:
> >
> >> Rust's situation is interesting here: They don't have pass by lambda,
> but what they do have is very compact syntax for lambda expressions.
> `|args..|{ lambda block..}   |args|expression    ||expression`
> >>
> >> their reasoning is you see costs explicitly at the call site.
> >>
> >> e.g.  `do_something(regular_args,||something_to_lazy_eval)`
> >>
> >> Could we get any closer to that in C++?   a shortcut for single
> expressions e.g. [](..)expr  is sugar for [](..){ return expr}`  and in
> turn `[]expr`  or `()expr` perhaps
> >
> > You're proposing to eliminate only the curly braces? Is it worth it?
> >
> > Note that the parens are already optional.
>
>
> How does one invoke the lambda immediately when the braces are omitted?
> With
> the current syntax, I can do
> for_each(vec.begin(), vec.end(), []{/*code here*/}()/* it's not the
> lambda I'll use as the functor but its result*/);
>
> Also, this more-terse syntax was already proposed in
> http://open-std.org/JTC1/SC22/WG21/docs/papers/2012/n3418.pdf
> but was rejected, mostly due to readability concerns.
>

--

---
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_696_30145469.1404404880567
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">What is point of calling one expression labda inplace? You=
 should remove `[]` than trying add `()`.<br><br>Syntax `[](...)exp` is err=
or prone, args and exp should be separated, `:` could do that:<br><div clas=
s=3D"prettyprint" style=3D"background-color: rgb(250, 250, 250); border-col=
or: rgb(187, 187, 187); border-style: solid; border-width: 1px; word-wrap: =
break-word;"><code class=3D"prettyprint"><div class=3D"subprettyprint"><spa=
n style=3D"color: #008;" class=3D"styled-by-prettify">int</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> x</span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">;</span><span style=3D"color: #000;"=
 class=3D"styled-by-prettify"><br></span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">auto</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> f </span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">[=3D]=
:(</span><span style=3D"color: #008;" class=3D"styled-by-prettify">long</sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">)</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify">x</span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">;</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"> </span><span style=3D"color: #800;" clas=
s=3D"styled-by-prettify">//long()</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br></span><span style=3D"color: #008;" class=3D"st=
yled-by-prettify">auto</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"> g </span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> <=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">[=3D](</spa=
n><span style=3D"color: #008;" class=3D"styled-by-prettify">long</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">):</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">x</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: #800;" class=3D"=
styled-by-prettify">//int(long)</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"><br></span><span style=3D"color: #008;" class=3D"style=
d-by-prettify">auto</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"> h </span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">[=3D]</span><s=
pan style=3D"color: #008;" class=3D"styled-by-prettify">mutable</span><span=
 style=3D"color: #660;" class=3D"styled-by-prettify">:++</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">x</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: #800;" class=3D"=
styled-by-prettify">//int()</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"><br></span></div></code></div><br><br><br>On Thursday, Jul=
y 3, 2014 11:06:08 AM UTC+2, Ville Voutilainen wrote:<blockquote class=3D"g=
mail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc sol=
id;padding-left: 1ex;">On 3 July 2014 11:53, David Krauss &lt;<a href=3D"ja=
vascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"XrrAKTs9_jsJ" onmouse=
down=3D"this.href=3D'javascript:';return true;" onclick=3D"this.href=3D'jav=
ascript:';return true;">pot...@gmail.com</a>&gt; wrote:
<br>&gt;
<br>&gt; On 2014-07-03, at 4:51 PM, walter1234 &lt;<a href=3D"javascript:" =
target=3D"_blank" gdf-obfuscated-mailto=3D"XrrAKTs9_jsJ" onmousedown=3D"thi=
s.href=3D'javascript:';return true;" onclick=3D"this.href=3D'javascript:';r=
eturn true;">walt...@gmail.com</a>&gt; wrote:
<br>&gt;
<br>&gt;&gt; Rust's situation is interesting here: They don't have pass by =
lambda, but what they do have is very compact syntax for lambda expressions=
.. &nbsp; `|args..|{ lambda block..} &nbsp; |args|expression &nbsp; &nbsp;||=
expression`
<br>&gt;&gt;
<br>&gt;&gt; their reasoning is you see costs explicitly at the call site.
<br>&gt;&gt;
<br>&gt;&gt; e.g. &nbsp;`do_something(regular_args,||<wbr>something_to_lazy=
_eval)`
<br>&gt;&gt;
<br>&gt;&gt; Could we get any closer to that in C++? &nbsp; a shortcut for =
single expressions e.g. [](..)expr &nbsp;is sugar for [](..){ return expr}`=
 &nbsp;and in turn `[]expr` &nbsp;or `()expr` perhaps
<br>&gt;
<br>&gt; You're proposing to eliminate only the curly braces? Is it worth i=
t?
<br>&gt;
<br>&gt; Note that the parens are already optional.
<br>
<br>
<br>How does one invoke the lambda immediately when the braces are omitted?=
 With
<br>the current syntax, I can do
<br>for_each(vec.begin(), vec.end(), []{/*code here*/}()/* it's not the
<br>lambda I'll use as the functor but its result*/);
<br>
<br>Also, this more-terse syntax was already proposed in
<br><a href=3D"http://open-std.org/JTC1/SC22/WG21/docs/papers/2012/n3418.pd=
f" target=3D"_blank" onmousedown=3D"this.href=3D'http://www.google.com/url?=
q\75http%3A%2F%2Fopen-std.org%2FJTC1%2FSC22%2FWG21%2Fdocs%2Fpapers%2F2012%2=
Fn3418.pdf\46sa\75D\46sntz\0751\46usg\75AFQjCNHprTaUXBviWPalr8BbNtntd2E20g'=
;return true;" onclick=3D"this.href=3D'http://www.google.com/url?q\75http%3=
A%2F%2Fopen-std.org%2FJTC1%2FSC22%2FWG21%2Fdocs%2Fpapers%2F2012%2Fn3418.pdf=
\46sa\75D\46sntz\0751\46usg\75AFQjCNHprTaUXBviWPalr8BbNtntd2E20g';return tr=
ue;">http://open-std.org/JTC1/SC22/<wbr>WG21/docs/papers/2012/n3418.<wbr>pd=
f</a>
<br>but was rejected, mostly due to readability concerns.
<br></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_696_30145469.1404404880567--

.


Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Thu, 3 Jul 2014 19:39:33 +0300
Raw View
On 3 July 2014 19:28,  <inkwizytoryankes@gmail.com> wrote:
> What is point of calling one expression labda inplace? You should remove
> `[]` than trying add `()`.

Did I say "one expression"?

>
> Syntax `[](...)exp` is error prone, args and exp should be separated, `:`
> could do that:
> int x;
> auto f = [=]:(long)x; //long()
> auto g = [=](long):x; //int(long)
> auto h = [=]mutable:++x; //int()

Yes, the current syntax separates the different parts nicely. Any tweaks should
probably try and maintain that separation.

How common are returning lambdas? People seem to claim they are so common
that they should have their own syntax. What is that based on?

--

---
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: inkwizytoryankes@gmail.com
Date: Thu, 3 Jul 2014 10:06:18 -0700 (PDT)
Raw View
------=_Part_486_22958126.1404407178961
Content-Type: text/plain; charset=UTF-8



On Thursday, July 3, 2014 6:39:35 PM UTC+2, Ville Voutilainen wrote:
>
> On 3 July 2014 19:28,  <inkwizyt...@gmail.com <javascript:>> wrote:
> > What is point of calling one expression labda inplace? You should remove
> > `[]` than trying add `()`.
>
> Did I say "one expression"?
>
> Then we have current lambda that can be easy call inplace.

>
> > Syntax `[](...)exp` is error prone, args and exp should be separated,
> `:`
> > could do that:
> > int x;
> > auto f = [=]:(long)x; //long()
> > auto g = [=](long):x; //int(long)
> > auto h = [=]mutable:++x; //int()
>
> Yes, the current syntax separates the different parts nicely. Any tweaks
> should
> probably try and maintain that separation.
>
> How common are returning lambdas? People seem to claim they are so common
> that they should have their own syntax. What is that based on?
>
 In C# I nearly ever use `delegat(arg){block}` styntax and stick only to
`arg => expr`. Its sometimes required by LINQ expressions but even if it
not require I still stick to it.
Another thing is this syntax is shorter by 10 characters, in extreme case
its reduction of 70% key presses :)

--

---
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_486_22958126.1404407178961
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Thursday, July 3, 2014 6:39:35 PM UTC+2, Ville =
Voutilainen wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;marg=
in-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On 3 July 20=
14 19:28, &nbsp;&lt;<a href=3D"javascript:" target=3D"_blank" gdf-obfuscate=
d-mailto=3D"O3rx3DyH8B4J" onmousedown=3D"this.href=3D'javascript:';return t=
rue;" onclick=3D"this.href=3D'javascript:';return true;">inkwizyt...@gmail.=
com</a>&gt; wrote:
<br>&gt; What is point of calling one expression labda inplace? You should =
remove
<br>&gt; `[]` than trying add `()`.
<br>
<br>Did I say "one expression"?
<br>
<br></blockquote><div>Then we have current lambda that can be easy call inp=
lace.<br><br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;mar=
gin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">&gt;
<br>&gt; Syntax `[](...)exp` is error prone, args and exp should be separat=
ed, `:`
<br>&gt; could do that:
<br>&gt; int x;
<br>&gt; auto f =3D [=3D]:(long)x; //long()
<br>&gt; auto g =3D [=3D](long):x; //int(long)
<br>&gt; auto h =3D [=3D]mutable:++x; //int()
<br>
<br>Yes, the current syntax separates the different parts nicely. Any tweak=
s should
<br>probably try and maintain that separation.
<br>
<br>How common are returning lambdas? People seem to claim they are so comm=
on
<br>that they should have their own syntax. What is that based on?
<br></blockquote><div>&nbsp;In C# I nearly ever use `delegat(arg){block}` s=
tyntax and stick only to `arg =3D&gt; expr`. Its sometimes required by LINQ=
 expressions but even if it not require I still stick to it.<br>Another thi=
ng is this syntax is shorter by 10 characters, in extreme case its reductio=
n of 70% key presses :)<br></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_486_22958126.1404407178961--

.


Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Thu, 3 Jul 2014 20:14:11 +0300
Raw View
On 3 July 2014 20:06,  <inkwizytoryankes@gmail.com> wrote:
>> > What is point of calling one expression labda inplace? You should remove
>> > `[]` than trying add `()`.
>> Did I say "one expression"?
> Then we have current lambda that can be easy call inplace.

Well, yes, we also have the current lambda which is short enough to write that I
don't need it to be shorter. I also don't have to teach users multiple
lambda syntaxes.

>> How common are returning lambdas? People seem to claim they are so common
>> that they should have their own syntax. What is that based on?
>  In C# I nearly ever use `delegat(arg){block}` styntax and stick only to
> `arg => expr`. Its sometimes required by LINQ expressions but even if it not
> require I still stick to it.
> Another thing is this syntax is shorter by 10 characters, in extreme case
> its reduction of 70% key presses :)


If people want to reverse a decision EWG already made, they should
provide compelling
arguments. I'm not going to speculate what such compelling arguments
are, but I'd
guess it takes more than "C# lambdas are shorter" or "rust lambdas are shorter".

--

---
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/.

.