220 5926 <1a43d06d-0ffa-45e6-bc10-577ce1fd4503@isocpp.org> article
Path: news.gmane.org!not-for-mail
From: cornedbee@google.com
Newsgroups: gmane.comp.lang.c++.isocpp.proposals
Subject: Re: Proposal: Mixins for C++
Date: Wed, 28 Aug 2013 04:59:51 -0700 (PDT)
Lines: 244
Approved: news@gmane.org
Message-ID: <1a43d06d-0ffa-45e6-bc10-577ce1fd4503@isocpp.org>
References: <787081f7-fb40-4507-907d-259318ef2000@isocpp.org>
 <23afefa3-3c10-4bbe-b07e-9d3b4addb162@isocpp.org>
 <3fcaf17b-b333-4c45-aeab-261bf274fad1@isocpp.org>
 <a67a536d-92ab-4ea8-b03c-2f97895ef48f@isocpp.org>
Reply-To: std-proposals@isocpp.org
NNTP-Posting-Host: plane.gmane.org
Mime-Version: 1.0
Content-Type: multipart/alternative; 
	boundary="----=_Part_23_28773091.1377691191182"
X-Trace: ger.gmane.org 1377691190 32093 80.91.229.3 (28 Aug 2013 11:59:50 GMT)
X-Complaints-To: usenet@ger.gmane.org
NNTP-Posting-Date: Wed, 28 Aug 2013 11:59:50 +0000 (UTC)
Cc: cornedbee@google.com
To: std-proposals@isocpp.org
Original-X-From: std-proposals+bncBD43DGWT5IFRBOGM66IAKGQENWU7ZRQ@isocpp.org Wed Aug 28 13:59:53 2013
Return-path: <std-proposals+bncBD43DGWT5IFRBOGM66IAKGQENWU7ZRQ@isocpp.org>
Envelope-to: gclcip-std-proposals@m.gmane.org
Original-Received: from mail-ye0-f200.google.com ([209.85.213.200])
	by plane.gmane.org with esmtp (Exim 4.69)
	(envelope-from <std-proposals+bncBD43DGWT5IFRBOGM66IAKGQENWU7ZRQ@isocpp.org>)
	id 1VEePh-00069s-FI
	for gclcip-std-proposals@m.gmane.org; Wed, 28 Aug 2013 13:59:53 +0200
Original-Received: by mail-ye0-f200.google.com with SMTP id r5sf6266386yen.11
        for <gclcip-std-proposals@m.gmane.org>; Wed, 28 Aug 2013 04:59:52 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=google.com; s=20120113;
        h=date:from:to:cc:message-id:in-reply-to:references:subject
         :mime-version:x-original-sender:reply-to:precedence:mailing-list
         :list-id:list-post:list-help:list-archive:list-subscribe
         :list-unsubscribe:content-type;
        bh=fcil09nuQukBUE4VTnWcXJDzeq9wZvW8Vl20GE0qUMk=;
        b=nlg6BCPq7aM9xNkH2YCMwb6QRkvOy3A1JEENsaMnNWF0iMfP2mhH5TSqsFHRdOeYvK
         Heg5xC1IKtX4xLhAlVy4QkkA8XIsOO3M+OTMZN/o0OG/2NPUlFiUIF1j7jbNMc1azfIx
         7O8Et8vAHcYwl6evTwk5PVGpS2+b9OMMESq2bVeqtFjmruXY24Mcrt4AjmQjUHbgqr5K
         wBrfE2NI93S2BI7CuIm/uTceOmzhrn3Mc3R5t63nsPpQLDsdkxL/8F/iWqft75i+yY+h
         0YljHwKEmB+ZxIiI0meqETPcXoeNN4TrHXJs9fzoh5IewL5JYKnWgGquJYYWfRQkRM2D
         XJgQ==
X-Received: by 10.236.180.71 with SMTP id i47mr4898775yhm.31.1377691192314;
        Wed, 28 Aug 2013 04:59:52 -0700 (PDT)
X-BeenThere: std-proposals@isocpp.org
Original-Received: by 10.49.16.103 with SMTP id f7ls328009qed.77.gmail; Wed, 28 Aug
 2013 04:59:51 -0700 (PDT)
X-Received: by 10.49.59.35 with SMTP id w3mr45772qeq.8.1377691191671;
        Wed, 28 Aug 2013 04:59:51 -0700 (PDT)
In-Reply-To: <a67a536d-92ab-4ea8-b03c-2f97895ef48f@isocpp.org>
X-Original-Sender: cornedbee@google.com
Precedence: list
Mailing-list: list std-proposals@isocpp.org; contact std-proposals+owners@isocpp.org
List-ID: <std-proposals.isocpp.org>
X-Google-Group-Id: 399137483710
List-Post: <http://groups.google.com/a/isocpp.org/group/std-proposals/post>, <mailto:std-proposals@isocpp.org>
List-Help: <http://support.google.com/a/isocpp.org/bin/topic.py?topic=25838>, <mailto:std-proposals+help@isocpp.org>
List-Archive: <http://groups.google.com/a/isocpp.org/group/std-proposals/>
List-Subscribe: <http://groups.google.com/a/isocpp.org/group/std-proposals/subscribe>,
 <mailto:std-proposals+subscribe@isocpp.org>
