Topic: An implementation of Generic lambdas (Request for feedback)


Author: Faisal Vali <faisalv@gmail.com>
Date: Mon, 17 Dec 2012 13:05:37 -0600
Raw View
Motivated by the positive feedback we received regarding Generic
Lambdas (during the October 2012 ISO C++ Standards Meeting in
Portland), I have implemented a reasonably complete (unless I am
missing something obvious) implementation
(http://faisalv.github.com/clang-glambda/) of most of the proposal
(named lambda syntax for functions has not been attempted) using a
fork of clang.

We would like to encourage developers who are interested in this
feature, to either compile the code or download the binaries (sorry,
only windows for now) and play with the implementation and provide us
with feedback so that we can incorporate it within our next revision
of the document.

The following link: http://faisalv.github.com/clang-glambda/, has some
instructions (towards the bottom) on how to compile the code or use
the binaries for windows.

Any and all constructive feedback will be greatly appreciated.

The current version (12/2012) implements subproposals 2.1, 2.2, 2.3 and 2.5.

2.1 Allow the type-specifier within a parameter declaration of a
lambda to be auto (i.e. auto is mandatory)

auto Sum = [](auto a, decltype(a) b) { return a + b; };
int i = Sum(3, 4);
double d = Sum(3.14, 2.77);

2.2 Allow the use of familiar template syntax in lambda expressions

auto NumElements = []<int N>(auto (&a)[N]) { return N; };
int arri[]{1, 2, 3};
double arrd[]{3.14, 2.77, 6.626};
auto total = NumElements(arri) + NumElements(arrd);

2.3 Permit a lambda body to be an expression

int local = 10;
auto L = [&](auto a) a + ++local;

2.5 Autogenerate a conversion to function pointer in captureless generic lambdas

auto L = [](auto a, decltype(a) b) { return a + b; };
int (*fp)(int, int) = L;


Thank you and looking forward to the feedback!

--




.


Author: dain.bray@gmail.com
Date: Mon, 17 Dec 2012 14:38:25 -0800 (PST)
Raw View
------=_Part_225_19016827.1355783905573
Content-Type: text/plain; charset=ISO-8859-1

Cool :)

 Why is "auto" required though? It seems like it would work fine without
the keyword..?


--




------=_Part_225_19016827.1355783905573
Content-Type: text/html; charset=ISO-8859-1

Cool :)<div><br></div><div>&nbsp;Why is "auto" required though? It seems like it would work fine without the keyword..?</div><div><br></div><div><br></div>

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_225_19016827.1355783905573--

.


Author: ibaxter@gmail.com
Date: Wed, 19 Dec 2012 13:45:36 -0800 (PST)
Raw View
------=_Part_783_27888708.1355953536066
Content-Type: text/plain; charset=ISO-8859-1



> [] (a) {}
>
> Is `a` an automatically-typed variable or an unnamed argument with the
> type `a`?
>

Isn't this another case of - if it can be a typename it is a typename?

--




------=_Part_783_27888708.1355953536066
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<br><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex=
;border-left: 1px #ccc solid;padding-left: 1ex;">[] (a) {}<br><br>Is `a` an=
 automatically-typed variable or an unnamed argument with the type `a`?<br>=
</blockquote><div><br></div><div>Isn't this another case of - if it can be =
a typename it is a typename?&nbsp;</div>

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_783_27888708.1355953536066--

.


Author: stackmachine@hotmail.com
Date: Thu, 20 Dec 2012 14:59:00 -0800 (PST)
Raw View
------=_Part_32_11344311.1356044340610
Content-Type: text/plain; charset=ISO-8859-1

I like where this is going. Kinda like boost.lambda, just built into the
language.

--




------=_Part_32_11344311.1356044340610
Content-Type: text/html; charset=ISO-8859-1

I like where this is going. Kinda like boost.lambda, just built into the language.<br>

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_32_11344311.1356044340610--

.


Author: stackmachine@hotmail.com
Date: Fri, 21 Dec 2012 04:39:38 -0800 (PST)
Raw View
------=_Part_110_9535405.1356093578413
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

What about =A7?

--=20




------=_Part_110_9535405.1356093578413
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

What about =A7?<br>

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_110_9535405.1356093578413--

.


Author: Alex Sinyakov <innochenti@gmail.com>
Date: Fri, 11 Jan 2013 22:12:10 +0200
Raw View
--e89a8f3b9f7d10608b04d308e95c
Content-Type: text/plain; charset=ISO-8859-1

good point! I hope committee will approve [] (a) {} form.
Stop making simple things compicated!

On Fri, Jan 11, 2013 at 10:08 PM, <nadiasvertex@gmail.com> wrote:

