On Thu, 17 Sep 2020 at 23:52, Ville Voutilainen <ville.voutilainen@gmail.com> wrote:
On Thu, 17 Sep 2020 at 23:51, Richard Hodges via Std-Discussion
<std-discussion@lists.isocpp.org> wrote:
 Personally I tend to prefer keywords that express intent rather than
library functions,

Why?

Thanks for asking. My position is pretty simple. It’s about elegance, readability and ultimately, performance.

Elegance & readability:
Library functions are wordy, namespaced and by definition, a compromise when seeking to express intent to both programmer and compiler. This inevitably results in wordiness, preconditions that are left unchecked, the possibility of UB and complicated syntax that Is expressed in and limited by the syntax of templates and function calls. A keyword with a specific job allows expression in terms of precise intent.

E.g Compare (ignoring current syntax transgressions):

auto x = std::make_tuple(foo, bar);

to

auto x = { foo, bar }; // shorter and now a language type

or

auto x = tuple [ foo, &bar]; // bar is a tie

or 

auto x = tuple & [ foo, bar ]; // equivalent to std::tie

In the above trivial example, the presence of the name std::make_tuple adds almost no information. It also creates a type with a long and unwieldy name (that actually causes some compilers to run out of string space!) and an eye-wateringly complex implementation. The presence of std:: adds absolutely none as a tuple is a globally understood concept. The last two examples suggest a similar capture model to that of lambdas, which provides consistency.

Performance:
Expression through library templates means two levels of translation of intent. One from user intent to expression in terms of existing library code and (sparse) core language features. There is plenty of opportunity for missing concepts in the language to limit the quality of that translation.
On the other hand, a keyword with code generation behind it means that a users’ specific intent can be translated into optimal code every time. Furthermore, as compiler technology improves, that translation can be improved, improving every program upon recompilation.
Of course this is partially true of libraries, but the library still suffers from not having access to direct code generation with knowledge of the absolute intent of the programmer.

Further:
Many modern library features rely on compiler intrinsics - from the programmer’s point of view these are required but undocumented language extensions. This is untenable at scale. Better, in my view, to have no intrinsics and simply extend the language to include these obviously essential features. Once that is done, why bother with the complication of a library? Make a tuple a compiler-supported type. Provide class reflection as a language feature. Then it can be easily documented, maintained and shipped with no secret interdependency between compiler and standard library.
 

..in my never-ending quest for rationale, as opposed to just blanket
statements. ;)


--
Richard Hodges
office: +442032898513
home: +376841522
mobile: +376380212