Date: Thu, 26 Sep 2019 02:02:00 +0000
As tempting as it is to add new and powerful features to the language,
for various reasons from simplifying existing code to 'keeping up' with
other languages out in the field, it's a dangerous and bloody art to do so.
The C++ spec may define the syntax and evaluation semantics of the
language, but what breathes life into it is the compiler. The more
complicated the spec is, the more complicated the compiler must become.
We're fortunate to have a diverse set of c++ compilers from the
proprietary to the open source, but the more features get added, the
higher the initial cost to creating a new viable c++ compiler project.
Slow and steady wins the race. There does not exist a language feature
(except maybe value semantics) that will not, at some point in the near
or far future, become invalidated by cleaner ways of doing the same
thing. Adding too many features kills languages. Optimally, the rate
at which features are added should be equal to the rate at which they
are deprecated and removed, over long time spans. This ensures that
compiler writers will not have to do too much up-front work to learn to
maintain a compiler or to write a new one.
To pick on coroutines (although they certainly can be useful), co_await,
co_yield, and co_return can be implemented as library functions
abstracting and making platform-independent the existing functions
setjmp and longjmp, with only the overhead of keeping a reference to
some state holding the continuation in the calling code and the
continuation in the coroutine. Additionally, while coroutines make
serial asynchronous operations easier to write, they cannot do the same
for parallel asynchronous operations without potentially pessimizing
performance. In "x = co_await y; x2 = co_await y2;" x2 cannot be
assigned before x has been assigned - even if y2 completes before y -
unless the compiler can come up with a proof that such re-ordering does
not change the visible behavior of the program. Instruction reordering
and the as-if rule already indicate that the semantics of C++ place too
much emphasis on the sequencing of operations over the dependency graph
of data.
As excited as I am for new C++20 features including concepts and
coroutines, I'm more excited for the deprecation of most of volatile. I
want the language to be well understood as-is so that it can be reasoned
about, the real pain points identified, and the spec slowly changed to
meet new needs with the patience of a community that deserves to
continue to beat until the last program is written and the last rock is
dust.
Peace,
Jefferson
for various reasons from simplifying existing code to 'keeping up' with
other languages out in the field, it's a dangerous and bloody art to do so.
The C++ spec may define the syntax and evaluation semantics of the
language, but what breathes life into it is the compiler. The more
complicated the spec is, the more complicated the compiler must become.
We're fortunate to have a diverse set of c++ compilers from the
proprietary to the open source, but the more features get added, the
higher the initial cost to creating a new viable c++ compiler project.
Slow and steady wins the race. There does not exist a language feature
(except maybe value semantics) that will not, at some point in the near
or far future, become invalidated by cleaner ways of doing the same
thing. Adding too many features kills languages. Optimally, the rate
at which features are added should be equal to the rate at which they
are deprecated and removed, over long time spans. This ensures that
compiler writers will not have to do too much up-front work to learn to
maintain a compiler or to write a new one.
To pick on coroutines (although they certainly can be useful), co_await,
co_yield, and co_return can be implemented as library functions
abstracting and making platform-independent the existing functions
setjmp and longjmp, with only the overhead of keeping a reference to
some state holding the continuation in the calling code and the
continuation in the coroutine. Additionally, while coroutines make
serial asynchronous operations easier to write, they cannot do the same
for parallel asynchronous operations without potentially pessimizing
performance. In "x = co_await y; x2 = co_await y2;" x2 cannot be
assigned before x has been assigned - even if y2 completes before y -
unless the compiler can come up with a proof that such re-ordering does
not change the visible behavior of the program. Instruction reordering
and the as-if rule already indicate that the semantics of C++ place too
much emphasis on the sequencing of operations over the dependency graph
of data.
As excited as I am for new C++20 features including concepts and
coroutines, I'm more excited for the deprecation of most of volatile. I
want the language to be well understood as-is so that it can be reasoned
about, the real pain points identified, and the spec slowly changed to
meet new needs with the patience of a community that deserves to
continue to beat until the last program is written and the last rock is
dust.
Peace,
Jefferson
Received on 2019-09-25 21:04:21