>
>
> On Saturday, December 29, 2012 10:01:20 AM UTC-5, innoc...@gmail.comwrote:
>>
>> so, maybe it'd make sense to introduce some special keyword to
>> disambiguate these cases?
>>
>> On Tuesday, December 18, 2012 5:50:50 PM UTC+2, tra...@solidfire.comwrote:
>>>
>>> The `auto` is required is disambiguate this:
>>>
>>> [] (a) {}
>>>
>>> Is `a` an automatically-typed variable or an unnamed argument with the
>>> type `a`?
>>>
>>
> It's an automatically-typed variable. Having an unnamed argument in a
> lambda in senseless. You can't overload it, so using it to force the
> compiler to choose some version of a function isn't possible. You can't
> refer to it. It is therefore silly to create problem which does not, in
> practice, exist.
>
>
>



--
Thanks,
Alex

--




--e89a8f3b9f7d10608b04d308e95c
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

good point! I hope committee will approve [] (a) {} form.<br>Stop making si=
mple things compicated!<br><br><div class=3D"gmail_quote">On Fri, Jan 11, 2=
013 at 10:08 PM,  <span dir=3D"ltr">&lt;<a href=3D"mailto:nadiasvertex@gmai=
l.com" target=3D"_blank">nadiasvertex@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"><br><br>On Saturday, December 29, 2012 10:01=
:20 AM UTC-5, <a href=3D"mailto:innoc...@gmail.com" target=3D"_blank">innoc=
....@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">
so, maybe it&#39;d make sense to introduce some special keyword to disambig=
uate these cases?<br><br>On Tuesday, December 18, 2012 5:50:50 PM UTC+2, <a=
>tra...@solidfire.com</a> wrote:<blockquote class=3D"gmail_quote" style=3D"=
margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex">
The `auto` is required is disambiguate this:<br><br>[] (a) {}<br><br>Is `a`=
 an automatically-typed variable or an unnamed argument with the type `a`?<=
br></blockquote></blockquote><div><br></div><div>It&#39;s an automatically-=
typed variable. Having an unnamed argument in a lambda in senseless. You ca=
n&#39;t overload it, so using it to force the compiler to choose some versi=
on of a function isn&#39;t possible. You can&#39;t refer to it. It is there=
fore silly to create problem which does not, in practice, exist.</div>
<div><br></div><div>=A0</div></blockquote></div><br><br clear=3D"all"><br>-=
- <br>Thanks,<div>Alex</div>

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

--e89a8f3b9f7d10608b04d308e95c--

.


Author: =?UTF-8?Q?R=C3=B3bert_D=C3=A1vid?= <lrdxgm@gmail.com>
Date: Fri, 11 Jan 2013 13:27:33 -0800 (PST)
Raw View
------=_Part_1046_28892478.1357939653622
Content-Type: text/plain; charset=ISO-8859-2
Content-Transfer-Encoding: quoted-printable

I didn't read the previous discussion, so sorry if it came up already.

There is more reasons to have a parameter on a function or lambda, if you=
=20
happen to write a callback function, you need to match the correct=20
signature. And lambdas in my experience used a lot for callbacks.
Consider the following:
class A{}; class B{}; class C{};
typedef void (*callback1)(A /*required*/, B /*optional*/);
typedef void (*callback2)(A /*required*/, C /*optional*/);
void func(callback1);
void func(callback2);

void foo() {
    func([](A a, B){ /*Do stuff with only a*/});
}
If B is an automatic-typed variable, this is ambiguous, even though it is=
=20
perfectly clear what the programmer wanted. Requiring auto if you want a=20
parameter named B makes this a non-issue.

I also like the version with requiring auto better. It makes a lot easier=
=20
to read the code later, auto practically yelling "hey, there is a new=20
parameter here".

Regards, Robert


2013. janu=E1r 11., p=E9ntek 21:08:09 UTC+1 id=F5pontban nadias...@gmail.co=
m a=20
k=F6vetkez=F5t =EDrta:
>
>
>
> On Saturday, December 29, 2012 10:01:20 AM UTC-5, innoc...@gmail.comwrote=
:
>>
>> so, maybe it'd make sense to introduce some special keyword to=20
>> disambiguate these cases?
>>
>> On Tuesday, December 18, 2012 5:50:50 PM UTC+2, tra...@solidfire.comwrot=
e:
>>>
>>> The `auto` is required is disambiguate this:
>>>
>>> [] (a) {}
>>>
>>> Is `a` an automatically-typed variable or an unnamed argument with the=
=20
>>> type `a`?
>>>
>>
> It's an automatically-typed variable. Having an unnamed argument in a=20
> lambda in senseless. You can't overload it, so using it to force the=20
> compiler to choose some version of a function isn't possible. You can't=
=20
> refer to it. It is therefore silly to create problem which does not, in=
=20
> practice, exist.
>
> =20
>

--=20




------=_Part_1046_28892478.1357939653622
Content-Type: text/html; charset=ISO-8859-2
Content-Transfer-Encoding: quoted-printable

