Topic: Compile-time generated abstract-syntax-trees using


Author: Paul <peetpaul69@gmail.com>
Date: Thu, 25 Feb 2016 10:06:51 -0800 (PST)
Raw View
------=_Part_1133_1840310694.1456423611493
Content-Type: multipart/alternative;
 boundary="----=_Part_1134_220028316.1456423611494"

------=_Part_1134_220028316.1456423611494
Content-Type: text/plain; charset=UTF-8

*Compile-time generated abstract-syntax-trees using generalized concepts*

*Problem:*

A major issue in generic programming with C++ is the increase of
compile-time
when compiling a complex code base (Boost, Hana, ...). Compilers like Clang
or GCC usually only cache the tokens from the source code, this is already a
good thing to do, to improve compile-time but the Lexer of a compiler
isn't the most time wasting part of the compile chain.
The Parser and Semantic-Analysis takes up the most time because every time a
template gets instantiated, the compiler basically re-runs the Parser &
Semantic-Analysis.
Another problem which arises when using templates is the misguided
diagnostic
but with the use of the concepts extension for C++, this issue can be
partially
seen as solved.

*Approach using AST-Injection:*

The idea is to generate an abstract-syntax-tree (AST) which can be injected
into
an appropriate context. This seems simple as it completely eliminates the
need
of re-parsing and requires minimal semantic analysis in context of the
place to
inject the AST.

*Problem with AST-Injection:*

Lets say we have this template code:

    template <typename T, typename Z>
    auto Foo(T a, Z b) {
      return T.getConstant(z);
    }

How can the compiler know what T is when Foo hasn't been instantiated?
The compiler simply cannot create an AST because it doesn't know the
signature
of getConstant and the class in general.
To create an independent AST which can be merged later within the context
to be inject, we have to at least constrain the type T, like we do with
Concepts
just with another purpose to get better diagnostics.

*Problem with Concepts:*

As a result from the above conclusions it seems that replacing 'typename'
with a
concept should solve the 'signature' problem.

Lets see:

    template<typename T, typename U>
    concept bool SameTy() {
      return std::is_same<T, U>::value;
    }

    template <typename T>
    concept bool TConcept =
      requires () {
        { &T::getConstant } -> SameTy<int (T::*) (int)>;
      } ||
      requires () {
        { &T::getConstant } -> SameTy<int (T::*) (short)>;
      };

    template <TConcept T, typename Z>
    auto Foo(T a, Z b) {
      return T.getConstant(z);
    }

We are basically checking the non-static member function's signature by
using
concepts but there is a flaw in that. You are not supposed to do type
signature
in that way, it seems more like a hack and has lots of limitations
(overloads?),
because of the expression based constraining.

*Generalizing Concepts:*

"Concepts are not a general purpose, compile-time introspection tool.
Nor are they a general purpose template metaprogramming tool." - Andrew
Sutton [1]

I would say that if the current Concepts proposal would be designed to be a
general purpose compile-time introspection tool, it would mainly give us the
ability to get this whole idea to reality.

Features like in-built signature checking is mostly needed to created an
useful
AST. A way which tells the compiler the approximate semantics/syntax of the
type.

*Syntax for injection an AST:*

This is an example of how code might look like when using the AST-Injection
approach.

    // I found this "old" concepts syntax somewhere which fits the
"generalized"
    // concepts approach
    concept TConcept<typename T> {
      int T::getConstant(int);
      int T::getConstant(short);
    }

    constast <TConcept T, typename Z>
    auto Foo(T a, Z b) {
      return T.getConstant(z);
    }

I know this isn't a proposal and this may contain tons of flaws but I just
would
like to share what I had in mind regards the still consisting issues with
templates and ideas how to solve it.

I would like to know what you think about this. Thank You.

[1]
https://www.reddit.com/r/cpp/comments/43p50g/c_concepts_possible_to_check_function_signatures/czjyteu

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/4550eac8-4009-455b-bfa1-d96278466c1b%40isocpp.org.

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

<div dir=3D"ltr"><div><b><u>Compile-time generated abstract-syntax-trees us=
ing generalized concepts</u></b></div><div><br></div><div><b>Problem:</b></=
div><div><br></div><div>A major issue in generic programming with C++ is th=
e increase of compile-time</div><div>when compiling a complex code base (Bo=
ost, Hana, ...). Compilers like Clang</div><div>or GCC usually only cache t=
he tokens from the source code, this is already a</div><div>good thing to d=
o, to improve compile-time but the Lexer of a compiler</div><div>isn&#39;t =
the most time wasting part of the compile chain.</div><div>The Parser and S=
emantic-Analysis takes up the most time because every time a</div><div>temp=
late gets instantiated, the compiler basically re-runs the Parser &amp;</di=
v><div>Semantic-Analysis.</div><div>Another problem which arises when using=
 templates is the misguided diagnostic</div><div>but with the use of the co=
ncepts extension for C++, this issue can be partially</div><div>seen as sol=
ved.</div><div><b><br></b></div><div><b>Approach using AST-Injection:</b></=
div><div><br></div><div>The idea is to generate an abstract-syntax-tree (AS=
T) which can be injected into</div><div>an appropriate context. This seems =
simple as it completely eliminates the need</div><div>of re-parsing and req=
uires minimal semantic analysis in context of the place to</div><div>inject=
 the AST.</div><div><b><br></b></div><div><b>Problem with AST-Injection:</b=
