Topic: Initial proposal of Computed Code / Reification
Author: Andrew Tomazos <andrewtomazos@gmail.com>
Date: Tue, 5 Feb 2019 20:16:34 +1000
Raw View
--0000000000001bb673058122e861
Content-Type: text/plain; charset="UTF-8"
This is most likely for reflection SG7 if I turn it into a formal proposal,
but I wanted to get some initial reaction to the idea:
int main() {
std::cout << codeeval("2 + 3") << std::endl; // outputs: 5
codeeval("int x = 3");
std::cout << x << std::endl; // outputs 3
}
codeeval("struct S{}");
S s; // OK
A call to the codeeval operator takes a single argument that is converted
to std::string_view and the char sub array to which the string view refers
must be a constant expression. That is, it accepts an expression of any
(current or future) constexpr string type (a string type of literal type)
as an argument. The text is parsed directly into *tokens*, and
syntactically and semantically analyzed as per translation phase 7 (no
preprocessor):
#define X 3
int main() {
return codeeval("X"); // ERROR
}
Depending on the location of the codeeval operator call, the argument text
is matched against an appropriate production for the location. That is:
- if it appears at namespace scope the codeeval call is itself a
declaration, and the argument is matched against a declaration-seq.
- if it appears at class scope the codeeval call is itself a
member-declaration, and the argument is matched against a
member-declaration-seq.
- if it appears at function scope the codeeval call is itself a statement,
and the argument is matched against a statement-seq
- if it appears within an expression, or where an expression can appear,
the codeeval call is itself an expression, and the argument is matched
against an expression
The codeeval call is replaced during translation phase 7 by the
construct(s) its argument is matched against and translation phase 7
continues.
This enables code to be computed during compile-time using constexpr
programming.
--
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/CAB%2B4KHKoCaiaZyHhyiEaXp%3DaD7OCYXuHoyVu9iLWWup9A%2B_2aA%40mail.gmail.com.
--0000000000001bb673058122e861
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div dir=3D"ltr">This is most likely for reflection SG7 if=
I turn it into a formal proposal, but I wanted to get some initial reactio=
n to the idea:<div><br></div><div>=C2=A0 int main() {</div><div>=C2=A0 =C2=
=A0 =C2=A0 std::cout << codeeval("2=C2=A0+ 3") << std=
::endl; // outputs: 5</div><div><br></div><div>=C2=A0 =C2=A0 =C2=A0 codeeva=
l("int x =3D 3");<br></div><div>=C2=A0 =C2=A0 =C2=A0 std::cout &l=
t;< x << std::endl; // outputs 3</div><div>=C2=A0 }</div><div><br>=
</div><div>=C2=A0 codeeval("struct S{}");<div>=C2=A0 S s; // OK</=
div><div><br></div><div>A call to the codeeval=C2=A0operator takes a single=
argument that is converted to std::string_view and the char sub array to w=
hich the string view refers must be a constant expression.=C2=A0 That is, i=
t accepts an expression of any (current or future) constexpr string type (a=
string type of literal type) as an argument.=C2=A0 The text is parsed dire=
ctly into <i>tokens</i>, and syntactically and semantically analyzed as per=
translation phase 7 (no preprocessor):</div><div><br></div><div>=C2=A0 =C2=
=A0#define X 3</div><div>=C2=A0 =C2=A0int main() {</div><div>=C2=A0 =C2=A0 =
=C2=A0 return codeeval("X"); // ERROR</div><div>=C2=A0 =C2=A0}<br=
></div><div><br></div><div>Depending on the location of the codeeval=C2=A0o=
perator call, the argument text is matched against an appropriate productio=
n for the location.=C2=A0 That is:</div><div><br></div><div>- if it appears=
at namespace scope the codeeval=C2=A0call is itself a declaration, and the=
argument is matched against a declaration-seq.</div><div><br></div><div>- =
if it appears at class scope the codeeval=C2=A0call is itself a member-decl=
aration, and the argument is matched against a member-declaration-seq.<br><=
/div></div><div><br></div><div>- if it appears at function scope the codeev=
al=C2=A0call is itself a statement, and the argument is matched against a s=
tatement-seq</div><div><br></div><div>- if it appears within an expression,=
or where an expression can appear, the codeeval=C2=A0call is itself an exp=
ression, and the argument is matched against an expression</div><div><br></=
div><div>The codeeval call is replaced during translation phase 7 by the co=
nstruct(s) its argument is matched against and translation phase 7 continue=
s.</div><div><br></div><div>This enables code to be computed during compile=
-time using constexpr programming.</div><div><br></div></div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;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"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/CAB%2B4KHKoCaiaZyHhyiEaXp%3DaD7OCYXuH=
oyVu9iLWWup9A%2B_2aA%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfoote=
r">https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAB%2B4KHKo=
CaiaZyHhyiEaXp%3DaD7OCYXuHoyVu9iLWWup9A%2B_2aA%40mail.gmail.com</a>.<br />
--0000000000001bb673058122e861--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Tue, 5 Feb 2019 19:13:14 -0800 (PST)
Raw View
------=_Part_2079_1584676289.1549422794997
Content-Type: multipart/alternative;
boundary="----=_Part_2080_1379067537.1549422794998"
------=_Part_2080_1379067537.1549422794998
Content-Type: text/plain; charset="UTF-8"
My biggest concern with this approach is the compile-time cost, compared to
other more direct alternatives for code generation.
In general, people are not going to use simple string literals to create
the parameter to `codeeval`; they will instead use constexpr/consteval
functions which generate the string based on parameters or somesuch. Which
means that you have to invoke the compiler twice: once to compile the
regular code, then after executing some compile-time code, you execute the
compiler again on the generated string.
Most other compile-time code generation mechanisms that have been
proposed/suggested/hinted at revolve around the constexpr code generating
some kind of compilation artifact via specialized C++ syntax. Having to go
through the trouble of building a string, then invoking the compiler, to
generate that artifact is disconcerting from a performance perspective. C++
compilers aren't known for their speed.
And that's doubly important, because this feature has the best chance of
doing the thing we all kind of want to do: kill off macros. There's pretty
much nothing that a macro can do that this can't, and it's all "in the
language" to some degree. But macros are really quick to resolve, so deep
macro usage isn't terribly slow. I can't imagine this being particularly
quick to resolve.
And yes, modules will probably buy you a lot in terms of performance, since
`codeeval` techniques will probably be used to create definitions (and thus
executed only when the module needs to be built). But if people start using
these inside of functions frequently, especially templates that often get
instantiated, that will add up *quickly*.
Plus, there are the "static if" concerns. You've defined this tool to
generate a compiled artifact within the scope of where the string gets
evaluated, which can potentially cause all kinds of problems. Your
constexpr function that generated the text to be compiled may break based
on innocuous stuff that just so happened to be before it. Also, the
`codeeval`-generated artifact may break the code that comes after it by
defining things that it didn't expect to be defined.
Compare this to templates. These can be thought of as a primitive means of
generating code from a set of parameters. But they are required to generate
the same code from the same set of parameters (two-phase lookup exists, but
ODR is violated if two equivalent instantiations result in different
definitions). You get a single compilation artifact, a specific
function/type/variable. It is (usually) clear to everyone when you attempt
to use that generated entity or some sub-element of that entity (members of
a template class, etc). The names of template-generated artifacts are
separate from the names of non-template artifacts.
Overall, the scope of template code generation is very restricted. Which is
a good thing.
It's one thing to have compile-time generation of variables, functions, or
classes. It is quite another thing entirely to have compile-time generation
of expressions that exist in-situ of the code that invokes their generation.
Also, how would `codeeval`'s scoping rules work through other (no doubt
`consteval`) functions? For example, I was going to suggest having a
variant of `codeeval` that wraps the code it is given into a
reference-capturing, nullary lambda function, so that declarations made by
the string don't leak to the outside code. But then I thought that you
might have some kind of wrapper function to do that:
consteval auto safe_codeeval(std::string_view str)
{
return [&](){codeeval(str);}
}
Except that the lambda can't reach out of the scope of `safe_codeeval` to
talk to the variables at the location where `safe_codeeval` gets called.
--
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/015fb1f6-7d31-4b61-9a2a-fb01a91aca08%40isocpp.org.
------=_Part_2080_1379067537.1549422794998
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div>My biggest concern with this approach is the compile-=
time cost, compared to other more direct alternatives for code generation.<=
/div><div><br></div><div>In general, people are not going to use simple str=
ing literals to create the parameter to `codeeval`; they will instead use c=
onstexpr/consteval functions which generate the string based on parameters =
or somesuch. Which means that you have to invoke the compiler twice: once t=
o compile the regular code, then after executing some compile-time code, yo=
u execute the compiler again on the generated string.</div><div><br></div><=
div>Most other compile-time code generation mechanisms that have been propo=
sed/suggested/hinted at revolve around the constexpr code generating some k=
ind of compilation artifact via specialized C++ syntax. Having to go throug=
h the trouble of building a string, then invoking the compiler, to generate=
that artifact is disconcerting from a performance perspective. C++ compile=
rs aren't known for their speed.<br></div><div><br></div><div>And that&=
#39;s doubly important, because this feature has the best chance of doing t=
he thing we all kind of want to do: kill off macros. There's pretty muc=
h nothing that a macro can do that this can't, and it's all "i=
n the language" to some degree. But macros are really quick to resolve=
, so deep macro usage isn't terribly slow. I can't imagine this bei=
ng particularly quick to resolve.<br></div><div><br></div><div>And yes, mod=
ules will probably buy you a lot in terms of performance, since `codeeval` =
techniques will probably be used to create definitions (and thus executed o=
nly when the module needs to be built). But if people start using these ins=
ide of functions frequently, especially templates that often get instantiat=
ed, that will add up <i>quickly</i>.<br></div><div><br></div><div>Plus, the=
re are the "static if" concerns. You've defined this tool to =
generate a compiled artifact within the scope of where the string gets eval=
uated, which can potentially cause all kinds of problems. Your constexpr fu=
nction that generated the text to be compiled may break based on innocuous =
stuff that just so happened to be before it. Also, the `codeeval`-generated=
artifact may break the code that comes after it by defining things that it=
didn't expect to be defined.<br></div><div><br></div><div>Compare this=
to templates. These can be thought of as a primitive means of generating c=
ode from a set of parameters. But they are required to generate the same co=
de from the same set of parameters (two-phase lookup exists, but ODR is vio=
lated if two equivalent instantiations result in different definitions). Yo=
u get a single compilation artifact, a specific function/type/variable. It =
is (usually) clear to everyone when you attempt to use that generated entit=
y or some sub-element of that entity (members of a template class, etc). Th=
e names of template-generated artifacts are separate from the names of non-=
template artifacts.</div><div><br></div><div>Overall, the scope of template=
code generation is very restricted. Which is a good thing.<br></div><div><=
br></div><div>It's one thing to have compile-time generation of variabl=
es, functions, or classes. It is quite another thing entirely to have compi=
le-time generation of expressions that exist in-situ of the code that invok=
es their generation.</div><div><br></div><div>Also, how would `codeeval`=
9;s scoping rules work through other (no doubt `consteval`) functions? For =
example, I was going to suggest having a variant of `codeeval` that wraps t=
he code it is given into a reference-capturing, nullary lambda function, so=
that declarations made by the string don't leak to the outside code. B=
ut then I thought that you might have some kind of wrapper function to do t=
hat:</div><div><br></div><div style=3D"background-color: rgb(250, 250, 250)=
; border-color: rgb(187, 187, 187); border-style: solid; border-width: 1px;=
overflow-wrap: break-word;" class=3D"prettyprint"><code class=3D"prettypri=
nt"><div class=3D"subprettyprint"><span style=3D"color: #000;" class=3D"sty=
led-by-prettify">consteval </span><span style=3D"color: #008;" class=3D"sty=
led-by-prettify">auto</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"> safe_codeeval</span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify">std</span><span style=3D"color: #660;" class=3D"styled-by-prettify">:=
:</span><span style=3D"color: #000;" class=3D"styled-by-prettify">string_vi=
ew str</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><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><sp=
an style=3D"color: #008;" class=3D"styled-by-prettify">return</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">[&](){</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify">codeeval</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify">str</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">);}</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"><br></span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">}</span></div></code></div><div><br></div><div>Except that the l=
ambda can't reach out of the scope of `safe_codeeval` to talk to the va=
riables at the location where `safe_codeeval` gets called.<br></div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;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"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/015fb1f6-7d31-4b61-9a2a-fb01a91aca08%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/015fb1f6-7d31-4b61-9a2a-fb01a91aca08=
%40isocpp.org</a>.<br />
------=_Part_2080_1379067537.1549422794998--
------=_Part_2079_1584676289.1549422794997--
.
Author: FrankHB1989 <frankhb1989@gmail.com>
Date: Wed, 6 Feb 2019 19:55:59 -0800 (PST)
Raw View
------=_Part_190_1637381602.1549511759875
Content-Type: multipart/alternative;
boundary="----=_Part_191_838553518.1549511759875"
------=_Part_191_838553518.1549511759875
Content-Type: text/plain; charset="UTF-8"
I prefer an approach to evaluate some IR (e.g. AST) instead of the source
code. I don't see initial phases to convert the source code necessary.
--
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/889f4e62-6d35-44ab-9145-c4f5bf0c9e92%40isocpp.org.
------=_Part_191_838553518.1549511759875
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">I prefer an approach to evaluate some IR (e.g. AST) instea=
d of the=20
source code. I don't see initial phases to convert the source code=20
necessary.<br></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;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"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/889f4e62-6d35-44ab-9145-c4f5bf0c9e92%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/889f4e62-6d35-44ab-9145-c4f5bf0c9e92=
%40isocpp.org</a>.<br />
------=_Part_191_838553518.1549511759875--
------=_Part_190_1637381602.1549511759875--
.
Author: FrankHB1989 <frankhb1989@gmail.com>
Date: Wed, 6 Feb 2019 20:13:53 -0800 (PST)
Raw View
------=_Part_187_2144128350.1549512834022
Content-Type: multipart/alternative;
boundary="----=_Part_188_1159298518.1549512834023"
------=_Part_188_1159298518.1549512834023
Content-Type: text/plain; charset="UTF-8"
This approach is strictly not expressible like traditional syntactic
extensions by (non-C-style) macros. The source-code-based and
context-sensitive nature makes it even difficult to implement some
traditional tricks which should be reasonably easy for a properly designed
hygienic macro system (like block scopes by beta reduction from some
invented translation-time function evaluation), as it totally misses the
primitives to introduce such abstractions (either a macro pattern language
<https://www.gnu.org/software/guile/manual/html_node/Syntax-Rules.html> or
some more generalized things like vau operator
<https://en.wikipedia.org/wiki/Fexpr#Fexprs_since_1980>).
For such limitations, this approach does not work well for most kinds of
"reflection" concerned with meta-level code manipulation by design, except
for cases only having interest on properties of the code fairly directly
mapped from the source form. Namely, it can does little beyond some limited
forms of code generation, plus many problems on interops with existing C++
features. Then all the problems mentioned by Nicol Bolas come.
--
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/6bfa3f6a-f0b4-4d9a-a66d-81a4882d795e%40isocpp.org.
------=_Part_188_1159298518.1549512834023
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div>This
approach is strictly not expressible like traditional syntactic=20
extensions by (non-C-style) macros. The source-code-based and=20
context-sensitive nature makes it even difficult to implement some=20
traditional tricks which should be reasonably easy for a properly=20
designed hygienic macro system (like block scopes by beta reduction from
some invented translation-time function evaluation), as it totally=20
misses the primitives to introduce such abstractions (either a <a href=3D"h=
ttps://www.gnu.org/software/guile/manual/html_node/Syntax-Rules.html">macro=
pattern language</a> or some more generalized things like <a href=3D"https=
://en.wikipedia.org/wiki/Fexpr#Fexprs_since_1980">vau operator</a>).<br></d=
iv><br>For such limitations, this approach does not work well for most kind=
s of "reflection" concerned with meta-level code manipulation by =
design, except for cases only having interest on properties of the code fai=
rly directly mapped from the source form. Namely, it can does little beyond=
some limited forms of code generation, plus many problems on interops with=
existing C++ features. Then all the problems mentioned by Nicol Bolas come=
..<br><br><br></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;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"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/6bfa3f6a-f0b4-4d9a-a66d-81a4882d795e%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/6bfa3f6a-f0b4-4d9a-a66d-81a4882d795e=
%40isocpp.org</a>.<br />
------=_Part_188_1159298518.1549512834023--
------=_Part_187_2144128350.1549512834022--
.
Author: Andrew Tomazos <andrewtomazos@gmail.com>
Date: Thu, 7 Feb 2019 15:41:48 +1000
Raw View
--0000000000003bcf0e0581474dd1
Content-Type: text/plain; charset="UTF-8"
Nicol, thanks again for detailed feedback...
On Wed, Feb 6, 2019 at 1:13 PM Nicol Bolas <jmckesson@gmail.com> wrote:
> My biggest concern with this approach is the compile-time cost, compared
> to other more direct alternatives for code generation.
>
> In general, people are not going to use simple string literals to create
> the parameter to `codeeval`; they will instead use constexpr/consteval
> functions which generate the string based on parameters or somesuch. Which
> means that you have to invoke the compiler twice: once to compile the
> regular code, then after executing some compile-time code, you execute the
> compiler again on the generated string.
>
> Most other compile-time code generation mechanisms that have been
> proposed/suggested/hinted at revolve around the constexpr code generating
> some kind of compilation artifact via specialized C++ syntax. Having to go
> through the trouble of building a string, then invoking the compiler, to
> generate that artifact is disconcerting from a performance perspective. C++
> compilers aren't known for their speed.
>
> And that's doubly important, because this feature has the best chance of
> doing the thing we all kind of want to do: kill off macros. There's pretty
> much nothing that a macro can do that this can't, and it's all "in the
> language" to some degree. But macros are really quick to resolve, so deep
> macro usage isn't terribly slow. I can't imagine this being particularly
> quick to resolve.
>
> And yes, modules will probably buy you a lot in terms of performance,
> since `codeeval` techniques will probably be used to create definitions
> (and thus executed only when the module needs to be built). But if people
> start using these inside of functions frequently, especially templates that
> often get instantiated, that will add up *quickly*.
>
It's hard to know what to compare the performance against. There are two
phases. The first phase is the computation of the code. This is
essentially constexpr programming. The range of computed code is much
greater than that of macros, so its not a fair comparison - but to say its
slow is to say that constexpr programming is slow. It's not specific to
codeeval.
The second phase is the evaluation of the code. This is as fast as normal
compilation (as if you typed the computed code in by hand). It's equally
as fast as macros in this regard.
Plus, there are the "static if" concerns. You've defined this tool to
> generate a compiled artifact within the scope of where the string gets
> evaluated, which can potentially cause all kinds of problems. Your
> constexpr function that generated the text to be compiled may break based
> on innocuous stuff that just so happened to be before it. Also, the
> `codeeval`-generated artifact may break the code that comes after it by
> defining things that it didn't expect to be defined.
>
I'm not sure I follow this. If you use codeeval to introduce names into a
scope, you need to (as usual) make sure that those names don't conflict or
unintentionally shadow other names. This is no different than if you are
typing code by hand.
I'm not sure I see the relationship with static if. The reason if
constexpr doesn't introduce names is because it would be surprising, people
are familiar with the scoping rules of regular if statements. I don't
think the way codeeval works is suprising. It converts a string into
code. It's as if you typed the code in the string by hand in place of the
codeeval.
Compare this to templates. These can be thought of as a primitive means of
> generating code from a set of parameters. But they are required to generate
> the same code from the same set of parameters (two-phase lookup exists, but
> ODR is violated if two equivalent instantiations result in different
> definitions). You get a single compilation artifact, a specific
> function/type/variable. It is (usually) clear to everyone when you attempt
> to use that generated entity or some sub-element of that entity (members of
> a template class, etc). The names of template-generated artifacts are
> separate from the names of non-template artifacts.
>
> Overall, the scope of template code generation is very restricted. Which
> is a good thing.
>
> It's one thing to have compile-time generation of variables, functions, or
> classes. It is quite another thing entirely to have compile-time generation
> of expressions that exist in-situ of the code that invokes their generation.
>
I don't follow this sorry. Whatever text is in the string argument to
codeeval, its as if that string was entered by hand. This is easy to
understand.
> Also, how would `codeeval`'s scoping rules work through other (no doubt
> `consteval`) functions? For example, I was going to suggest having a
> variant of `codeeval` that wraps the code it is given into a
> reference-capturing, nullary lambda function, so that declarations made by
> the string don't leak to the outside code. But then I thought that you
> might have some kind of wrapper function to do that:
>
> consteval auto safe_codeeval(std::string_view str)
> {
> return [&](){codeeval(str);}
> }
>
> Except that the lambda can't reach out of the scope of `safe_codeeval` to
> talk to the variables at the location where `safe_codeeval` gets called.
>
It's not clear what you are trying to do here. So if you want to produce
a lambda you could:
constexpr string wrap_lambda(std::string_view str) {
return strcat("[&]{", str, "}");
}
codeeval(wrap_lambda(str));
--
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/CAB%2B4KHJBm0ea%3DEomob-rJ115R1T2hcjpF3OSJOj-QMUF5s6mWA%40mail.gmail.com.
--0000000000003bcf0e0581474dd1
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div>Nicol, thanks again for detailed feedback...</div><br=
><div class=3D"gmail_quote"><div dir=3D"ltr" class=3D"gmail_attr">On Wed, F=
eb 6, 2019 at 1:13 PM Nicol Bolas <<a href=3D"mailto:jmckesson@gmail.com=
">jmckesson@gmail.com</a>> wrote:<br></div><blockquote class=3D"gmail_qu=
ote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,20=
4);padding-left:1ex"><div dir=3D"ltr"><div>My biggest concern with this app=
roach is the compile-time cost, compared to other more direct alternatives =
for code generation.</div><div><br></div><div>In general, people are not go=
ing to use simple string literals to create the parameter to `codeeval`; th=
ey will instead use constexpr/consteval functions which generate the string=
based on parameters or somesuch. Which means that you have to invoke the c=
ompiler twice: once to compile the regular code, then after executing some =
compile-time code, you execute the compiler again on the generated string.<=
/div><div><br></div><div>Most other compile-time code generation mechanisms=
that have been proposed/suggested/hinted at revolve around the constexpr c=
ode generating some kind of compilation artifact via specialized C++ syntax=
.. Having to go through the trouble of building a string, then invoking the =
compiler, to generate that artifact is disconcerting from a performance per=
spective. C++ compilers aren't known for their speed.<br></div><div><br=
></div><div>And that's doubly important, because this feature has the b=
est chance of doing the thing we all kind of want to do: kill off macros. T=
here's pretty much nothing that a macro can do that this can't, and=
it's all "in the language" to some degree. But macros are re=
ally quick to resolve, so deep macro usage isn't terribly slow. I can&#=
39;t imagine this being particularly quick to resolve.<br></div><div><br></=
div><div>And yes, modules will probably buy you a lot in terms of performan=
ce, since `codeeval` techniques will probably be used to create definitions=
(and thus executed only when the module needs to be built). But if people =
start using these inside of functions frequently, especially templates that=
often get instantiated, that will add up <i>quickly</i>.<br></div></div></=
blockquote><div><br></div><div>It's hard to know what to compare the pe=
rformance against.=C2=A0 There are two phases.=C2=A0 The first phase is the=
computation of the code.=C2=A0 This is essentially constexpr programming.=
=C2=A0 The range of computed code is much greater than that of macros, so i=
ts not a fair comparison - but to say its slow is to say that constexpr pro=
gramming is slow.=C2=A0 It's not specific to codeeval.</div><div><br></=
div><div>The second phase is the evaluation of the code.=C2=A0 This is as f=
ast as normal compilation (as if you typed the computed code in by hand).=
=C2=A0 It's equally as fast as macros in this regard.</div><div><br></d=
iv><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;bord=
er-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr"><div>=
Plus, there are the "static if" concerns. You've defined this=
tool to generate a compiled artifact within the scope of where the string =
gets evaluated, which can potentially cause all kinds of problems. Your con=
stexpr function that generated the text to be compiled may break based on i=
nnocuous stuff that just so happened to be before it. Also, the `codeeval`-=
generated artifact may break the code that comes after it by defining thing=
s that it didn't expect to be defined.<br></div></div></blockquote><div=
><br></div><div>I'm not sure I follow this.=C2=A0 If you use codeeval t=
o introduce names into a scope, you need to (as usual) make sure that those=
names don't conflict or unintentionally shadow other names.=C2=A0 This=
is no different than if you are typing code by hand.</div><div><br></div><=
div>I'm not sure I see the relationship with static if.=C2=A0 The reaso=
n if constexpr doesn't introduce names is because it would be surprisin=
g, people are familiar with the scoping rules of regular if statements.=C2=
=A0 I don't think the way codeeval works is suprising.=C2=A0 It convert=
s a string into code.=C2=A0 It's as if you typed the code in the string=
by hand in place of the codeeval.</div><div><br></div><blockquote class=3D=
"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(2=
04,204,204);padding-left:1ex"><div dir=3D"ltr"><div>Compare this to templat=
es. These can be thought of as a primitive means of generating code from a =
set of parameters. But they are required to generate the same code from the=
same set of parameters (two-phase lookup exists, but ODR is violated if tw=
o equivalent instantiations result in different definitions). You get a sin=
gle compilation artifact, a specific function/type/variable. It is (usually=
) clear to everyone when you attempt to use that generated entity or some s=
ub-element of that entity (members of a template class, etc). The names of =
template-generated artifacts are separate from the names of non-template ar=
tifacts.</div><div><br></div><div>Overall, the scope of template code gener=
ation is very restricted. Which is a good thing.<br></div><div><br></div><d=
iv>It's one thing to have compile-time generation of variables, functio=
ns, or classes. It is quite another thing entirely to have compile-time gen=
eration of expressions that exist in-situ of the code that invokes their ge=
neration.</div></div></blockquote><div><br></div><div>I don't follow th=
is sorry.=C2=A0 Whatever text is in the string argument to codeeval, its as=
if that string was entered by hand.=C2=A0 This is easy to understand.=C2=
=A0=C2=A0</div><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"=
margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-lef=
t:1ex"><div dir=3D"ltr"><div>Also, how would `codeeval`'s scoping rules=
work through other (no doubt `consteval`) functions? For example, I was go=
ing to suggest having a variant of `codeeval` that wraps the code it is giv=
en into a reference-capturing, nullary lambda function, so that declaration=
s made by the string don't leak to the outside code. But then I thought=
that you might have some kind of wrapper function to do that:</div><div><b=
r></div><div style=3D"background-color:rgb(250,250,250);border-color:rgb(18=
7,187,187);border-style:solid;border-width:1px" class=3D"gmail-m_-809980180=
1182369320prettyprint"><code class=3D"gmail-m_-8099801801182369320prettypri=
nt"><div class=3D"gmail-m_-8099801801182369320subprettyprint"><span style=
=3D"color:rgb(0,0,0)" class=3D"gmail-m_-8099801801182369320styled-by-pretti=
fy">consteval </span><span style=3D"color:rgb(0,0,136)" class=3D"gmail-m_-8=
099801801182369320styled-by-prettify">auto</span><span style=3D"color:rgb(0=
,0,0)" class=3D"gmail-m_-8099801801182369320styled-by-prettify"> safe_codee=
val</span><span style=3D"color:rgb(102,102,0)" class=3D"gmail-m_-8099801801=
182369320styled-by-prettify">(</span><span style=3D"color:rgb(0,0,0)" class=
=3D"gmail-m_-8099801801182369320styled-by-prettify">std</span><span style=
=3D"color:rgb(102,102,0)" class=3D"gmail-m_-8099801801182369320styled-by-pr=
ettify">::</span><span style=3D"color:rgb(0,0,0)" class=3D"gmail-m_-8099801=
801182369320styled-by-prettify">string_view str</span><span style=3D"color:=
rgb(102,102,0)" class=3D"gmail-m_-8099801801182369320styled-by-prettify">)<=
/span><span style=3D"color:rgb(0,0,0)" class=3D"gmail-m_-809980180118236932=
0styled-by-prettify"><br></span><span style=3D"color:rgb(102,102,0)" class=
=3D"gmail-m_-8099801801182369320styled-by-prettify">{</span><span style=3D"=
color:rgb(0,0,0)" class=3D"gmail-m_-8099801801182369320styled-by-prettify">=
<br>=C2=A0 =C2=A0 </span><span style=3D"color:rgb(0,0,136)" class=3D"gmail-=
m_-8099801801182369320styled-by-prettify">return</span><span style=3D"color=
:rgb(0,0,0)" class=3D"gmail-m_-8099801801182369320styled-by-prettify"> </sp=
an><span style=3D"color:rgb(102,102,0)" class=3D"gmail-m_-80998018011823693=
20styled-by-prettify">[&](){</span><span style=3D"color:rgb(0,0,0)" cla=
ss=3D"gmail-m_-8099801801182369320styled-by-prettify">codeeval</span><span =
style=3D"color:rgb(102,102,0)" class=3D"gmail-m_-8099801801182369320styled-=
by-prettify">(</span><span style=3D"color:rgb(0,0,0)" class=3D"gmail-m_-809=
9801801182369320styled-by-prettify">str</span><span style=3D"color:rgb(102,=
102,0)" class=3D"gmail-m_-8099801801182369320styled-by-prettify">);}</span>=
<span style=3D"color:rgb(0,0,0)" class=3D"gmail-m_-8099801801182369320style=
d-by-prettify"><br></span><span style=3D"color:rgb(102,102,0)" class=3D"gma=
il-m_-8099801801182369320styled-by-prettify">}</span></div></code></div><di=
v><br></div><div>Except that the lambda can't reach out of the scope of=
`safe_codeeval` to talk to the variables at the location where `safe_codee=
val` gets called.</div></div></blockquote><div><br></div><div>=C2=A0It'=
s not clear what you are trying to do here.=C2=A0 So if you want to produce=
a lambda you could:</div><div><br></div><div>constexpr string wrap_lambda(=
std::string_view str) {</div><div>=C2=A0 =C2=A0return strcat("[&]{=
", str, "}");</div><div>}</div><div><br></div><div>codeeval(=
wrap_lambda(str));</div><div><br></div></div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;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"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/CAB%2B4KHJBm0ea%3DEomob-rJ115R1T2hcjp=
F3OSJOj-QMUF5s6mWA%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter"=
>https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAB%2B4KHJBm0=
ea%3DEomob-rJ115R1T2hcjpF3OSJOj-QMUF5s6mWA%40mail.gmail.com</a>.<br />
--0000000000003bcf0e0581474dd1--
.
Author: Andrew Tomazos <andrewtomazos@gmail.com>
Date: Thu, 7 Feb 2019 15:43:56 +1000
Raw View
--000000000000be6e180581475470
Content-Type: text/plain; charset="UTF-8"
On Thu, Feb 7, 2019 at 1:56 PM FrankHB1989 <frankhb1989@gmail.com> wrote:
> I prefer an approach to evaluate some IR (e.g. AST) instead of the source
> code. I don't see initial phases to convert the source code necessary.
>
I agree we should evaluate an AST, but you need someway to specify the
AST. If only there was some language to specify a C++ AST. Oh wait, there
is. It's called the C++ programming language. ;)
--
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/CAB%2B4KHJ05sdU8tQB7kFDOX2d8BO-zCFXiB%2BpSaGE75YHjgKtKQ%40mail.gmail.com.
--000000000000be6e180581475470
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div dir=3D"ltr">On Thu, Feb 7, 2019 at 1:56 PM FrankHB198=
9 <<a href=3D"mailto:frankhb1989@gmail.com">frankhb1989@gmail.com</a>>=
; wrote:<br></div><div class=3D"gmail_quote"><blockquote class=3D"gmail_quo=
te" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204=
);padding-left:1ex"><div dir=3D"ltr">I prefer an approach to evaluate some =
IR (e.g. AST) instead of the=20
source code. I don't see initial phases to convert the source code=20
necessary.<br></div></blockquote><div>=C2=A0</div><div>I agree we should ev=
aluate an AST, but you need someway to specify the AST.=C2=A0 If only there=
was some language to specify a C++ AST.=C2=A0 Oh wait, there is.=C2=A0 It&=
#39;s called the C++ programming language. ;)</div><div><br></div></div></d=
iv>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;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"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/CAB%2B4KHJ05sdU8tQB7kFDOX2d8BO-zCFXiB=
%2BpSaGE75YHjgKtKQ%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter"=
>https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAB%2B4KHJ05s=
dU8tQB7kFDOX2d8BO-zCFXiB%2BpSaGE75YHjgKtKQ%40mail.gmail.com</a>.<br />
--000000000000be6e180581475470--
.
Author: Andrew Tomazos <andrewtomazos@gmail.com>
Date: Thu, 7 Feb 2019 15:55:18 +1000
Raw View
--00000000000079024c0581477d04
Content-Type: text/plain; charset="UTF-8"
On Thu, Feb 7, 2019 at 2:13 PM FrankHB1989 <frankhb1989@gmail.com> wrote:
> This approach is strictly not expressible like traditional syntactic
> extensions by (non-C-style) macros. The source-code-based and
> context-sensitive nature makes it even difficult to implement some
> traditional tricks which should be reasonably easy for a properly designed
> hygienic macro system (like block scopes by beta reduction from some
> invented translation-time function evaluation), as it totally misses the
> primitives to introduce such abstractions (either a macro pattern language
> <https://www.gnu.org/software/guile/manual/html_node/Syntax-Rules.html>
> or some more generalized things like vau operator
> <https://en.wikipedia.org/wiki/Fexpr#Fexprs_since_1980>).
>
> For such limitations, this approach does not work well for most kinds of
> "reflection" concerned with meta-level code manipulation by design, except
> for cases only having interest on properties of the code fairly directly
> mapped from the source form. Namely, it can does little beyond some limited
> forms of code generation, plus many problems on interops with existing C++
> features. Then all the problems mentioned by Nicol Bolas come.
>
I guess I don't follow this. codeeval can emit any C++ code. constexpr
programming is turing complete. Therefore as a reification mechanism, it
is provably complete. A claim that it isn't powerful enough was the least
expected criticism.
What is an example of a reification use case that it does not cover?
--
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/CAB%2B4KHK2ox2b6sN%2BLgz%2Bu880iO-%3DmQFx262e3isqfFkj4g-Mrg%40mail.gmail.com.
--00000000000079024c0581477d04
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div dir=3D"ltr">On Thu, Feb 7, 2019 at 2:13 PM FrankHB198=
9 <<a href=3D"mailto:frankhb1989@gmail.com">frankhb1989@gmail.com</a>>=
; wrote:<br></div><div class=3D"gmail_quote"><blockquote class=3D"gmail_quo=
te" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204=
);padding-left:1ex"><div dir=3D"ltr"><div>This
approach is strictly not expressible like traditional syntactic=20
extensions by (non-C-style) macros. The source-code-based and=20
context-sensitive nature makes it even difficult to implement some=20
traditional tricks which should be reasonably easy for a properly=20
designed hygienic macro system (like block scopes by beta reduction from
some invented translation-time function evaluation), as it totally=20
misses the primitives to introduce such abstractions (either a <a href=3D"h=
ttps://www.gnu.org/software/guile/manual/html_node/Syntax-Rules.html" targe=
t=3D"_blank">macro pattern language</a> or some more generalized things lik=
e <a href=3D"https://en.wikipedia.org/wiki/Fexpr#Fexprs_since_1980" target=
=3D"_blank">vau operator</a>).<br></div></div></blockquote><div><blockquote=
class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px so=
lid rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr"><br class=3D"gmail-=
Apple-interchange-newline">For such limitations, this approach does not wor=
k well for most kinds of "reflection" concerned with meta-level c=
ode manipulation by design, except for cases only having interest on proper=
ties of the code fairly directly mapped from the source form. Namely, it ca=
n does little beyond some limited forms of code generation, plus many probl=
ems on interops with existing C++ features. Then all the problems mentioned=
by Nicol Bolas come.<br></div></blockquote><div>=C2=A0</div></div><div>I g=
uess I don't follow this.=C2=A0 codeeval can emit any C++ code.=C2=A0 c=
onstexpr programming is turing complete.=C2=A0 Therefore as a reification m=
echanism, it is provably complete.=C2=A0 A claim that it isn't powerful=
enough was the least expected criticism.<br></div><div><br></div><div>What=
is an example of a reification use case that it does not cover?</div><div>=
<br></div></div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;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"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/CAB%2B4KHK2ox2b6sN%2BLgz%2Bu880iO-%3D=
mQFx262e3isqfFkj4g-Mrg%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfoo=
ter">https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAB%2B4KH=
K2ox2b6sN%2BLgz%2Bu880iO-%3DmQFx262e3isqfFkj4g-Mrg%40mail.gmail.com</a>.<br=
/>
--00000000000079024c0581477d04--
.