List-Unsubscribe: <http://groups.google.com/a/isocpp.org/group/std-proposals/subscribe>,
 <mailto:googlegroups-manage+399137483710+unsubscribe@googlegroups.com>
Xref: news.gmane.org gmane.comp.lang.c++.isocpp.proposals:5926
Archived-At: <http://permalink.gmane.org/gmane.comp.lang.c++.isocpp.proposals/5926>

------=_Part_23_28773091.1377691191182
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable



On Wednesday, August 28, 2013 1:17:32 PM UTC+2, R=F3bert D=E1vid wrote:
>
>
>> Nice that it works in VS2012. Have you actually tried instantiating it?
>> It's still invalid, and won't compile in Clang or GCC. You can't use=20
>> `this` (even implicitly) at the top level of a class, even inside a=20
>> decltype. Even if you could, at that point the type Derived is incomplet=
e=20
>> and the get() call would be invalid. And finally, no, you can't omit the=
=20
>> template arguments to my_ptr when passing it to the base class, because =
as=20
>> [basic.scope.pdecl]p7 says, "The point of declaration for an=20
>> injected-class-name (Clause 9) is immediately following the opening brac=
e=20
>> of the class definition." The opening brace is of course after the base=
=20
>> class specifier, so the injected-class-name doesn't exist there.
>> Now you could argue that these are defects in the standard, but the fact=
=20
>> is that your "simple" CRTP example is currently not valid C++, and thus =
not=20
>> a counterargument to my points.
>>
>
> Yes, of course, it works fine in every way. This was the compiler at hand=
,=20
> and I didn't try in other compilers, didn't think this can be nonstandard=
=20
> (MSVC surprises me every now and then in being nonstandard, but I think=
=20
> this is a convenient extension.)
>

This is really curious, because it doesn't actually compile once you try to=
=20
instantiate it:
http://rise4fun.com/Vcpp/dWWR=20

>
> =20
>> Even if above example was valid, that wouldn't change the fact that it's=
=20
>> still CRTP. I claim that CRTP by its very nature is not intuitive - sayi=
ng,=20
>> "but using CRTP doesn't need the extra boilerplate that you also complai=
ned=20
>> about" doesn't contradict my core argument.
>>
>
> Instead ditching CRTP for an (in my opinion) infernal,
>

I didn't think it was that bad ... ;-)
=20

> but more intuitive solution, adding more complication to the language=20
> without any real benefit, what about trying to make CRTP more intuitive?
>

Making the injected-class-name available in the base class list gets rid of=
=20
completely unnecessary syntax clutter. That's a good thing, but it doesn't=
=20
really increase the ease of CRTP.

My main objections are:
1) The very nature of the curious recursion in the CRTP makes it=20
unintuitive. Deriving from a class template that you gave the deriving=20
class tied a knot in the brain of every single person I've ever explained=
=20
it to. That includes people I've explained to how Java's IComparable works.=
=20
(It's also curiously recurring, even though it's not a template.)
2) A CRTP base isn't actually bound to the deriving class. That is, I can=
=20
do "class foo : public crtp<bar>", and the compiler can't immediately say,=
=20
"This is wrong!". And currently (with the injected-class-name not available=
=20
in the base list), such an error is actually easy to make - just make an=20
error in specifying the template arguments to your own class. Mixins simply=
=20
make this error impossible. (This, by the way, is a big argument for me=20
against Nevin's suggestion to make the embedding class argument explicit.)
3) On the flip side, the compiler can't know, in the CRTP class, that the=
=20
only class ever to derive from it will be the one named by the Derived=20
argument, because the language doesn't make such a guarantee.
4) The derived type can never be complete, or even partially complete, in=
=20
the CRTP class body. That's just not how the compilation model of C++=20
works. The only way for the embedding class to provide things to the CRTP=
=20
mixin that need to be known in the class definition and not just in the=20
member definitions is via additional template arguments (possibly just one=
=20
that is a traits class containing all the info). This is a major usability=
=20
impediment.

To solve these problems, you would have to add the following to C++:
To solve 1) and 2), there would be a need to create a class template that,=
=20
when derived from, implicitly gets the deriving class passed as a template=
=20
argument. There must not be different way to pass this argument.
To solve 3), the compiler would have to know, in such a class, that the=20
static type of `this` should be a pointer to that derived class.
To solve 4), there would have to be a way to delay instantiation of the=20
base class until some point in the class definition, so that the base class=
=20
can access at least parts of the deriving class.

I added these extensions. I call them mixins.
=20

> =20
> Well, this list is the "C++ standard proposals", if people didn't think i=
t=20
> needs tweaks here and there, it would been deserted long ago.
>
>
Ah, you were talking about general C++ tweaks. I thought you meant=20
something related to this particular problem domain.

