C++ Logo

std-proposals

Advanced search

Re: [std-proposals] Grouped-namespace "using" statements (floating the idea)

From: Barry Revzin <barry.revzin_at_[hidden]>
Date: Thu, 4 May 2023 10:15:12 -0500
On Sat, Apr 29, 2023 at 11:27 AM Barry Revzin <barry.revzin_at_[hidden]>
wrote:

> On Wed, Apr 26, 2023 at 8:21 AM Arthur O'Dwyer via Std-Proposals <
> std-proposals_at_[hidden]> wrote:
>
>> FWIW, I'm strongly opposed to this. (And I did a double-take at Barry's
>> post: is it April Fool's Day already?)
>>
>
> The hell is wrong with you?
>
>
>> C++ isn't Perl; we don't use Unix shell globs like that. In C++, curly
>> braces have a couple of different meanings (code block,
>> initializer-sequence), but not "shell glob."
>>
>> (1) Ville has shown C++'s existing syntax for this:
>> namespace LVT = longish::verbosish::tedious;
>> using LVT::X;
>> using LVT::Y;
>> using LVT::Z;
>>
>> (2) It is a long-standing guideline that you shouldn't introduce multiple
>> declarations on the same line of code.
>> int x, y, z; // worse
>>
>> int x;
>> int y;
>> int z; // better
>>
>
> The reason this guideline exists for variables doesn't really apply to
> using declarations: C declarators make multiple variables in one line
> confusing, and once you start adding initializers to your multiple
> variables in a line, it can be easy to miss an initialization and it's
> particularly hard for users to understand.
>
> On the other hand, this:
>
> using std::format, std::format_to, std::formatter;
>
> is just a shorter version of:
>
> using std::format;
> using std::format_to;
> using std::formatter;
>
> Repeating "using" doesn't really add much to the reader. Good practice to
> split up using declarations from different namespaces, but the point OP is
> making is that repeating "std::" doesn't really buy much either. This:
>
> using std::{format, format_to, formatter};
>
> is easier to read still.
>
>
>
>>
>> (3) The "zero, one, infinity" rule. In practice, `using`-declarations
>> rarely come in twos and threes. There's either one using-declaration (e.g.
>> to enable ADL
>> <https://quuxplusone.github.io/blog/2022/04/30/poison-pill-redux/>), or
>> hundreds (e.g. in the implementation of the <cmath> header
>> <https://github.com/llvm/llvm-project/blob/main/libcxx/include/cmath#L335>).
>> Neither scenario is a good one for this proposed (mis)feature. Anytime
>> this feature saves a significant amount of typing, the result will be
>> unfriendly to the human reader — and the code isn't likely to have been
>> generated by a human typist in the first place.
>>
>
> The premise of this is not true - using declarations come in small groups
> (i.e. more than one, fewer than "hundreds") pretty frequently. Introducing
> an arbitrary terse namespace alias which remains in scope forever, which is
> your proposed solution to this problem, is much more unfriendly to the
> human reader than OP's proposal.
>
>
>>
>> (4) Another meaning of "C++ isn't Perl": We don't *need* to assign a
>> meaning to every single sequence of ASCII characters. It's okay for some
>> sequences of characters to be syntax errors; or to be reserved for future
>> standardization, until we come up with a feature that is so useful that it
>> deserves a dedicated syntax. The mere fact that "::{" is currently
>> unassigned, is not an argument in favor of giving it *this* meaning.
>>
>
> As Jason already pointed out but bears repeating, this was obviously not
> the argument being made
>
>
>>
>> John: Did you know about
>> namespace XYZ = longish::verbosish::tedious;
>> before this week? Now that you know about it, does it adequately solve
>> your problem?
>>
>> –Arthur
>>
>
> I can't see ever using a namespace alias just for using declarations. This
> is actively detracting from readability, in a way that doesn't actually
> make your code meaningfully shorter. We're talking about changing:
>
> using longish::verbosish::tedious::X;
> using longish::verbosish::tedious::Y;
> using longish::verbosish::tedious::Z;
>
> to:
>
> namespace LVT = longish::verbosish::tedious;
> using LVT::X;
> using LVT::Y;
> using LVT::Z;
>
> But the former is clearer, you already know what
> longish::verbosish::tedious is, but LVT is meaningless. Sure, now you can
> write:
>
> namespace LVT = longish::verbosish::tedious;
> using LVT::X, LVT::Y, LVT::Z;
>
> So that you can end up using fewer lines of code, but this isn't... really
> better. Maybe somebody prefers this, but I can't see ever writing it.
>
> On the other hand, this:
>
> using longish::verbosish::tedious::{X, Y, Z};
>
> Is clearer precisely because it's shorter, and doesn't require adding
> extra [effectively meaningless] identifiers to your program.
>
> Barry
>

Also, we already have something like this in the language. It's just
limited to attributes (https://eel.is/c++draft/dcl.attr#grammar-example-1):

[[using CC: opt(1), debug]] // same as [[CC::opt(1), CC::debug]]
  void f() {}
[[using CC: opt(1)]] [[CC::debug]] // same as [[CC::opt(1)]] [[CC::debug]]
  void g() {}


I always forget this exists, because it's a little strange to me to scope
with a single colon, just here, and I think OP's suggested syntax is better:

using std::{print, println};
using std: print, println;

The second one is shorter, but looks like a typo, and I don't know that it
would ever *not* look like a typo to me.

Barry

Received on 2023-05-04 15:15:27