C++ Logo

std-discussion

Advanced search

Re: Making the new expression smart

From: Richard Hodges <hodges.r_at_[hidden]>
Date: Fri, 18 Sep 2020 13:24:18 +0200
On Fri, 18 Sep 2020 at 10:33, Ville Voutilainen <ville.voutilainen_at_[hidden]>
wrote:

> On Fri, 18 Sep 2020 at 09:36, Richard Hodges via Std-Discussion
> <std-discussion_at_[hidden]> wrote:
> > auto x = tuple [ foo, &bar]; // bar is a tie
> > 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.
>
> Interesting consistency, considering that &bar means address of bar
> everywhere else, but reference to bar
> in lambda captures.
>

& means "reference to" in argument declarations, method declarations,
lambda captures and structured bindings. It seems to me that a tuple (the
arbitrary chosen example) is merely conceptually the corollary of a
structured binding (although I do appreciate that tuples came first).
Therefore to me the notation seems consistent in this case. However, I am
not arguing for a particular notation, merely providing an off-the-cuff
example of it.
As for the confusion due to the use of & to also mean "address of", I would
have to refer you to Mssrs Stroustrup, Kernighan, Ritchie et.al. for a
rationale. I confess it was before my time. I've only been writing C++
since '98.



>
> > 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.
>
> I don't quite see what the "plenty of opportunity for missing concepts
> in the language" might be, and how
> make_unique leads into any less-optimized code than writing the same
> with operators and sigils does.
>

I was under the impression that you were asking about my general rationale
for preferring the creation of keywords to describe common concepts in the
language rather than library types. It might be that I misunderstood. If
you did mean what I thought you meant, then focusing on specific operations
where there is no specific performance benefit immediately obvious today
would seem to be to be confrontational. I will put it down to a
misunderstanding.

>
> > 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.
>
> Things like tuple and make_unique don't rely on intrinsics. Wrt. "why
> bother with the complication of a library?", why bother
> with the complication of every compiler?
>

Again, std::tuple may or may not rely on intrinsics today, that is not the
point. We know that a growing number of library constructs do. To me this
interdependency between library and
non-language-but-otherwise-necessary compiler interface seems like the
worst of all worlds.

Why bother the compiler writer? Because compilers are few and programmers
are many, so embedding best practice into the implementation of the
compiler seems to me to provide best bang for buck in terms of
disseminating excellence when transforming human intent into machine
instructions. In addition, the compiler has the best possible view of the
situation and is therefore the most informed agent in the compilation chain.

A few years ago, I remember that there were laments about it being
"impossible to implement std::vector with compliant code". One answer to
that (the approach taken) is to supply library tools (backed by compiler
intrinsics in the case of clang I believe). Another is to simply accept
that vector is so useful and necessary a noun that it ought to be part of
the language.



I appreciate that positions such as this have a tendency to ignite
religious wars in the C++ community. You don't have to agree, but if you
are going to engage with me I would ask that you consider the entirety of
what I write, and understand that it is written in good faith.

-- 
Richard Hodges
hodges.r_at_[hidden]
office: +442032898513
home: +376841522
mobile: +376380212

Received on 2020-09-18 06:24:35