I didn't read the previous discussion, so sorry if it came up already.<br><=
br>There is more reasons to have a parameter on a function or lambda, if yo=
u happen to write a callback function, you need to match the correct signat=
ure. And lambdas in my experience used a lot for callbacks.<br>Consider the=
 following:<br><div class=3D"prettyprint" style=3D"background-color: rgb(25=
0, 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"subprettyprint"><span style=3D"color: #008;" class=3D"styled-by-prettif=
y">class</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> A=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">{};</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span sty=
le=3D"color: #008;" class=3D"styled-by-prettify">class</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"> B</span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">{};</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> class C{};<br></span><span style=3D"color: #0=
08;" class=3D"styled-by-prettify">typedef</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">void</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">(*</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
>callback1</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
)(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">A /*requ=
ired</span><span style=3D"color: #660;" class=3D"styled-by-prettify">*/,</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> B</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify"> /*optional*/);</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>typedef void=
 (*callback2)(A </span><code class=3D"prettyprint"><span style=3D"color: #0=
00;" class=3D"styled-by-prettify">/*required</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">*/,</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"> C</span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify"> /*optional*/</span></code><span style=3D"color: #000;" =
class=3D"styled-by-prettify">);<br></span><span style=3D"color: #008;" clas=
s=3D"styled-by-prettify">void</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"> func</span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify">callback</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">1);</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=
void func(callback2);<br><br></span><span style=3D"color: #008;" class=3D"s=
tyled-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-pre=
ttify">()</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> =
</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: #000;" class=3D"styled-by-prettify">&nbsp; &nbsp; func</span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">([](</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify">A a</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"> B</span><span style=3D"color: #660;"=
 class=3D"styled-by-prettify">){</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #800;" class=3D"style=
d-by-prettify">/*</span><span style=3D"color: #800;" class=3D"styled-by-pre=
ttify"><code class=3D"prettyprint"><span style=3D"color: #800;" class=3D"st=
yled-by-prettify">Do stuff with only a</span><span style=3D"color: #800;" c=
lass=3D"styled-by-prettify"></span></code>*/</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">});</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"><br></span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">}</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"><br></span></div></code></div>If B is an automatic-typed variab=
le, this is ambiguous, even though it is perfectly clear what the programme=
r wanted. Requiring auto if you want a parameter named B makes this a non-i=
ssue.<br><br>I also like the version with requiring auto better. It makes a=
 lot easier to read the code later, auto practically yelling "hey, there is=
 a new parameter here".<br><br>Regards, Robert<br><br><br>2013. janu=E1r 11=
.., p=E9ntek 21:08:09 UTC+1 id=F5pontban nadias...@gmail.com a k=F6vetkez=F5=
t =EDrta:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: =
0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><br><br>On Saturday, =
December 29, 2012 10:01:20 AM UTC-5, <a>innoc...@gmail.com</a> wrote:<block=
quote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left=
:1px #ccc solid;padding-left:1ex">so, maybe it'd make sense to introduce so=
me special keyword to disambiguate these cases?<br><br>On Tuesday, December=
 18, 2012 5:50:50 PM UTC+2, <a>tra...@solidfire.com</a> wrote:<blockquote c=
lass=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #c=
cc solid;padding-left:1ex">The `auto` is required is disambiguate this:<br>=
<br>[] (a) {}<br><br>Is `a` an automatically-typed variable or an unnamed a=
rgument with the type `a`?<br></blockquote></blockquote><div><br></div><div=
>It's an automatically-typed variable. Having an unnamed argument in a lamb=
da in senseless. You can't overload it, so using it to force the compiler t=
o choose some version of a function isn't possible. You can't refer to it. =
It is therefore silly to create problem which does not, in practice, exist.=
</div><div><br></div><div>&nbsp;</div></blockquote>

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_1046_28892478.1357939653622--

.


Author: Faisal Vali <faisalv@gmail.com>
Date: Fri, 11 Jan 2013 22:11:48 -0600
Raw View
On Fri, Jan 11, 2013 at 8:12 PM,  <andy.prowl@gmail.com> wrote:
> I have a quick question concerning the standardization of generic lambdas. I
> am not sure if this is the place where to ask, so I apologize in advance if
> that is not the case.
>
> The current standard forbids declaring local types which contain template
> member functions. Clearly, generic lambdas will have to be an exception to
> this rule.
> My question is: will this restriction be lifted completely, or will generic
> lambdas be the only exception allowed?
>

It is my personal opinion that if the restriction on local class
templates or local member templates is to be lifted, a separate
proposal would be required (and I really hope someone writes one).  As
far as I know, the EWG has not had any official discussion so far
about lifting this restriction (or enabling this feature); but, a
formal and well thought out proposal could make all the difference...

--




.