></div><div><br></div><div>Lets say we have this template code:</div><div><=
br></div><div>=C2=A0 =C2=A0 template &lt;typename T, typename Z&gt;</div><d=
iv>=C2=A0 =C2=A0 auto Foo(T a, Z b) {</div><div>=C2=A0 =C2=A0 =C2=A0 return=
 T.getConstant(z);</div><div>=C2=A0 =C2=A0 }</div><div><br></div><div>How c=
an the compiler know what T is when Foo hasn&#39;t been instantiated?</div>=
<div>The compiler simply cannot create an AST because it doesn&#39;t know t=
he signature</div><div>of getConstant and the class in general.</div><div>T=
o create an independent AST which can be merged later within the context</d=
iv><div>to be inject, we have to at least constrain the type T, like we do =
with Concepts</div><div>just with another purpose to get better diagnostics=
..</div><div><br></div><div><b>Problem with Concepts:</b></div><div><br></di=
v><div>As a result from the above conclusions it seems that replacing &#39;=
typename&#39; with a</div><div>concept should solve the &#39;signature&#39;=
 problem.</div><div><br></div><div>Lets see:</div><div><br></div><div>=C2=
=A0 =C2=A0 template&lt;typename T, typename U&gt;</div><div>=C2=A0 =C2=A0 c=
oncept bool SameTy() {</div><div>=C2=A0 =C2=A0 =C2=A0 return std::is_same&l=
t;T, U&gt;::value;</div><div>=C2=A0 =C2=A0 }</div><div>=C2=A0 =C2=A0=C2=A0<=
/div><div>=C2=A0 =C2=A0 template &lt;typename T&gt;</div><div>=C2=A0 =C2=A0=
 concept bool TConcept =3D</div><div>=C2=A0 =C2=A0 =C2=A0 requires () {</di=
v><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 { &amp;T::getConstant } -&gt; SameTy&lt;=
int (T::*) (int)&gt;;</div><div>=C2=A0 =C2=A0 =C2=A0 } ||</div><div>=C2=A0 =
=C2=A0 =C2=A0 requires () {</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 { &amp;T:=
:getConstant } -&gt; SameTy&lt;int (T::*) (short)&gt;;</div><div>=C2=A0 =C2=
=A0 =C2=A0 };</div><div><br></div><div>=C2=A0 =C2=A0 template &lt;TConcept =
T, typename Z&gt;</div><div>=C2=A0 =C2=A0 auto Foo(T a, Z b) {</div><div>=
=C2=A0 =C2=A0 =C2=A0 return T.getConstant(z);</div><div>=C2=A0 =C2=A0 }</di=
v><div><br></div><div>We are basically checking the non-static member funct=
ion&#39;s signature by using</div><div>concepts but there is a flaw in that=
.. You are not supposed to do type signature</div><div>in that way, it seems=
 more like a hack and has lots of limitations (overloads?),</div><div>becau=
se of the expression based constraining.</div><div><br></div><div><b>Genera=
lizing Concepts:</b></div><div><br></div><div>&quot;Concepts are not a gene=
ral purpose, compile-time introspection tool.</div><div>Nor are they a gene=
ral purpose template metaprogramming tool.&quot; - Andrew Sutton [1]</div><=
div><br></div><div>I would say that if the current Concepts proposal would =
be designed to be a</div><div>general purpose compile-time introspection to=
ol, it would mainly give us the</div><div>ability to get this whole idea to=
 reality.</div><div><br></div><div>Features like in-built signature checkin=
g is mostly needed to created an useful</div><div>AST. A way which tells th=
e compiler the approximate semantics/syntax of the type.</div><div><br></di=
v><div><b>Syntax for injection an AST:</b></div><div><br></div><div>This is=
 an example of how code might look like when using the AST-Injection</div><=
div>approach.</div><div><br></div><div>=C2=A0 =C2=A0 // I found this &quot;=
old&quot; concepts syntax somewhere which fits the &quot;generalized&quot;<=
/div><div>=C2=A0 =C2=A0 // concepts approach</div><div>=C2=A0 =C2=A0 concep=
t TConcept&lt;typename T&gt; {</div><div>=C2=A0 =C2=A0 =C2=A0 int T::getCon=
stant(int);</div><div>=C2=A0 =C2=A0 =C2=A0 int T::getConstant(short);</div>=
<div>=C2=A0 =C2=A0 }</div><div>=C2=A0 =C2=A0=C2=A0</div><div>=C2=A0 =C2=A0 =
constast &lt;TConcept T, typename Z&gt;=C2=A0</div><div>=C2=A0 =C2=A0 auto =
Foo(T a, Z b) {</div><div>=C2=A0 =C2=A0 =C2=A0 return T.getConstant(z);</di=
v><div>=C2=A0 =C2=A0 }</div><div><br></div><div>I know this isn&#39;t a pro=
posal and this may contain tons of flaws but I just would</div><div>like to=
 share what I had in mind regards the still consisting issues with</div><di=
v>templates and ideas how to solve it.</div><div><br></div><div>I would lik=
e to know what you think about this. Thank You.</div><div><br></div><div>[1=
] https://www.reddit.com/r/cpp/comments/43p50g/c_concepts_possible_to_check=
_function_signatures/czjyteu</div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/4550eac8-4009-455b-bfa1-d96278466c1b%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/4550eac8-4009-455b-bfa1-d96278466c1b=
%40isocpp.org</a>.<br />

------=_Part_1134_220028316.1456423611494--
------=_Part_1133_1840310694.1456423611493--

.