--=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_23_28773091.1377691191182
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Wednesday, August 28, 2013 1:17:32 PM UTC+2, R=
=F3bert D=E1vid 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"><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.=
8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><br><div>=
Nice that it works in VS2012. Have you actually tried instantiating it?</di=
v><div>It's still invalid, and won't compile in Clang or GCC. You can't use=
 `this` (even implicitly) at the top level of a class, even inside a declty=
pe. Even if you could, at that point the type Derived is incomplete and the=
 get() call would be invalid. And finally, no, you can't omit the template =
arguments to my_ptr when passing it to the base class, because as [basic.sc=
ope.pdecl]p7 says, "The point of declaration for an injected-class-name (Cl=
ause 9) is immediately following the opening brace of the class definition.=
" The opening brace is of course after the base class specifier, so the inj=
ected-class-name doesn't exist there.</div><div>Now you could argue that th=
ese are defects in the standard, but the fact is that your "simple" CRTP ex=
ample is currently not valid C++, and thus not a counterargument to my poin=
ts.</div></div></blockquote><div><br>Yes, of course, it works fine in every=
 way. This was the compiler at hand, and I didn't try in other compilers, d=
idn't think this can be nonstandard (MSVC surprises me every now and then i=
n being nonstandard, but I think this is a convenient extension.)<br></div>=
</div></blockquote><div><br></div><div>This is really curious, because it d=
oesn't actually compile once you try to instantiate it:</div><div><a href=
=3D"http://rise4fun.com/Vcpp/dWWR">http://rise4fun.com/Vcpp/dWWR</a>&nbsp;<=
/div><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><br=
></div><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>&nbsp;=
</div><div>Even if above example was valid, that wouldn't change the fact t=
hat it's still CRTP. I claim that CRTP by its very nature is not intuitive =
- saying, "but using CRTP doesn't need the extra boilerplate that you also =
complained about" doesn't contradict my core argument.</div></div></blockqu=
ote><div><br>Instead ditching CRTP for an (in my opinion) infernal,</div></=
div></blockquote><div><br></div><div>I didn't think it was that bad ... ;-)=
</div><div>&nbsp;</div><blockquote class=3D"gmail_quote" style=3D"margin: 0=
;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div di=
r=3D"ltr"><div> but more intuitive solution, adding more complication to th=
e language without any real benefit, what about trying to make CRTP more in=
tuitive?</div></div></blockquote><div><br></div><div>Making the injected-cl=
ass-name available in the base class list gets rid of completely unnecessar=
y syntax clutter. That's a good thing, but it doesn't really increase the e=
ase of CRTP.</div><div><br></div><div>My main objections are:</div><div>1) =
The very nature of the curious recursion in the CRTP makes it unintuitive. =
Deriving from a class template that you gave the deriving class tied a knot=
 in the brain of every single person I've ever explained it to. That includ=
es people I've explained to how Java's IComparable works. (It's also curiou=
sly recurring, even though it's not a template.)</div><div>2) A CRTP base i=
sn't actually bound to the deriving class. That is, I can do "class foo : p=
ublic crtp&lt;bar&gt;", and the compiler can't immediately say, "This is wr=
ong!". And currently (with the injected-class-name not available in the bas=
e list), such an error is actually easy to make - just make an error in spe=
cifying the template arguments to your own class. Mixins simply make this e=
rror impossible. (This, by the way, is a big argument for me against Nevin'=
s suggestion to make the embedding class argument explicit.)</div><div>3) O=
n the flip side, the compiler can't know, in the CRTP class, that the only =
class ever to derive from it will be the one named by the Derived argument,=
 because the language doesn't make such a guarantee.</div><div>4) The deriv=
ed type can never be complete, or even partially complete, in the CRTP clas=
s body. That's just not how the compilation model of C++ works. The only wa=
y for the embedding class to provide things to the CRTP mixin that need to =
be known in the class definition and not just in the member definitions is =
via additional template arguments (possibly just one that is a traits class=
 containing all the info). This is a major usability impediment.</div><div>=
<br></div><div>To solve these problems, you would have to add the following=
 to C++:</div><div>To solve 1) and 2), there would be a need to create a cl=
ass template that, when derived from, implicitly gets the deriving class pa=
ssed as a template argument. There must not be different way to pass this a=
rgument.</div><div>To solve 3), the compiler would have to know, in such a =
class, that the static type of `this` should be a pointer to that derived c=
lass.</div><div>To solve 4), there would have to be a way to delay instanti=
ation of the base class until some point in the class definition, so that t=
he base class can access at least parts of the deriving class.</div><div><b=
r></div><div>I added these extensions. I call them mixins.</div><div>&nbsp;=
</div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8=
ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div>&n=
bsp;<br></div><div>Well, this list is the "C++ standard proposals", if peop=
le didn't think it needs tweaks here and there, it would been deserted long=
 ago.<br><br></div></div></blockquote><div><br></div><div>Ah, you were talk=
ing about general C++ tweaks. I thought you meant something related to this=
 particular problem domain.</div><div><br></div></div>

<p></p>

-- <br />
&nbsp;<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 std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<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_23_28773091.1377691191182--

.
